aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2011-11-17 01:29:09 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2012-01-08 19:33:23 -0500
commit6de1d09d9677dce7a04ef485d426821159ab7de9 (patch)
treee906ecf66e13f5827df4a4c34adb327a45a73542 /fs/btrfs/super.c
parentaea52e19dd2085617dd7d247afb76a90cf2ea40c (diff)
btrfs: fix mount/umount race
Do *NOT* skip doomed superblocks in btrfs_test_super(); we want sget() to wait for their shutdown to complete. Since we don't mutilate ->s_fs_info in ->put_super() anymore (or free what it used to point to until the superblock is past being findable by sget()), we can just DTRT there and report a match. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r--fs/btrfs/super.c13
1 files changed, 4 insertions, 9 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index eca48624a4f0..b9fd62a0fca2 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -733,20 +733,15 @@ static int btrfs_test_super(struct super_block *s, void *data)
733 struct btrfs_root *test_root = data; 733 struct btrfs_root *test_root = data;
734 struct btrfs_root *root = btrfs_sb(s); 734 struct btrfs_root *root = btrfs_sb(s);
735 735
736 /*
737 * If this super block is going away, return false as it
738 * can't match as an existing super block.
739 */
740 if (!atomic_read(&s->s_active))
741 return 0;
742 return root->fs_info->fs_devices == test_root->fs_info->fs_devices; 736 return root->fs_info->fs_devices == test_root->fs_info->fs_devices;
743} 737}
744 738
745static int btrfs_set_super(struct super_block *s, void *data) 739static int btrfs_set_super(struct super_block *s, void *data)
746{ 740{
747 s->s_fs_info = data; 741 int err = set_anon_super(s, data);
748 742 if (!err)
749 return set_anon_super(s, data); 743 s->s_fs_info = data;
744 return err;
750} 745}
751 746
752/* 747/*