ncpfs: rcu-delay unload_nls() and freeing ncp_server
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 3 Oct 2013 17:22:44 +0000 (13:22 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Fri, 25 Oct 2013 03:43:28 +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/ncpfs/inode.c
fs/ncpfs/ncp_fs_sb.h

index 4659da6..2cf2ebe 100644 (file)
@@ -782,6 +782,17 @@ out:
        return error;
 }
 
+static void delayed_free(struct rcu_head *p)
+{
+       struct ncp_server *server = container_of(p, struct ncp_server, rcu);
+#ifdef CONFIG_NCPFS_NLS
+       /* unload the NLS charsets */
+       unload_nls(server->nls_vol);
+       unload_nls(server->nls_io);
+#endif /* CONFIG_NCPFS_NLS */
+       kfree(server);
+}
+
 static void ncp_put_super(struct super_block *sb)
 {
        struct ncp_server *server = NCP_SBP(sb);
@@ -792,11 +803,6 @@ static void ncp_put_super(struct super_block *sb)
 
        ncp_stop_tasks(server);
 
-#ifdef CONFIG_NCPFS_NLS
-       /* unload the NLS charsets */
-       unload_nls(server->nls_vol);
-       unload_nls(server->nls_io);
-#endif /* CONFIG_NCPFS_NLS */
        mutex_destroy(&server->rcv.creq_mutex);
        mutex_destroy(&server->root_setup_lock);
        mutex_destroy(&server->mutex);
@@ -813,8 +819,7 @@ static void ncp_put_super(struct super_block *sb)
        vfree(server->rxbuf);
        vfree(server->txbuf);
        vfree(server->packet);
-       sb->s_fs_info = NULL;
-       kfree(server);
+       call_rcu(&server->rcu, delayed_free);
 }
 
 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
index c51b2c5..b81e97a 100644 (file)
@@ -38,7 +38,7 @@ struct ncp_mount_data_kernel {
 };
 
 struct ncp_server {
-
+       struct rcu_head rcu;
        struct ncp_mount_data_kernel m; /* Nearly all of the mount data is of
                                           interest for us later, so we store
                                           it completely. */