d_add_ci(): make sure we don't miss d_lookup_done()
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 30 Jul 2022 04:29:05 +0000 (00:29 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sat, 30 Jul 2022 04:29:05 +0000 (00:29 -0400)
All callers of d_alloc_parallel() must make sure that resulting
in-lookup dentry (if any) will encounter __d_lookup_done() before
the final dput().  d_add_ci() might end up creating in-lookup
dentries; they are fed to d_splice_alias(), which will normally
make sure they meet __d_lookup_done().  However, it is possible
to end up with d_splice_alias() failing with ERR_PTR(-ELOOP)
without having done so.  It takes a corrupted ntfs or case-insensitive
xfs image, but neither should end up with memory corruption...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/dcache.c

index 93f4f5e..94b7373 100644 (file)
@@ -2240,6 +2240,7 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
        }
        res = d_splice_alias(inode, found);
        if (res) {
+               d_lookup_done(found);
                dput(found);
                return res;
        }