diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2010-03-23 01:23:25 +0100 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-05-22 00:31:16 +0200 |
commit | df40c01a9249873e4ad0625ae5d9fb831962b75c (patch) | |
tree | 9d049e176ad6a329e040faa32d6ee5933d1cea58 /fs/super.c | |
parent | fix get_active_super()/umount() race (diff) | |
download | linux-df40c01a9249873e4ad0625ae5d9fb831962b75c.tar.xz linux-df40c01a9249873e4ad0625ae5d9fb831962b75c.zip |
In get_super() and user_get_super() restarts are unconditional
If superblock had been still alive, we would've returned it...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to '')
-rw-r--r-- | fs/super.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/fs/super.c b/fs/super.c index 44971d7df1ce..1f72e0d42d8f 100644 --- a/fs/super.c +++ b/fs/super.c @@ -425,7 +425,7 @@ void sync_supers(void) * mounted on the device given. %NULL is returned if no match is found. */ -struct super_block * get_super(struct block_device *bdev) +struct super_block *get_super(struct block_device *bdev) { struct super_block *sb; @@ -441,13 +441,14 @@ rescan: sb->s_count++; spin_unlock(&sb_lock); down_read(&sb->s_umount); + /* still alive? */ if (sb->s_root) return sb; up_read(&sb->s_umount); - /* restart only when sb is no longer on the list */ + /* nope, got unmounted */ spin_lock(&sb_lock); - if (__put_super_and_need_restart(sb)) - goto rescan; + __put_super(sb); + goto rescan; } } spin_unlock(&sb_lock); @@ -487,7 +488,7 @@ restart: return NULL; } -struct super_block * user_get_super(dev_t dev) +struct super_block *user_get_super(dev_t dev) { struct super_block *sb; @@ -500,13 +501,14 @@ rescan: sb->s_count++; spin_unlock(&sb_lock); down_read(&sb->s_umount); + /* still alive? */ if (sb->s_root) return sb; up_read(&sb->s_umount); - /* restart only when sb is no longer on the list */ + /* nope, got unmounted */ spin_lock(&sb_lock); - if (__put_super_and_need_restart(sb)) - goto rescan; + __put_super(sb); + goto rescan; } } spin_unlock(&sb_lock); |