From: Al Viro Date: Thu, 3 Oct 2013 16:53:37 +0000 (-0400) Subject: cifs: rcu-delay unload_nls() and freeing sbi X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=2e32cf5ef2683a196df24ccd2cd2b4ed735ad9d3;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git cifs: rcu-delay unload_nls() and freeing sbi makes ->d_hash(), ->d_compare() and ->permission() safety in RCU mode independent from vfsmount_lock. Signed-off-by: Al Viro --- diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 37e4a72a7d1c..9409fa10bd5c 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h @@ -65,5 +65,6 @@ struct cifs_sb_info { char *mountdata; /* options received at mount time or via DFS refs */ struct backing_dev_info bdi; struct delayed_work prune_tlinks; + struct rcu_head rcu; }; #endif /* _CIFS_FS_SB_H */ diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index a279ffc0bc29..886db8b41e35 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3755,6 +3755,13 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses, return rc; } +static void delayed_free(struct rcu_head *p) +{ + struct cifs_sb_info *sbi = container_of(p, struct cifs_sb_info, rcu); + unload_nls(sbi->local_nls); + kfree(sbi); +} + void cifs_umount(struct cifs_sb_info *cifs_sb) { @@ -3779,8 +3786,7 @@ cifs_umount(struct cifs_sb_info *cifs_sb) bdi_destroy(&cifs_sb->bdi); kfree(cifs_sb->mountdata); - unload_nls(cifs_sb->local_nls); - kfree(cifs_sb); + call_rcu(&cifs_sb->rcu, delayed_free); } int