summaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorShyam Prasad N <sprasad@microsoft.com>2022-04-01 06:25:17 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-04-20 09:34:10 +0200
commit675e7d3086d0aa360b6ce856ce55cd003589f9ad (patch)
treec971357d8918dc2a3b91c3109522464330506bb0 /fs/cifs
parentd40cf3492277d203c1f676cb9df88ab55d0c5d0f (diff)
downloadlinux-stable-675e7d3086d0aa360b6ce856ce55cd003589f9ad.tar.gz
linux-stable-675e7d3086d0aa360b6ce856ce55cd003589f9ad.tar.bz2
linux-stable-675e7d3086d0aa360b6ce856ce55cd003589f9ad.zip
cifs: release cached dentries only if mount is complete
[ Upstream commit d788e51636462e61c6883f7d96b07b06bc291650 ] During cifs_kill_sb, we first dput all the dentries that we have cached. However this function can also get called for mount failures. So dput the cached dentries only if the filesystem mount is complete. i.e. cifs_sb->root is populated. Fixes: 5e9c89d43fa6 ("cifs: Grab a reference for the dentry of the cached directory during the lifetime of the cache") Signed-off-by: Shyam Prasad N <sprasad@microsoft.com> Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsfs.c28
1 files changed, 15 insertions, 13 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index ed220daca3e1..92fd1a7e83dc 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -266,22 +266,24 @@ static void cifs_kill_sb(struct super_block *sb)
* before we kill the sb.
*/
if (cifs_sb->root) {
+ node = rb_first(root);
+ while (node != NULL) {
+ tlink = rb_entry(node, struct tcon_link, tl_rbnode);
+ tcon = tlink_tcon(tlink);
+ cfid = &tcon->crfid;
+ mutex_lock(&cfid->fid_mutex);
+ if (cfid->dentry) {
+ dput(cfid->dentry);
+ cfid->dentry = NULL;
+ }
+ mutex_unlock(&cfid->fid_mutex);
+ node = rb_next(node);
+ }
+
+ /* finally release root dentry */
dput(cifs_sb->root);
cifs_sb->root = NULL;
}
- node = rb_first(root);
- while (node != NULL) {
- tlink = rb_entry(node, struct tcon_link, tl_rbnode);
- tcon = tlink_tcon(tlink);
- cfid = &tcon->crfid;
- mutex_lock(&cfid->fid_mutex);
- if (cfid->dentry) {
- dput(cfid->dentry);
- cfid->dentry = NULL;
- }
- mutex_unlock(&cfid->fid_mutex);
- node = rb_next(node);
- }
kill_anon_super(sb);
cifs_umount(cifs_sb);