Using d_unhashed() brings a race window with d_add() and d_drop()
leading to dentry hash table corruption. If dentry which is in hash
already is added to hash table, it gets looped to itself via next
pointer:
dentry 0xffff8fd34cc08840
...
d_hash = {
next = 0xffff8fd34cc08848,
pprev = 0x0
},
See for reference:
commit
00699ad8571afd7fb8bc2c61f67c86c2428680ab
Author: Al Viro <viro@zeniv.linux.org.uk>
Date: Tue Jul 5 09:44:53 2016 -0400
Use the right predicate in ->atomic_open() instances
Keep using d_unhashed() if d_in_lookup() is not provided by kernel.
HPE-bug-id: LUS-11560
Signed-off-by: Vladimir Saveliev <vladimir.saveliev@hpe.com>
Change-Id: I6c27f031d0d7e7d571752d6172a32406ad68e913
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/51147
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Neil Brown <neilb@suse.de>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
/* Only negative dentries enter here */
LASSERT(dentry->d_inode == NULL);
+#ifndef HAVE_D_IN_LOOKUP
if (!d_unhashed(dentry)) {
+#else
+ if (!d_in_lookup(dentry)) {
+#endif
/* A valid negative dentry that just passed revalidation,
* there's little point to try and open it server-side,
* even though there's a minuscule chance it might succeed.