--- x/fs/super.c +++ y/fs/super.c @@ -660,6 +660,7 @@ EXPORT_SYMBOL(retire_super); void generic_shutdown_super(struct super_block *sb) { const struct super_operations *sop = sb->s_op; + put = 0; if (sb->s_root) { shrink_dcache_for_umount(sb); @@ -689,8 +690,7 @@ void generic_shutdown_super(struct super sb->s_dio_done_wq = NULL; } - if (sop->put_super) - sop->put_super(sb); + put = 1; if (CHECK_DATA_CORRUPTION(!list_empty(&sb->s_inodes), "VFS: Busy inodes after unmount of %s (%s)", @@ -722,6 +722,10 @@ void generic_shutdown_super(struct super */ super_wake(sb, SB_DYING); super_unlock_excl(sb); + + if (put && sop->put_super) + sop->put_super(sb); + if (sb->s_bdi != &noop_backing_dev_info) { if (sb->s_iflags & SB_I_PERSB_BDI) bdi_unregister(sb->s_bdi); @@ -1624,9 +1628,9 @@ struct dentry *mount_bdev(struct file_sy */ super_unlock_excl(s); error = setup_bdev_super(s, flags, NULL); - __super_lock_excl(s); if (!error) error = fill_super(s, data, flags & SB_SILENT ? 1 : 0); + __super_lock_excl(s); if (error) { deactivate_locked_super(s); return ERR_PTR(error);