WIP: update tizen_qemu_defconfig
[platform/kernel/linux-starfive.git] / fs / super.c
index 8d39e4f..7c140ee 100644 (file)
@@ -476,13 +476,22 @@ void generic_shutdown_super(struct super_block *sb)
 
                cgroup_writeback_umount();
 
-               /* evict all inodes with zero refcount */
+               /* Evict all inodes with zero refcount. */
                evict_inodes(sb);
-               /* only nonzero refcount inodes can have marks */
+
+               /*
+                * Clean up and evict any inodes that still have references due
+                * to fsnotify or the security policy.
+                */
                fsnotify_sb_delete(sb);
-               fscrypt_destroy_keyring(sb);
                security_sb_delete(sb);
 
+               /*
+                * Now that all potentially-encrypted inodes have been evicted,
+                * the fscrypt keyring can be destroyed.
+                */
+               fscrypt_destroy_keyring(sb);
+
                if (sb->s_dio_done_wq) {
                        destroy_workqueue(sb->s_dio_done_wq);
                        sb->s_dio_done_wq = NULL;
@@ -491,10 +500,23 @@ void generic_shutdown_super(struct super_block *sb)
                if (sop->put_super)
                        sop->put_super(sb);
 
-               if (!list_empty(&sb->s_inodes)) {
-                       printk("VFS: Busy inodes after unmount of %s. "
-                          "Self-destruct in 5 seconds.  Have a nice day...\n",
-                          sb->s_id);
+               if (CHECK_DATA_CORRUPTION(!list_empty(&sb->s_inodes),
+                               "VFS: Busy inodes after unmount of %s (%s)",
+                               sb->s_id, sb->s_type->name)) {
+                       /*
+                        * Adding a proper bailout path here would be hard, but
+                        * we can at least make it more likely that a later
+                        * iput_final() or such crashes cleanly.
+                        */
+                       struct inode *inode;
+
+                       spin_lock(&sb->s_inode_list_lock);
+                       list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
+                               inode->i_op = VFS_PTR_POISON;
+                               inode->i_sb = VFS_PTR_POISON;
+                               inode->i_mapping = VFS_PTR_POISON;
+                       }
+                       spin_unlock(&sb->s_inode_list_lock);
                }
        }
        spin_lock(&sb_lock);