diff --git a/fs/super.c b/fs/super.c index eeb8f745a8bf..b8638feee171 100644 --- a/fs/super.c +++ b/fs/super.c @@ -1006,13 +1006,24 @@ void emergency_remount(void) static void do_thaw_all_callback(struct super_block *sb) { + bool active = false; + down_write(&sb->s_umount); - if (sb->s_root && sb->s_flags & SB_BORN) { - emergency_thaw_bdev(sb); + if (sb->s_root && sb->s_flags & SB_BORN) + active = atomic_inc_not_zero(&sb->s_active); + up_write(&sb->s_umount); + if (!active) + return; + + /* thaw_bdev() acquires s_umount so it must not be held here */ + emergency_thaw_bdev(sb); + + down_write(&sb->s_umount); + if (sb->s_root && sb->s_flags & SB_BORN) thaw_super_locked(sb); - } else { + else up_write(&sb->s_umount); - } + deactivate_super(sb); } static void do_thaw_all(struct work_struct *work)