adfs: delayed freeing of sbi
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 3 Oct 2013 16:37:18 +0000 (12:37 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Fri, 25 Oct 2013 03:43:27 +0000 (23:43 -0400)
makes ->d_hash() and ->d_compare() safety in RCU mode independent
from vfsmount_lock.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/adfs/adfs.h
fs/adfs/super.c

index 585adafb0cc270f9e0b023b2543e1151fa83e3b4..c770337c4b458beefc707a91fb8c9f7315d0634b 100644 (file)
@@ -43,9 +43,12 @@ struct adfs_dir_ops;
  * ADFS file system superblock data in memory
  */
 struct adfs_sb_info {
-       struct adfs_discmap *s_map;     /* bh list containing map                */
-       struct adfs_dir_ops *s_dir;     /* directory operations                  */
-
+       union { struct {
+               struct adfs_discmap *s_map;     /* bh list containing map        */
+               struct adfs_dir_ops *s_dir;     /* directory operations          */
+               };
+               struct rcu_head rcu;            /* used only at shutdown time    */
+       };
        kuid_t          s_uid;          /* owner uid                             */
        kgid_t          s_gid;          /* owner gid                             */
        umode_t         s_owner_mask;   /* ADFS owner perm -> unix perm          */
index 0ff4bae2c2a2c2372a75bc5486a4920672aef0bf..7b3003cb6f1bde4d562d01e85db3455d120c7309 100644 (file)
@@ -123,8 +123,7 @@ static void adfs_put_super(struct super_block *sb)
        for (i = 0; i < asb->s_map_size; i++)
                brelse(asb->s_map[i].dm_bh);
        kfree(asb->s_map);
-       kfree(asb);
-       sb->s_fs_info = NULL;
+       kfree_rcu(asb, rcu);
 }
 
 static int adfs_show_options(struct seq_file *seq, struct dentry *root)