freeze_bdev: kill bd_mount_sem
authorChristoph Hellwig <hch@lst.de>
Mon, 3 Aug 2009 21:28:06 +0000 (23:28 +0200)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 24 Sep 2009 11:47:39 +0000 (07:47 -0400)
Now that we have the freeze count there is not much reason for bd_mount_sem
anymore.  The actual freeze/thaw operations are serialized using the
bd_fsfreeze_mutex, and the only other place we take bd_mount_sem is
get_sb_bdev which tries to prevent mounting a filesystem while the block
device is frozen.  Instead of add a check for bd_fsfreeze_count and
return -EBUSY if a filesystem is frozen.  While that is a change in user
visible behaviour a failing mount is much better for this case rather
than having the mount process stuck uninterruptible for a long time.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/block_dev.c
fs/super.c
include/linux/fs.h

index 5d1ed50..22506eb 100644 (file)
@@ -216,8 +216,6 @@ EXPORT_SYMBOL(fsync_bdev);
  * freeze_bdev  --  lock a filesystem and force it into a consistent state
  * @bdev:      blockdevice to lock
  *
- * This takes the block device bd_mount_sem to make sure no new mounts
- * happen on bdev until thaw_bdev() is called.
  * If a superblock is found on this device, we take the s_umount semaphore
  * on it to make sure nobody unmounts until the snapshot creation is done.
  * The reference counter (bd_fsfreeze_count) guarantees that only the last
@@ -240,7 +238,6 @@ struct super_block *freeze_bdev(struct block_device *bdev)
        }
        bdev->bd_fsfreeze_count++;
 
-       down(&bdev->bd_mount_sem);
        sb = get_super(bdev);
        if (sb && !(sb->s_flags & MS_RDONLY)) {
                sb->s_frozen = SB_FREEZE_WRITE;
@@ -260,7 +257,6 @@ struct super_block *freeze_bdev(struct block_device *bdev)
                                        "VFS:Filesystem freeze failed\n");
                                sb->s_frozen = SB_UNFROZEN;
                                drop_super(sb);
-                               up(&bdev->bd_mount_sem);
                                bdev->bd_fsfreeze_count--;
                                mutex_unlock(&bdev->bd_fsfreeze_mutex);
                                return ERR_PTR(error);
@@ -271,7 +267,7 @@ struct super_block *freeze_bdev(struct block_device *bdev)
        sync_blockdev(bdev);
        mutex_unlock(&bdev->bd_fsfreeze_mutex);
 
-       return sb;      /* thaw_bdev releases s->s_umount and bd_mount_sem */
+       return sb;      /* thaw_bdev releases s->s_umount */
 }
 EXPORT_SYMBOL(freeze_bdev);
 
@@ -321,7 +317,6 @@ int thaw_bdev(struct block_device *bdev, struct super_block *sb)
                drop_super(sb);
        }
 
-       up(&bdev->bd_mount_sem);
        mutex_unlock(&bdev->bd_fsfreeze_mutex);
        return 0;
 }
@@ -430,7 +425,6 @@ static void init_once(void *foo)
 
        memset(bdev, 0, sizeof(*bdev));
        mutex_init(&bdev->bd_mutex);
-       sema_init(&bdev->bd_mount_sem, 1);
        INIT_LIST_HEAD(&bdev->bd_inodes);
        INIT_LIST_HEAD(&bdev->bd_list);
 #ifdef CONFIG_SYSFS
index 4906e2d..1cb26a3 100644 (file)
@@ -743,9 +743,14 @@ int get_sb_bdev(struct file_system_type *fs_type,
         * will protect the lockfs code from trying to start a snapshot
         * while we are mounting
         */
-       down(&bdev->bd_mount_sem);
+       mutex_lock(&bdev->bd_fsfreeze_mutex);
+       if (bdev->bd_fsfreeze_count > 0) {
+               mutex_unlock(&bdev->bd_fsfreeze_mutex);
+               error = -EBUSY;
+               goto error_bdev;
+       }
        s = sget(fs_type, test_bdev_super, set_bdev_super, bdev);
-       up(&bdev->bd_mount_sem);
+       mutex_unlock(&bdev->bd_fsfreeze_mutex);
        if (IS_ERR(s))
                goto error_s;
 
index cbb7724..72dfbd4 100644 (file)
@@ -640,7 +640,6 @@ struct block_device {
        struct super_block *    bd_super;
        int                     bd_openers;
        struct mutex            bd_mutex;       /* open/close mutex */
-       struct semaphore        bd_mount_sem;
        struct list_head        bd_inodes;
        void *                  bd_holder;
        int                     bd_holders;