diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2024-02-03 23:53:05 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2024-02-09 23:31:16 -0500 |
commit | 7e4a205fe56b9092f0143dad6aa5fee081139b09 (patch) | |
tree | 494c45bb1a3783b9bebb2ae87ebb879e1b6fc55b | |
parent | 6613476e225e090cc9aad49be7fa504e290dd33d (diff) | |
download | linux-stable-7e4a205fe56b9092f0143dad6aa5fee081139b09.tar.gz linux-stable-7e4a205fe56b9092f0143dad6aa5fee081139b09.tar.bz2 linux-stable-7e4a205fe56b9092f0143dad6aa5fee081139b09.zip |
Revert "get rid of DCACHE_GENOCIDE"
This reverts commit 57851607326a2beef21e67f83f4f53a90df8445a.
Unfortunately, while we only call that thing once, the callback
*can* be called more than once for the same dentry - all it
takes is rename_lock being touched while we are in d_walk().
For now let's revert it.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/dcache.c | 5 | ||||
-rw-r--r-- | include/linux/dcache.h | 1 |
2 files changed, 5 insertions, 1 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index b813528fb147..6ebccba33336 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -3061,7 +3061,10 @@ static enum d_walk_ret d_genocide_kill(void *data, struct dentry *dentry) if (d_unhashed(dentry) || !dentry->d_inode) return D_WALK_SKIP; - dentry->d_lockref.count--; + if (!(dentry->d_flags & DCACHE_GENOCIDE)) { + dentry->d_flags |= DCACHE_GENOCIDE; + dentry->d_lockref.count--; + } } return D_WALK_CONTINUE; } diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 1666c387861f..d07cf2f1bb7d 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -173,6 +173,7 @@ struct dentry_operations { #define DCACHE_DONTCACHE BIT(7) /* Purge from memory on final dput() */ #define DCACHE_CANT_MOUNT BIT(8) +#define DCACHE_GENOCIDE BIT(9) #define DCACHE_SHRINK_LIST BIT(10) #define DCACHE_OP_WEAK_REVALIDATE BIT(11) |