diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-10-03 13:22:44 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-10-24 23:43:28 -0400 |
commit | 1dcddd4abd2c6df7f28928ad5cafa4a1cd20030b (patch) | |
tree | 5aad2d4a6ec078b16750b77217e10a8a3172d38a /fs/ncpfs/inode.c | |
parent | cac45b062c67f86dc1d91d675128838773523243 (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.c | 19 |
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 | ||
785 | static 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 | |||
785 | static void ncp_put_super(struct super_block *sb) | 796 | static 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 | ||
820 | static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf) | 825 | static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf) |