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>
This commit is contained in:
parent
1494583de5
commit
df40c01a92
1 changed files with 10 additions and 8 deletions
18
fs/super.c
18
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 @@ struct super_block * get_super(struct block_device *bdev)
|
|||
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 @@ struct super_block *get_active_super(struct block_device *bdev)
|
|||
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 @@ struct super_block * user_get_super(dev_t dev)
|
|||
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);
|
||||
|
|
Loading…
Reference in a new issue