Patch from Maneesh Soni Turns out that sysfs is doing dget() on a zero-ref dentry. That's a bug, but dcache is no longer detecting it. The check was removed because with lockless d_lookup, there can be cases when d_lookup and dput are going on concurrently, If d_lookup happens earlier then it may do dget() on a dentry for which dput() has decremented the ref count to zero. This race is handled by taking the per dentry lock and checking the DCACHE_UNHASHED flag. The patch open-codes that part of d_lookup(), and restores the BUG check in dget(). dcache.c | 7 +++++-- linux/dcache.h | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff -puN fs/dcache.c~dget-BUG fs/dcache.c --- 25/fs/dcache.c~dget-BUG 2003-02-20 02:09:12.000000000 -0800 +++ 25-akpm/fs/dcache.c 2003-02-20 02:09:12.000000000 -0800 @@ -1004,8 +1004,11 @@ struct dentry * d_lookup(struct dentry * */ if (unlikely(move_count != dentry->d_move_count)) break; - if (!d_unhashed(dentry)) - found = dget(dentry); + if (!d_unhashed(dentry)) { + atomic_inc(&dentry->d_count); + dentry->d_vfs_flags |= DCACHE_REFERENCED; + found = dentry; + } spin_unlock(&dentry->d_lock); break; } diff -puN include/linux/dcache.h~dget-BUG include/linux/dcache.h --- 25/include/linux/dcache.h~dget-BUG 2003-02-20 02:09:12.000000000 -0800 +++ 25-akpm/include/linux/dcache.h 2003-02-20 02:09:12.000000000 -0800 @@ -262,6 +262,8 @@ extern char * d_path(struct dentry *, st static __inline__ struct dentry * dget(struct dentry *dentry) { if (dentry) { + if (!atomic_read(&dentry->d_count)) + BUG(); atomic_inc(&dentry->d_count); dentry->d_vfs_flags |= DCACHE_REFERENCED; } _