aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ncpfs/inode.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-10-03 13:22:44 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-10-24 23:43:28 -0400
commit1dcddd4abd2c6df7f28928ad5cafa4a1cd20030b (patch)
tree5aad2d4a6ec078b16750b77217e10a8a3172d38a /fs/ncpfs/inode.c
parentcac45b062c67f86dc1d91d675128838773523243 (diff)
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>
Diffstat (limited to 'fs/ncpfs/inode.c')
-rw-r--r--fs/ncpfs/inode.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index 4659da67e7f6..2cf2ebecb55f 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -782,6 +782,17 @@ out:
782 return error; 782 return error;
783} 783}
784 784
785static void delayed_free(struct rcu_head *p)
786{
787 struct ncp_server *server = container_of(p, struct ncp_server, rcu);
788#ifdef CONFIG_NCPFS_NLS
789 /* unload the NLS charsets */
790 unload_nls(server->nls_vol);
791 unload_nls(server->nls_io);
792#endif /* CONFIG_NCPFS_NLS */
793 kfree(server);
794}
795
785static void ncp_put_super(struct super_block *sb) 796static void ncp_put_super(struct super_block *sb)
786{ 797{
787 struct ncp_server *server = NCP_SBP(sb); 798 struct ncp_server *server = NCP_SBP(sb);
@@ -792,11 +803,6 @@ static void ncp_put_super(struct super_block *sb)
792 803
793 ncp_stop_tasks(server); 804 ncp_stop_tasks(server);
794 805
795#ifdef CONFIG_NCPFS_NLS
796 /* unload the NLS charsets */
797 unload_nls(server->nls_vol);
798 unload_nls(server->nls_io);
799#endif /* CONFIG_NCPFS_NLS */
800 mutex_destroy(&server->rcv.creq_mutex); 806 mutex_destroy(&server->rcv.creq_mutex);
801 mutex_destroy(&server->root_setup_lock); 807 mutex_destroy(&server->root_setup_lock);
802 mutex_destroy(&server->mutex); 808 mutex_destroy(&server->mutex);
@@ -813,8 +819,7 @@ static void ncp_put_super(struct super_block *sb)
813 vfree(server->rxbuf); 819 vfree(server->rxbuf);
814 vfree(server->txbuf); 820 vfree(server->txbuf);
815 vfree(server->packet); 821 vfree(server->packet);
816 sb->s_fs_info = NULL; 822 call_rcu(&server->rcu, delayed_free);
817 kfree(server);
818} 823}
819 824
820static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf) 825static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)