diff options
author | Stefan Behrens <sbehrens@giantdisaster.de> | 2013-10-11 17:14:58 +0200 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2013-11-11 22:01:18 -0500 |
commit | 361c093d7f99c3f6cbb07d5c580ce778ab418c42 (patch) | |
tree | d98d188e9350117d7dcc0a5d08cab65bec0fca08 /fs/btrfs | |
parent | 27087f370174ebb298cdf6dcb36b1e4dcbe34e93 (diff) |
Btrfs: Wait for uuid-tree rebuild task on remount read-only
If the user remounts the filesystem read-only while the uuid-tree
scan and rebuild task is still running (this happens once after the
filesystem was mounted with an old kernel, or when forced with the
mount options), the remount should wait on the tasks completion
before setting the filesystem read-only. Otherwise the background
task continues to write to the filesystem which is apparently not
what users expect.
The reproducer:
TEST_DEV=/dev/sdzzzzz1
TEST_MNT=/mnt
mkfs.btrfs -f $TEST_DEV
mount $TEST_DEV $TEST_MNT
for i in `seq 50000`; do btrfs subvolume create ${TEST_MNT}/$i; done
umount $TEST_MNT
mount $TEST_DEV $TEST_MNT -o rescan_uuid_tree
sleep 1
ps -elf | fgrep '[btrfs-uuid]' | grep -v grep
mount $TEST_DEV $TEST_MNT -o ro,remount
ps -elf | fgrep '[btrfs-uuid]' | grep -v grep
sleep 1
umount $TEST_MNT
Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/super.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 1f62c1ccab1f..02f552f11829 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1330,6 +1330,12 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) * this also happens on 'umount -rf' or on shutdown, when * the filesystem is busy. */ + + /* wait for the uuid_scan task to finish */ + down(&fs_info->uuid_tree_rescan_sem); + /* avoid complains from lockdep et al. */ + up(&fs_info->uuid_tree_rescan_sem); + sb->s_flags |= MS_RDONLY; btrfs_dev_replace_suspend_for_unmount(fs_info); |