Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1dcddd4a authored by Al Viro's avatar Al Viro
Browse files

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: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent cac45b06
Loading
Loading
Loading
Loading
+12 −7
Original line number Diff line number Diff line
@@ -782,6 +782,17 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
	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)
+1 −1
Original line number Diff line number Diff line
@@ -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. */