From ec9b8ac0808cdcb30c1a34687ad4e9036db60b15 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 28 May 2004 20:58:56 -0700 Subject: [PATCH] [PATCH] fs/dcache.c: avoid race when updating nr_unused count of unused dentries. From: NeilBrown d_count == 1 is no guarantee that dentry is on the dentry_unused list, even if it has just been incremented inside dcache_lock, as dput can decrement at any time. This test from Greg Banks is much safer, and is more transparently correct. Cc: Maneesh Soni , Dipankar Sarma From: Greg Banks Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/dcache.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 5f6e53022ce1c..613ff66dacde2 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -259,7 +259,7 @@ int d_invalidate(struct dentry * dentry) static inline struct dentry * __dget_locked(struct dentry *dentry) { atomic_inc(&dentry->d_count); - if (atomic_read(&dentry->d_count) == 1) { + if (!list_empty(&dentry->d_lru)) { dentry_stat.nr_unused--; list_del_init(&dentry->d_lru); } @@ -935,8 +935,9 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry) * lookup is going on. * * dentry_unused list is not updated even if lookup finds the required dentry - * in there. It is updated in places such as prune_dcache, shrink_dcache_sb and - * select_parent. This laziness saves lookup from dcache_lock acquisition. + * in there. It is updated in places such as prune_dcache, shrink_dcache_sb, + * select_parent and __dget_locked. This laziness saves lookup from dcache_lock + * acquisition. * * d_lookup() is protected against the concurrent renames in some unrelated * directory using the seqlockt_t rename_lock. -- 2.53.0