[PATCH] md/bitmap: tidy up i_writecount handling in md/bitmap
authorNeilBrown <neilb@suse.de>
Mon, 26 Jun 2006 07:27:47 +0000 (00:27 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 26 Jun 2006 16:58:38 +0000 (09:58 -0700)
md/bitmap modifies i_writecount of a bitmap file to make sure that no-one else
writes to it.  The reverting of the change is sometimes done twice, and there
is one error path where it is omitted.

This patch tidies that up.

Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/md/bitmap.c
drivers/md/md.c

index dfe5e12741babc07a45ad98208e96e4cbf3e1e3f..e40d3e4b8d27b4b29eba89ceddc4e63947ddba3f 100644 (file)
@@ -625,7 +625,6 @@ static void drain_write_queues(struct bitmap *bitmap)
 static void bitmap_file_put(struct bitmap *bitmap)
 {
        struct file *file;
-       struct inode *inode;
        unsigned long flags;
 
        spin_lock_irqsave(&bitmap->lock, flags);
@@ -637,13 +636,8 @@ static void bitmap_file_put(struct bitmap *bitmap)
 
        bitmap_file_unmap(bitmap);
 
-       if (file) {
-               inode = file->f_mapping->host;
-               spin_lock(&inode->i_lock);
-               atomic_set(&inode->i_writecount, 1); /* allow writes again */
-               spin_unlock(&inode->i_lock);
+       if (file)
                fput(file);
-       }
 }
 
 
index ea6837d45fc8c09ad2ba3fbf74accb4b0ff11031..7da9e2d023bb161ac1eef4e3e1bc614d7accc87e 100644 (file)
@@ -2877,6 +2877,32 @@ out:
        return err;
 }
 
+/* similar to deny_write_access, but accounts for our holding a reference
+ * to the file ourselves */
+static int deny_bitmap_write_access(struct file * file)
+{
+       struct inode *inode = file->f_mapping->host;
+
+       spin_lock(&inode->i_lock);
+       if (atomic_read(&inode->i_writecount) > 1) {
+               spin_unlock(&inode->i_lock);
+               return -ETXTBSY;
+       }
+       atomic_set(&inode->i_writecount, -1);
+       spin_unlock(&inode->i_lock);
+
+       return 0;
+}
+
+static void restore_bitmap_write_access(struct file *file)
+{
+       struct inode *inode = file->f_mapping->host;
+
+       spin_lock(&inode->i_lock);
+       atomic_set(&inode->i_writecount, 1);
+       spin_unlock(&inode->i_lock);
+}
+
 static int do_md_stop(mddev_t * mddev, int ro)
 {
        int err = 0;
@@ -2940,7 +2966,7 @@ static int do_md_stop(mddev_t * mddev, int ro)
 
                bitmap_destroy(mddev);
                if (mddev->bitmap_file) {
-                       atomic_set(&mddev->bitmap_file->f_dentry->d_inode->i_writecount, 1);
+                       restore_bitmap_write_access(mddev->bitmap_file);
                        fput(mddev->bitmap_file);
                        mddev->bitmap_file = NULL;
                }
@@ -3544,23 +3570,6 @@ abort_export:
        return err;
 }
 
-/* similar to deny_write_access, but accounts for our holding a reference
- * to the file ourselves */
-static int deny_bitmap_write_access(struct file * file)
-{
-       struct inode *inode = file->f_mapping->host;
-
-       spin_lock(&inode->i_lock);
-       if (atomic_read(&inode->i_writecount) > 1) {
-               spin_unlock(&inode->i_lock);
-               return -ETXTBSY;
-       }
-       atomic_set(&inode->i_writecount, -1);
-       spin_unlock(&inode->i_lock);
-
-       return 0;
-}
-
 static int set_bitmap_file(mddev_t *mddev, int fd)
 {
        int err;
@@ -3608,8 +3617,10 @@ static int set_bitmap_file(mddev_t *mddev, int fd)
                mddev->pers->quiesce(mddev, 0);
        }
        if (fd < 0) {
-               if (mddev->bitmap_file)
+               if (mddev->bitmap_file) {
+                       restore_bitmap_write_access(mddev->bitmap_file);
                        fput(mddev->bitmap_file);
+               }
                mddev->bitmap_file = NULL;
        }