summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2010-03-23 03:15:33 +0300
committerAl Viro <viro@zeniv.linux.org.uk>2010-05-22 02:31:15 +0400
commit1494583de59dfad2e3a6788ce9817e658d32df22 (patch)
tree6f0a0fe022af703aa18ecc5f65a616fe44b9f8ad /fs
parente7fe0585ca8793e2d43c57e77d4ca79042806acf (diff)
downloadlinux-1494583de59dfad2e3a6788ce9817e658d32df22.tar.xz
fix get_active_super()/umount() race
This one needs restarts... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/super.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/fs/super.c b/fs/super.c
index 4df8233dfb61..44971d7df1ce 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -471,17 +471,17 @@ struct super_block *get_active_super(struct block_device *bdev)
if (!bdev)
return NULL;
+restart:
spin_lock(&sb_lock);
list_for_each_entry(sb, &super_blocks, s_list) {
if (list_empty(&sb->s_instances))
continue;
- if (sb->s_bdev != bdev)
- continue;
-
- if (grab_super(sb)) /* drops sb_lock */
- return sb;
-
- spin_lock(&sb_lock);
+ if (sb->s_bdev == bdev) {
+ if (grab_super(sb)) /* drops sb_lock */
+ return sb;
+ else
+ goto restart;
+ }
}
spin_unlock(&sb_lock);
return NULL;