__generic_block_fiemap(): fix for files bigger than 4GB
[safe/jmp/linux-2.6] / fs / ntfs / super.c
index 4a46743..80b0477 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/spinlock.h>
-#include <linux/blkdev.h>      /* For bdev_hardsect_size(). */
+#include <linux/blkdev.h>      /* For bdev_logical_block_size(). */
 #include <linux/backing-dev.h>
 #include <linux/buffer_head.h>
 #include <linux/vfs.h>
@@ -201,8 +201,7 @@ use_utf8:
                                                v, old_nls->charset);
                                nls_map = old_nls;
                        } else /* nls_map */ {
-                               if (old_nls)
-                                       unload_nls(old_nls);
+                               unload_nls(old_nls);
                        }
                } else if (!strcmp(p, "utf8")) {
                        bool val = false;
@@ -443,6 +442,8 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
        ntfs_volume *vol = NTFS_SB(sb);
 
        ntfs_debug("Entering with remount options string: %s", opt);
+
+       lock_kernel();
 #ifndef NTFS_RW
        /* For read-only compiled driver, enforce read-only flag. */
        *flags |= MS_RDONLY;
@@ -466,15 +467,18 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
                if (NVolErrors(vol)) {
                        ntfs_error(sb, "Volume has errors and is read-only%s",
                                        es);
+                       unlock_kernel();
                        return -EROFS;
                }
                if (vol->vol_flags & VOLUME_IS_DIRTY) {
                        ntfs_error(sb, "Volume is dirty and read-only%s", es);
+                       unlock_kernel();
                        return -EROFS;
                }
                if (vol->vol_flags & VOLUME_MODIFIED_BY_CHKDSK) {
                        ntfs_error(sb, "Volume has been modified by chkdsk "
                                        "and is read-only%s", es);
+                       unlock_kernel();
                        return -EROFS;
                }
                if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) {
@@ -482,11 +486,13 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
                                        "(0x%x) and is read-only%s",
                                        (unsigned)le16_to_cpu(vol->vol_flags),
                                        es);
+                       unlock_kernel();
                        return -EROFS;
                }
                if (ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) {
                        ntfs_error(sb, "Failed to set dirty bit in volume "
                                        "information flags%s", es);
+                       unlock_kernel();
                        return -EROFS;
                }
 #if 0
@@ -506,18 +512,21 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
                        ntfs_error(sb, "Failed to empty journal $LogFile%s",
                                        es);
                        NVolSetErrors(vol);
+                       unlock_kernel();
                        return -EROFS;
                }
                if (!ntfs_mark_quotas_out_of_date(vol)) {
                        ntfs_error(sb, "Failed to mark quotas out of date%s",
                                        es);
                        NVolSetErrors(vol);
+                       unlock_kernel();
                        return -EROFS;
                }
                if (!ntfs_stamp_usnjrnl(vol)) {
                        ntfs_error(sb, "Failed to stamp transation log "
                                        "($UsnJrnl)%s", es);
                        NVolSetErrors(vol);
+                       unlock_kernel();
                        return -EROFS;
                }
        } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) {
@@ -533,8 +542,11 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
 
        // TODO: Deal with *flags.
 
-       if (!parse_options(vol, opt))
+       if (!parse_options(vol, opt)) {
+               unlock_kernel();
                return -EINVAL;
+       }
+       unlock_kernel();
        ntfs_debug("Done.");
        return 0;
 }
@@ -618,7 +630,7 @@ static bool is_boot_sector_ntfs(const struct super_block *sb,
         * many BIOSes will refuse to boot from a bootsector if the magic is
         * incorrect, so we emit a warning.
         */
-       if (!silent && b->end_of_sector_marker != const_cpu_to_le16(0xaa55))
+       if (!silent && b->end_of_sector_marker != cpu_to_le16(0xaa55))
                ntfs_warning(sb, "Invalid end of sector marker.");
        return true;
 not_ntfs:
@@ -1242,13 +1254,13 @@ static int check_windows_hibernation_status(ntfs_volume *vol)
        u32 *kaddr, *kend;
        ntfs_name *name = NULL;
        int ret = 1;
-       static const ntfschar hiberfil[13] = { const_cpu_to_le16('h'),
-                       const_cpu_to_le16('i'), const_cpu_to_le16('b'),
-                       const_cpu_to_le16('e'), const_cpu_to_le16('r'),
-                       const_cpu_to_le16('f'), const_cpu_to_le16('i'),
-                       const_cpu_to_le16('l'), const_cpu_to_le16('.'),
-                       const_cpu_to_le16('s'), const_cpu_to_le16('y'),
-                       const_cpu_to_le16('s'), 0 };
+       static const ntfschar hiberfil[13] = { cpu_to_le16('h'),
+                       cpu_to_le16('i'), cpu_to_le16('b'),
+                       cpu_to_le16('e'), cpu_to_le16('r'),
+                       cpu_to_le16('f'), cpu_to_le16('i'),
+                       cpu_to_le16('l'), cpu_to_le16('.'),
+                       cpu_to_le16('s'), cpu_to_le16('y'),
+                       cpu_to_le16('s'), 0 };
 
        ntfs_debug("Entering.");
        /*
@@ -1296,7 +1308,7 @@ static int check_windows_hibernation_status(ntfs_volume *vol)
                goto iput_out;
        }
        kaddr = (u32*)page_address(page);
-       if (*(le32*)kaddr == const_cpu_to_le32(0x72626968)/*'hibr'*/) {
+       if (*(le32*)kaddr == cpu_to_le32(0x72626968)/*'hibr'*/) {
                ntfs_debug("Magic \"hibr\" found in hiberfil.sys.  Windows is "
                                "hibernated on the volume.  This is the "
                                "system volume.");
@@ -1337,12 +1349,12 @@ static bool load_and_init_quota(ntfs_volume *vol)
        MFT_REF mref;
        struct inode *tmp_ino;
        ntfs_name *name = NULL;
-       static const ntfschar Quota[7] = { const_cpu_to_le16('$'),
-                       const_cpu_to_le16('Q'), const_cpu_to_le16('u'),
-                       const_cpu_to_le16('o'), const_cpu_to_le16('t'),
-                       const_cpu_to_le16('a'), 0 };
-       static ntfschar Q[3] = { const_cpu_to_le16('$'),
-                       const_cpu_to_le16('Q'), 0 };
+       static const ntfschar Quota[7] = { cpu_to_le16('$'),
+                       cpu_to_le16('Q'), cpu_to_le16('u'),
+                       cpu_to_le16('o'), cpu_to_le16('t'),
+                       cpu_to_le16('a'), 0 };
+       static ntfschar Q[3] = { cpu_to_le16('$'),
+                       cpu_to_le16('Q'), 0 };
 
        ntfs_debug("Entering.");
        /*
@@ -1416,16 +1428,16 @@ static bool load_and_init_usnjrnl(ntfs_volume *vol)
        struct page *page;
        ntfs_name *name = NULL;
        USN_HEADER *uh;
-       static const ntfschar UsnJrnl[9] = { const_cpu_to_le16('$'),
-                       const_cpu_to_le16('U'), const_cpu_to_le16('s'),
-                       const_cpu_to_le16('n'), const_cpu_to_le16('J'),
-                       const_cpu_to_le16('r'), const_cpu_to_le16('n'),
-                       const_cpu_to_le16('l'), 0 };
-       static ntfschar Max[5] = { const_cpu_to_le16('$'),
-                       const_cpu_to_le16('M'), const_cpu_to_le16('a'),
-                       const_cpu_to_le16('x'), 0 };
-       static ntfschar J[3] = { const_cpu_to_le16('$'),
-                       const_cpu_to_le16('J'), 0 };
+       static const ntfschar UsnJrnl[9] = { cpu_to_le16('$'),
+                       cpu_to_le16('U'), cpu_to_le16('s'),
+                       cpu_to_le16('n'), cpu_to_le16('J'),
+                       cpu_to_le16('r'), cpu_to_le16('n'),
+                       cpu_to_le16('l'), 0 };
+       static ntfschar Max[5] = { cpu_to_le16('$'),
+                       cpu_to_le16('M'), cpu_to_le16('a'),
+                       cpu_to_le16('x'), 0 };
+       static ntfschar J[3] = { cpu_to_le16('$'),
+                       cpu_to_le16('J'), 0 };
 
        ntfs_debug("Entering.");
        /*
@@ -2246,6 +2258,9 @@ static void ntfs_put_super(struct super_block *sb)
        ntfs_volume *vol = NTFS_SB(sb);
 
        ntfs_debug("Entering.");
+
+       lock_kernel();
+
 #ifdef NTFS_RW
        /*
         * Commit all inodes while they are still open in case some of them
@@ -2373,39 +2388,12 @@ static void ntfs_put_super(struct super_block *sb)
                vol->mftmirr_ino = NULL;
        }
        /*
-        * If any dirty inodes are left, throw away all mft data page cache
-        * pages to allow a clean umount.  This should never happen any more
-        * due to mft.c::ntfs_mft_writepage() cleaning all the dirty pages as
-        * the underlying mft records are written out and cleaned.  If it does,
-        * happen anyway, we want to know...
+        * We should have no dirty inodes left, due to
+        * mft.c::ntfs_mft_writepage() cleaning all the dirty pages as
+        * the underlying mft records are written out and cleaned.
         */
        ntfs_commit_inode(vol->mft_ino);
        write_inode_now(vol->mft_ino, 1);
-       if (sb_has_dirty_inodes(sb)) {
-               const char *s1, *s2;
-
-               mutex_lock(&vol->mft_ino->i_mutex);
-               truncate_inode_pages(vol->mft_ino->i_mapping, 0);
-               mutex_unlock(&vol->mft_ino->i_mutex);
-               write_inode_now(vol->mft_ino, 1);
-               if (sb_has_dirty_inodes(sb)) {
-                       static const char *_s1 = "inodes";
-                       static const char *_s2 = "";
-                       s1 = _s1;
-                       s2 = _s2;
-               } else {
-                       static const char *_s1 = "mft pages";
-                       static const char *_s2 = "They have been thrown "
-                                       "away.  ";
-                       s1 = _s1;
-                       s2 = _s2;
-               }
-               ntfs_error(sb, "Dirty %s found at umount time.  %sYou should "
-                               "run chkdsk.  Please email "
-                               "linux-ntfs-dev@lists.sourceforge.net and say "
-                               "that you saw this message.  Thank you.", s1,
-                               s2);
-       }
 #endif /* NTFS_RW */
 
        iput(vol->mft_ino);
@@ -2438,13 +2426,13 @@ static void ntfs_put_super(struct super_block *sb)
                ntfs_free(vol->upcase);
                vol->upcase = NULL;
        }
-       if (vol->nls_map) {
-               unload_nls(vol->nls_map);
-               vol->nls_map = NULL;
-       }
+
+       unload_nls(vol->nls_map);
+
        sb->s_fs_info = NULL;
        kfree(vol);
-       return;
+
+       unlock_kernel();
 }
 
 /**
@@ -2785,13 +2773,13 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
                goto err_out_now;
 
        /* We support sector sizes up to the PAGE_CACHE_SIZE. */
-       if (bdev_hardsect_size(sb->s_bdev) > PAGE_CACHE_SIZE) {
+       if (bdev_logical_block_size(sb->s_bdev) > PAGE_CACHE_SIZE) {
                if (!silent)
                        ntfs_error(sb, "Device has unsupported sector size "
                                        "(%i).  The maximum supported sector "
                                        "size on this architecture is %lu "
                                        "bytes.",
-                                       bdev_hardsect_size(sb->s_bdev),
+                                       bdev_logical_block_size(sb->s_bdev),
                                        PAGE_CACHE_SIZE);
                goto err_out_now;
        }