Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

Al Viro 1dcddd4a cac45b06

+13 -8
+12 -7
fs/ncpfs/inode.c
··· 782 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 796 static void ncp_put_super(struct super_block *sb) 786 797 { 787 798 struct ncp_server *server = NCP_SBP(sb); ··· 803 792 804 793 ncp_stop_tasks(server); 805 794 806 - #ifdef CONFIG_NCPFS_NLS 807 - /* unload the NLS charsets */ 808 - unload_nls(server->nls_vol); 809 - unload_nls(server->nls_io); 810 - #endif /* CONFIG_NCPFS_NLS */ 811 795 mutex_destroy(&server->rcv.creq_mutex); 812 796 mutex_destroy(&server->root_setup_lock); 813 797 mutex_destroy(&server->mutex); ··· 819 813 vfree(server->rxbuf); 820 814 vfree(server->txbuf); 821 815 vfree(server->packet); 822 - sb->s_fs_info = NULL; 823 - kfree(server); 816 + call_rcu(&server->rcu, delayed_free); 824 817 } 825 818 826 819 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
+1 -1
fs/ncpfs/ncp_fs_sb.h
··· 38 38 }; 39 39 40 40 struct ncp_server { 41 - 41 + struct rcu_head rcu; 42 42 struct ncp_mount_data_kernel m; /* Nearly all of the mount data is of 43 43 interest for us later, so we store 44 44 it completely. */