ncpfs: rcu-delay unload_nls() and freeing ncp_server
makes ->d_hash() and ->d_compare() safety in RCU mode independent from vfsmount_lock. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
cac45b062c
commit
1dcddd4abd
|
@ -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)
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Reference in New Issue