diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2010-03-23 01:15:33 +0100 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-05-22 00:31:15 +0200 |
commit | 1494583de59dfad2e3a6788ce9817e658d32df22 (patch) | |
tree | 6f0a0fe022af703aa18ecc5f65a616fe44b9f8ad | |
parent | fix do_emergency_remount()/umount() races (diff) | |
download | linux-1494583de59dfad2e3a6788ce9817e658d32df22.tar.xz linux-1494583de59dfad2e3a6788ce9817e658d32df22.zip |
fix get_active_super()/umount() race
This one needs restarts...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/super.c | 14 |
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; |