diff options
author | Christoph Hellwig <hch@lst.de> | 2009-08-03 17:28:06 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-09-24 07:47:39 -0400 |
commit | 4fadd7bb20a1e7c774ed88dc703d8fbcd00ff917 (patch) | |
tree | a6f3df6f19d27e81f35a93f8858b73bd4273f420 | |
parent | 1ba50bbe93ebb98e83b174a85eff76af430c4e5b (diff) |
freeze_bdev: kill bd_mount_sem
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>
-rw-r--r-- | fs/block_dev.c | 8 | ||||
-rw-r--r-- | fs/super.c | 9 | ||||
-rw-r--r-- | include/linux/fs.h | 1 |
3 files changed, 8 insertions, 10 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index 5d1ed50bd46c..22506eb4a58e 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -216,8 +216,6 @@ EXPORT_SYMBOL(fsync_bdev); | |||
216 | * freeze_bdev -- lock a filesystem and force it into a consistent state | 216 | * freeze_bdev -- lock a filesystem and force it into a consistent state |
217 | * @bdev: blockdevice to lock | 217 | * @bdev: blockdevice to lock |
218 | * | 218 | * |
219 | * This takes the block device bd_mount_sem to make sure no new mounts | ||
220 | * happen on bdev until thaw_bdev() is called. | ||
221 | * If a superblock is found on this device, we take the s_umount semaphore | 219 | * If a superblock is found on this device, we take the s_umount semaphore |
222 | * on it to make sure nobody unmounts until the snapshot creation is done. | 220 | * on it to make sure nobody unmounts until the snapshot creation is done. |
223 | * The reference counter (bd_fsfreeze_count) guarantees that only the last | 221 | * The reference counter (bd_fsfreeze_count) guarantees that only the last |
@@ -240,7 +238,6 @@ struct super_block *freeze_bdev(struct block_device *bdev) | |||
240 | } | 238 | } |
241 | bdev->bd_fsfreeze_count++; | 239 | bdev->bd_fsfreeze_count++; |
242 | 240 | ||
243 | down(&bdev->bd_mount_sem); | ||
244 | sb = get_super(bdev); | 241 | sb = get_super(bdev); |
245 | if (sb && !(sb->s_flags & MS_RDONLY)) { | 242 | if (sb && !(sb->s_flags & MS_RDONLY)) { |
246 | sb->s_frozen = SB_FREEZE_WRITE; | 243 | sb->s_frozen = SB_FREEZE_WRITE; |
@@ -260,7 +257,6 @@ struct super_block *freeze_bdev(struct block_device *bdev) | |||
260 | "VFS:Filesystem freeze failed\n"); | 257 | "VFS:Filesystem freeze failed\n"); |
261 | sb->s_frozen = SB_UNFROZEN; | 258 | sb->s_frozen = SB_UNFROZEN; |
262 | drop_super(sb); | 259 | drop_super(sb); |
263 | up(&bdev->bd_mount_sem); | ||
264 | bdev->bd_fsfreeze_count--; | 260 | bdev->bd_fsfreeze_count--; |
265 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 261 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
266 | return ERR_PTR(error); | 262 | return ERR_PTR(error); |
@@ -271,7 +267,7 @@ struct super_block *freeze_bdev(struct block_device *bdev) | |||
271 | sync_blockdev(bdev); | 267 | sync_blockdev(bdev); |
272 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 268 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
273 | 269 | ||
274 | return sb; /* thaw_bdev releases s->s_umount and bd_mount_sem */ | 270 | return sb; /* thaw_bdev releases s->s_umount */ |
275 | } | 271 | } |
276 | EXPORT_SYMBOL(freeze_bdev); | 272 | EXPORT_SYMBOL(freeze_bdev); |
277 | 273 | ||
@@ -321,7 +317,6 @@ int thaw_bdev(struct block_device *bdev, struct super_block *sb) | |||
321 | drop_super(sb); | 317 | drop_super(sb); |
322 | } | 318 | } |
323 | 319 | ||
324 | up(&bdev->bd_mount_sem); | ||
325 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 320 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
326 | return 0; | 321 | return 0; |
327 | } | 322 | } |
@@ -430,7 +425,6 @@ static void init_once(void *foo) | |||
430 | 425 | ||
431 | memset(bdev, 0, sizeof(*bdev)); | 426 | memset(bdev, 0, sizeof(*bdev)); |
432 | mutex_init(&bdev->bd_mutex); | 427 | mutex_init(&bdev->bd_mutex); |
433 | sema_init(&bdev->bd_mount_sem, 1); | ||
434 | INIT_LIST_HEAD(&bdev->bd_inodes); | 428 | INIT_LIST_HEAD(&bdev->bd_inodes); |
435 | INIT_LIST_HEAD(&bdev->bd_list); | 429 | INIT_LIST_HEAD(&bdev->bd_list); |
436 | #ifdef CONFIG_SYSFS | 430 | #ifdef CONFIG_SYSFS |
diff --git a/fs/super.c b/fs/super.c index 4906e2d8f400..1cb26a3e3df0 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -743,9 +743,14 @@ int get_sb_bdev(struct file_system_type *fs_type, | |||
743 | * will protect the lockfs code from trying to start a snapshot | 743 | * will protect the lockfs code from trying to start a snapshot |
744 | * while we are mounting | 744 | * while we are mounting |
745 | */ | 745 | */ |
746 | down(&bdev->bd_mount_sem); | 746 | mutex_lock(&bdev->bd_fsfreeze_mutex); |
747 | if (bdev->bd_fsfreeze_count > 0) { | ||
748 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | ||
749 | error = -EBUSY; | ||
750 | goto error_bdev; | ||
751 | } | ||
747 | s = sget(fs_type, test_bdev_super, set_bdev_super, bdev); | 752 | s = sget(fs_type, test_bdev_super, set_bdev_super, bdev); |
748 | up(&bdev->bd_mount_sem); | 753 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
749 | if (IS_ERR(s)) | 754 | if (IS_ERR(s)) |
750 | goto error_s; | 755 | goto error_s; |
751 | 756 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index cbb7724c11d3..72dfbd423974 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -640,7 +640,6 @@ struct block_device { | |||
640 | struct super_block * bd_super; | 640 | struct super_block * bd_super; |
641 | int bd_openers; | 641 | int bd_openers; |
642 | struct mutex bd_mutex; /* open/close mutex */ | 642 | struct mutex bd_mutex; /* open/close mutex */ |
643 | struct semaphore bd_mount_sem; | ||
644 | struct list_head bd_inodes; | 643 | struct list_head bd_inodes; |
645 | void * bd_holder; | 644 | void * bd_holder; |
646 | int bd_holders; | 645 | int bd_holders; |