diff mbox series

[13/22] __dentry_kill(): get consistent rules for victim's refcount

Message ID 20231109062056.3181775-13-viro@zeniv.linux.org.uk (mailing list archive)
State New, archived
Headers show
Series [01/22] struct dentry: get rid of randomize_layout idiocy | expand

Commit Message

Al Viro Nov. 9, 2023, 6:20 a.m. UTC
Currently we call it with refcount equal to 1 when called from
dentry_kill(); all other callers have it equal to 0.

Make it always be called with zero refcount; on this step we
just decrement it before the calls in dentry_kill().  That is
safe, since all places that care about the value of refcount
either do that under ->d_lock or hold a reference to dentry
in question.  Either is sufficient to prevent observing a
dentry immediately prior to __dentry_kill() getting called
from dentry_kill().

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/dcache.c | 2 ++
 1 file changed, 2 insertions(+)

Comments

Christian Brauner Nov. 9, 2023, 3:27 p.m. UTC | #1
On Thu, Nov 09, 2023 at 06:20:47AM +0000, Al Viro wrote:
> Currently we call it with refcount equal to 1 when called from
> dentry_kill(); all other callers have it equal to 0.
> 
> Make it always be called with zero refcount; on this step we
> just decrement it before the calls in dentry_kill().  That is
> safe, since all places that care about the value of refcount
> either do that under ->d_lock or hold a reference to dentry

Also worth noting that dentry_kill() is marked with
__releases(dentry->d_lock).

I'm usually pretty liberal with lockdep_assert asserts as well because
it gives nice splats on testing kernels and makes for much faster review
because the assumptions are visible directly in the helper.

> in question.  Either is sufficient to prevent observing a
> dentry immediately prior to __dentry_kill() getting called
> from dentry_kill().
> 
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
> ---

Looks good to me,
Reviewed-by: Christian Brauner <brauner@kernel.org>
diff mbox series

Patch

diff --git a/fs/dcache.c b/fs/dcache.c
index 1f61a5d03d5b..d9466cab4884 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -729,6 +729,7 @@  static struct dentry *dentry_kill(struct dentry *dentry)
 			goto slow_positive;
 		}
 	}
+	dentry->d_lockref.count--;
 	__dentry_kill(dentry);
 	return parent;
 
@@ -741,6 +742,7 @@  static struct dentry *dentry_kill(struct dentry *dentry)
 	if (unlikely(dentry->d_lockref.count != 1)) {
 		dentry->d_lockref.count--;
 	} else if (likely(!retain_dentry(dentry))) {
+		dentry->d_lockref.count--;
 		__dentry_kill(dentry);
 		return parent;
 	} else {