summaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifsfs.c
diff options
context:
space:
mode:
authorRonnie Sahlberg <lsahlber@redhat.com>2021-03-09 09:07:31 +1000
committerSteve French <stfrench@microsoft.com>2021-04-25 16:28:23 -0500
commit5e9c89d43fa6f5d458d4d0f9e22a67cc001c8da9 (patch)
treee0882caf0f8bf52942dcfcbf9e671d41d82d97c6 /fs/cifs/cifsfs.c
parent269f67e1ffead61777b1b0cf2ea0f61d06f8c56d (diff)
downloadlinux-5e9c89d43fa6f5d458d4d0f9e22a67cc001c8da9.tar.bz2
cifs: Grab a reference for the dentry of the cached directory during the lifetime of the cache
We need to hold both a reference for the root/superblock as well as the directory that we are caching. We need to drop these references before we call kill_anon_sb(). At this point, the root and the cached dentries are always the same but this will change once we start caching other directories as well. Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs/cifsfs.c')
-rw-r--r--fs/cifs/cifsfs.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index cf8eceb1d5a5..4257f841ec4e 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -257,11 +257,28 @@ out_no_root:
static void cifs_kill_sb(struct super_block *sb)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+ struct cifs_tcon *tcon;
+ struct cached_fid *cfid;
+ /*
+ * We ned to release all dentries for the cached directories
+ * before we kill the sb.
+ */
if (cifs_sb->root) {
dput(cifs_sb->root);
cifs_sb->root = NULL;
}
+ tcon = cifs_sb_master_tcon(cifs_sb);
+ if (tcon) {
+ cfid = &tcon->crfid;
+ mutex_lock(&cfid->fid_mutex);
+ if (cfid->dentry) {
+
+ dput(cfid->dentry);
+ cfid->dentry = NULL;
+ }
+ mutex_unlock(&cfid->fid_mutex);
+ }
kill_anon_super(sb);
cifs_umount(cifs_sb);