]> git.neil.brown.name Git - history.git/commitdiff
NTFS: Release 2.0.6 - Major bugfix to make compatible with other kernel changes.
authorAnton Altaparmakov <aia21@cantab.net>
Sat, 4 May 2002 23:58:17 +0000 (00:58 +0100)
committerAnton Altaparmakov <aia21@cantab.net>
Sat, 4 May 2002 23:58:17 +0000 (00:58 +0100)
- Initialize the mftbmp address space properly now that there are more
fields in the struct address_space. This was leading to hangs and
oopses on umount since 2.5.12 because of changes to other parts of
the kernel. We probably want a kernel generic init_address_space()
function...
- Drop BKL from ntfs_readdir() after consultation with Al Viro. The
only caller of ->readdir() is vfs_readdir() which holds i_sem during
the call, and i_sem is sufficient protection against changes in the
directory inode (including ->i_size).
- Use generic_file_llseek() for directories (as opposed to
default_llseek()) as this downs i_sem instead of the BKL which is
what we now need for exclusion against ->f_pos changes considering we
no longer take the BKL in ntfs_readdir().

Documentation/filesystems/ntfs.txt
fs/ntfs/ChangeLog
fs/ntfs/Makefile
fs/ntfs/compress.c
fs/ntfs/dir.c
fs/ntfs/super.c

index 535bb1370c5269256f85abca2d8ab570f993165d..5b1a63680d4427334faddc204c9016c56bf4c2fb 100644 (file)
@@ -262,6 +262,13 @@ ChangeLog
 
 Note that a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
 
+2.0.6:
+       - Major bugfix to make compatible with other kernel changes. This fixes
+         the hangs/oopses on umount.
+       - Locking cleanup in directory operations (remove BKL usage).
+2.0.5:
+       - Major buffer overflow bug fix.
+       - Minor cleanups and updates for kernel 2.5.12.
 2.0.4:
        - Cleanups and updates for kernel 2.5.11.
 2.0.3:
index b6243c47d7557eae11601edd34275e764b9074e2..bd1e60d0d4ddaaf8ebc4cbcb0f4ab5325677f742 100644 (file)
@@ -14,11 +14,6 @@ ToDo:
          strictly a speed optimization. Obviously need to keep the ->run_list
          locked or RACE. load_attribute_list() already performs such an
          optimization so use the same optimization where desired.
-       - Optimize all our readpage functions to not do i/o on buffer heads
-         beyond initialized_size, just zero the buffer heads instead.
-         Question: How to setup the buffer heads so they point to the on disk
-         location correctly (after all they are allocated) but are not read
-         from disk?
        - Consider if ntfs_file_read_compressed_block() shouldn't be coping
          with initialized_size < data_size. I don't think it can happen but
          it requires more careful consideration.
@@ -26,6 +21,24 @@ ToDo:
          several copies of almost identicall functions and the functions are
          quite big. Modularising them a bit, e.g. a-la get_block(), will make
          them cleaner and make code reuse easier.
+       - Want to use dummy inodes for address space i/o. We need some VFS
+         changes first, which are currently under discussion.
+
+2.0.6 - Major bugfix to make compatible with other kernel changes.
+
+       - Initialize the mftbmp address space properly now that there are more
+         fields in the struct address_space. This was leading to hangs and
+         oopses on umount since 2.5.12 because of changes to other parts of
+         the kernel. We probably want a kernel generic init_address_space()
+         function...
+       - Drop BKL from ntfs_readdir() after consultation with Al Viro. The
+         only caller of ->readdir() is vfs_readdir() which holds i_sem during
+         the call, and i_sem is sufficient protection against changes in the
+         directory inode (including ->i_size).
+       - Use generic_file_llseek() for directories (as opposed to
+         default_llseek()) as this downs i_sem instead of the BKL which is
+         what we now need for exclusion against ->f_pos changes considering we
+         no longer take the BKL in ntfs_readdir().
 
 2.0.5 - Major bugfix. Buffer overflow in extent inode handling.
 
index e158bc7d287418a725cab9f34d59b41a3f241373..aebe60aaf54665dbd828222aa9035cc490180615 100644 (file)
@@ -7,7 +7,7 @@ obj-y   := aops.o attrib.o compress.o debug.o dir.o file.o inode.o mft.o \
 
 obj-m   := $(O_TARGET)
 
-EXTRA_CFLAGS = -DNTFS_VERSION=\"2.0.5\"
+EXTRA_CFLAGS = -DNTFS_VERSION=\"2.0.6\"
 
 ifeq ($(CONFIG_NTFS_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
index b2fd83191a44b9a4ad6a5e147ed4c0a0be8322fe..b4896ab4008bce294c4cfb92b1f2c4f8815921bf 100644 (file)
@@ -763,9 +763,10 @@ retry_remap:
                 * ntfs_decompess.
                 */
                if (err) {
-                       ntfs_error(vol->sb, "ntfs_decompress() failed with "
-                                       "error code %i. Skipping this "
-                                       "compression block.\n", -err);
+                       ntfs_error(vol->sb, "ntfs_decompress() failed in inode "
+                                       "0x%Lx with error code %i. Skipping "
+                                       "this compression block.\n",
+                                       (unsigned long long)ni->mft_no, -err);
                        /* Release the unfinished pages. */
                        for (; prev_cur_page < cur_page; prev_cur_page++) {
                                page = pages[prev_cur_page];
index 2ded94359b78c0d7e93305d682b5c022a940707e..ac8d04938c79b241bd9c6c3f1223c5e73290b3ea 100644 (file)
@@ -500,7 +500,12 @@ static inline int ntfs_filldir(ntfs_volume *vol, struct file *filp,
 }
 
 /*
- * VFS calls readdir with BKL held so no possible RACE conditions.
+ * VFS calls readdir without BKL but with i_sem held. This protects the VFS
+ * parts (e.g. ->f_pos and ->i_size, and it also protects against directory
+ * modifications). Together with the rw semaphore taken by the call to
+ * map_mft_record(), the directory is truly locked down so we have a race free
+ * ntfs_readdir() without the BKL. (-:
+ *
  * We use the same basic approach as the old NTFS driver, i.e. we parse the
  * index root entries and then the index allocation entries that are marked
  * as in use in the index bitmap.
@@ -525,7 +530,6 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
        u8 *kaddr, *bmp, *index_end;
        attr_search_context *ctx;
 
-       lock_kernel();
        ntfs_debug("Entering for inode 0x%Lx, f_pos 0x%Lx.",
                        (unsigned long long)ndir->mft_no, filp->f_pos);
        rc = err = 0;
@@ -794,7 +798,6 @@ done:
                ntfs_debug("filldir returned %i, f_pos 0x%Lx, returning 0.",
                                rc, filp->f_pos);
 #endif
-       unlock_kernel();
        return 0;
 map_page_err_out:
        ntfs_error(sb, "Reading index allocation data failed.");
@@ -817,7 +820,8 @@ dir_err_out:
 }
 
 struct file_operations ntfs_dir_ops = {
-       read:                   generic_read_dir,       /* Return -EISDIR. */
-       readdir:                ntfs_readdir,           /* Read directory. */
+       llseek:         generic_file_llseek,    /* Seek inside directory. */
+       read:           generic_read_dir,       /* Return -EISDIR. */
+       readdir:        ntfs_readdir,           /* Read directory contents. */
 };
 
index 1009315877b8fd32a78bad096673fabf73e42fcf..7f73fe3d1346b1a885c4a3ec5e9989f446e927b7 100644 (file)
@@ -1126,8 +1126,7 @@ void ntfs_put_super(struct super_block *vfs_sb)
        down_write(&vol->mftbmp_lock);
        /*
         * Clean up mft bitmap address space. Ignore the _inode_ bit in the
-        * name of the function... FIXME: What does this do with dirty pages?
-        * (ask Al Viro)
+        * name of the function... FIXME: This destroys dirty pages!!! (AIA)
         */
        truncate_inode_pages(&vol->mftbmp_mapping, 0);
        vol->mftbmp_mapping.a_ops = NULL;
@@ -1493,22 +1492,6 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
        vol->sb = sb;
        vol->upcase = NULL;
        vol->mft_ino = NULL;
-       init_rwsem(&vol->mftbmp_lock);
-       INIT_LIST_HEAD(&vol->mftbmp_mapping.clean_pages);
-       INIT_LIST_HEAD(&vol->mftbmp_mapping.dirty_pages);
-       INIT_LIST_HEAD(&vol->mftbmp_mapping.locked_pages);
-       vol->mftbmp_mapping.a_ops = NULL;
-       vol->mftbmp_mapping.host = NULL;
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,6)
-       vol->mftbmp_mapping.i_mmap = NULL;
-       vol->mftbmp_mapping.i_mmap_shared = NULL;
-#else
-       INIT_LIST_HEAD(&vol->mftbmp_mapping.i_mmap);
-       INIT_LIST_HEAD(&vol->mftbmp_mapping.i_mmap_shared);
-#endif
-       spin_lock_init(&vol->mftbmp_mapping.i_shared_lock);
-       init_run_list(&vol->mftbmp_rl);
        vol->mftmirr_ino = NULL;
        vol->lcnbmp_ino = NULL;
        init_rwsem(&vol->lcnbmp_lock);
@@ -1519,6 +1502,26 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
        vol->on_errors = 0;
        vol->mft_zone_multiplier = 0;
        vol->nls_map = NULL;
+       init_rwsem(&vol->mftbmp_lock);
+       init_run_list(&vol->mftbmp_rl);
+
+       /* Initialize the mftbmp address space mapping.  */
+       INIT_RADIX_TREE(&vol->mftbmp_mapping.page_tree, GFP_ATOMIC);
+       rwlock_init(&vol->mftbmp_mapping.page_lock);
+       INIT_LIST_HEAD(&vol->mftbmp_mapping.clean_pages);
+       INIT_LIST_HEAD(&vol->mftbmp_mapping.dirty_pages);
+       INIT_LIST_HEAD(&vol->mftbmp_mapping.locked_pages);
+       INIT_LIST_HEAD(&vol->mftbmp_mapping.io_pages);
+       vol->mftbmp_mapping.nrpages = 0;
+       vol->mftbmp_mapping.a_ops = NULL;
+       vol->mftbmp_mapping.host = NULL;
+       INIT_LIST_HEAD(&vol->mftbmp_mapping.i_mmap);
+       INIT_LIST_HEAD(&vol->mftbmp_mapping.i_mmap_shared);
+       spin_lock_init(&vol->mftbmp_mapping.i_shared_lock);
+       vol->mftbmp_mapping.dirtied_when = 0;
+       vol->mftbmp_mapping.gfp_mask = GFP_HIGHUSER;
+       vol->mftbmp_mapping.ra_pages =
+                       sb->s_bdev->bd_inode->i_mapping->ra_pages;
 
        /*
         * Default is group and other don't have any access to files or