Commit 040f04bd authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

fs: simplify freeze_bdev/thaw_bdev



Store the frozen superblock in struct block_device to avoid the awkward
interface that can return a sb only used a cookie, an ERR_PTR or NULL.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
Acked-by: Chao Yu <yuchao0@huawei.com>		[f2fs]
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 60b49885
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -96,11 +96,6 @@ struct mapped_device {
	 */
	struct workqueue_struct *wq;

	/*
	 * freeze/thaw support require holding onto a super block
	 */
	struct super_block *frozen_sb;

	/* forced geometry settings */
	struct hd_geometry geometry;

+6 −14
Original line number Diff line number Diff line
@@ -2392,27 +2392,19 @@ static int lock_fs(struct mapped_device *md)
{
	int r;

	WARN_ON(md->frozen_sb);

	md->frozen_sb = freeze_bdev(md->bdev);
	if (IS_ERR(md->frozen_sb)) {
		r = PTR_ERR(md->frozen_sb);
		md->frozen_sb = NULL;
		return r;
	}
	WARN_ON(test_bit(DMF_FROZEN, &md->flags));

	r = freeze_bdev(md->bdev);
	if (!r)
		set_bit(DMF_FROZEN, &md->flags);

	return 0;
	return r;
}

static void unlock_fs(struct mapped_device *md)
{
	if (!test_bit(DMF_FROZEN, &md->flags))
		return;

	thaw_bdev(md->bdev, md->frozen_sb);
	md->frozen_sb = NULL;
	thaw_bdev(md->bdev);
	clear_bit(DMF_FROZEN, &md->flags);
}

+15 −22
Original line number Diff line number Diff line
@@ -548,55 +548,47 @@ EXPORT_SYMBOL(fsync_bdev);
 * count down in thaw_bdev(). When it becomes 0, thaw_bdev() will unfreeze
 * actually.
 */
struct super_block *freeze_bdev(struct block_device *bdev)
int freeze_bdev(struct block_device *bdev)
{
	struct super_block *sb;
	int error = 0;

	mutex_lock(&bdev->bd_fsfreeze_mutex);
	if (++bdev->bd_fsfreeze_count > 1) {
		/*
		 * We don't even need to grab a reference - the first call
		 * to freeze_bdev grab an active reference and only the last
		 * thaw_bdev drops it.
		 */
		sb = get_super(bdev);
		if (sb)
			drop_super(sb);
		mutex_unlock(&bdev->bd_fsfreeze_mutex);
		return sb;
	}
	if (++bdev->bd_fsfreeze_count > 1)
		goto done;

	sb = get_active_super(bdev);
	if (!sb)
		goto out;
		goto sync;
	if (sb->s_op->freeze_super)
		error = sb->s_op->freeze_super(sb);
	else
		error = freeze_super(sb);
	if (error) {
	deactivate_super(sb);

	if (error) {
		bdev->bd_fsfreeze_count--;
		mutex_unlock(&bdev->bd_fsfreeze_mutex);
		return ERR_PTR(error);
		goto done;
	}
	deactivate_super(sb);
 out:
	bdev->bd_fsfreeze_sb = sb;

sync:
	sync_blockdev(bdev);
done:
	mutex_unlock(&bdev->bd_fsfreeze_mutex);
	return sb;	/* thaw_bdev releases s->s_umount */
	return error;
}
EXPORT_SYMBOL(freeze_bdev);

/**
 * thaw_bdev  -- unlock filesystem
 * @bdev:	blockdevice to unlock
 * @sb:		associated superblock
 *
 * Unlocks the filesystem and marks it writeable again after freeze_bdev().
 */
int thaw_bdev(struct block_device *bdev, struct super_block *sb)
int thaw_bdev(struct block_device *bdev)
{
	struct super_block *sb;
	int error = -EINVAL;

	mutex_lock(&bdev->bd_fsfreeze_mutex);
@@ -607,6 +599,7 @@ int thaw_bdev(struct block_device *bdev, struct super_block *sb)
	if (--bdev->bd_fsfreeze_count > 0)
		goto out;

	sb = bdev->bd_fsfreeze_sb;
	if (!sb)
		goto out;

+1 −1
Original line number Diff line number Diff line
@@ -523,7 +523,7 @@ repeat:

void emergency_thaw_bdev(struct super_block *sb)
{
	while (sb->s_bdev && !thaw_bdev(sb->s_bdev, sb))
	while (sb->s_bdev && !thaw_bdev(sb->s_bdev))
		printk(KERN_WARNING "Emergency Thaw on %pg\n", sb->s_bdev);
}

+1 −1
Original line number Diff line number Diff line
@@ -624,7 +624,7 @@ static int ext4_shutdown(struct super_block *sb, unsigned long arg)
	case EXT4_GOING_FLAGS_DEFAULT:
		freeze_bdev(sb->s_bdev);
		set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
		thaw_bdev(sb->s_bdev, sb);
		thaw_bdev(sb->s_bdev);
		break;
	case EXT4_GOING_FLAGS_LOGFLUSH:
		set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
Loading