From: Jeff Layton Date: Wed, 22 Apr 2026 11:29:48 +0000 (-0400) Subject: dcache: add extra sanity checks of the dentry in dentry_free() X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=c06d4e760c9842b013fce9614fbfd6db966c061d;p=thirdparty%2Fkernel%2Flinux.git dcache: add extra sanity checks of the dentry in dentry_free() If d_flags isn't what we expect, then it's good to display it. Add a new DENTRY_WARN_ONCE() macro that also displays d_flags for the dentry. Change D_FLAG_VERIFY() to call that instead of a generic WARN_ON_ONCE(). Change the existing hlist_unhashed() check in dentry_free() to use the new macro, and add checks for other invariants of a dead dentry. Notably: 1) Ensure that DCACHE_LRU_LIST and DCACHE_SHRINK_LIST are not set. 2) Ensure that d_lockref is negative Signed-off-by: Jeff Layton Link: https://patch.msgid.link/20260422-dcache-warn-v1-1-50155e1b40b6@kernel.org Signed-off-by: Christian Brauner (Amutable) --- diff --git a/fs/dcache.c b/fs/dcache.c index 8ffc4ef79bbab..131a3cf1c3609 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -426,9 +426,16 @@ static inline void __d_clear_type_and_inode(struct dentry *dentry) this_cpu_inc(nr_dentry_negative); } +#define DENTRY_WARN_ONCE(condition, dentry) \ + WARN_ONCE((condition), "dentry=%p d_flags=0x%x\n", (dentry), (dentry)->d_flags) +#define D_FLAG_VERIFY(dentry, x) \ + DENTRY_WARN_ONCE(((dentry)->d_flags & (DCACHE_LRU_LIST | DCACHE_SHRINK_LIST)) != (x), (dentry)) + static void dentry_free(struct dentry *dentry) { - WARN_ON(d_really_is_positive(dentry)); + DENTRY_WARN_ONCE(d_really_is_positive(dentry), dentry); + DENTRY_WARN_ONCE(dentry->d_lockref.count >= 0, dentry); + D_FLAG_VERIFY(dentry, 0); if (unlikely(dname_external(dentry))) { struct external_name *p = external_name(dentry); if (likely(atomic_dec_and_test(&p->count))) { @@ -495,7 +502,6 @@ static void dentry_unlink_inode(struct dentry * dentry) * These helper functions make sure we always follow the * rules. d_lock must be held by the caller. */ -#define D_FLAG_VERIFY(dentry,x) WARN_ON_ONCE(((dentry)->d_flags & (DCACHE_LRU_LIST | DCACHE_SHRINK_LIST)) != (x)) static void d_lru_add(struct dentry *dentry) { D_FLAG_VERIFY(dentry, 0);