From: Yafang Shao <laoar.shao@gmail.com>
To: torvalds@linux-foundation.org, viro@zeniv.linux.org.uk,
brauner@kernel.org, jack@suse.cz
Cc: linux-fsdevel@vger.kernel.org, Yafang Shao <laoar.shao@gmail.com>
Subject: [PATCH RFC] vfs: Introduce a new open flag to imply dentry deletion on file removal
Date: Thu, 12 Sep 2024 17:15:48 +0800 [thread overview]
Message-ID: <20240912091548.98132-1-laoar.shao@gmail.com> (raw)
Commit 681ce8623567 ("vfs: Delete the associated dentry when deleting a
file") introduced an unconditional deletion of the associated dentry when a
file is removed. However, this led to performance regressions in specific
benchmarks, such as ilebench.sum_operations/s [0], prompting a revert in
commit 4a4be1ad3a6e ("Revert 'vfs: Delete the associated dentry when
deleting a file'").
This patch seeks to reintroduce the concept conditionally, where the
associated dentry is deleted only when the user explicitly opts for it
during file removal.
There are practical use cases for this proactive dentry reclamation.
Besides the Elasticsearch use case mentioned in commit 681ce8623567,
additional examples have surfaced in our production environment. For
instance, in video rendering services that continuously generate temporary
files, upload them to persistent storage servers, and then delete them, a
large number of negative dentries—serving no useful purpose—accumulate.
Users in such cases would benefit from proactively reclaiming these
negative dentries. This patch provides an API allowing users to actively
delete these unnecessary negative dentries.
Link: https://lore.kernel.org/linux-fsdevel/202405291318.4dfbb352-oliver.sang@intel.com [0]
Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
---
fs/dcache.c | 7 ++++++-
fs/open.c | 9 ++++++++-
include/linux/dcache.h | 2 +-
include/linux/sched.h | 2 +-
include/uapi/asm-generic/fcntl.h | 4 ++++
5 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/fs/dcache.c b/fs/dcache.c
index 3d8daaecb6d1..6d744b5e5a6c 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1667,7 +1667,10 @@ static struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
smp_store_release(&dentry->d_name.name, dname); /* ^^^ */
dentry->d_lockref.count = 1;
- dentry->d_flags = 0;
+ if (current->flags & PF_REMOVE_DENTRY)
+ dentry->d_flags = DCACHE_FILE_REMOVE;
+ else
+ dentry->d_flags = 0;
spin_lock_init(&dentry->d_lock);
seqcount_spinlock_init(&dentry->d_seq, &dentry->d_lock);
dentry->d_inode = NULL;
@@ -2394,6 +2397,8 @@ void d_delete(struct dentry * dentry)
* Are we the only user?
*/
if (dentry->d_lockref.count == 1) {
+ if (dentry->d_flags & DCACHE_FILE_REMOVE)
+ __d_drop(dentry);
dentry->d_flags &= ~DCACHE_CANT_MOUNT;
dentry_unlink_inode(dentry);
} else {
diff --git a/fs/open.c b/fs/open.c
index 22adbef7ecc2..3441a004a841 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -1428,7 +1428,14 @@ static long do_sys_openat2(int dfd, const char __user *filename,
long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
{
struct open_how how = build_open_how(flags, mode);
- return do_sys_openat2(dfd, filename, &how);
+ long err;
+
+ if (flags & O_NODENTRY)
+ current->flags |= PF_REMOVE_DENTRY;
+ err = do_sys_openat2(dfd, filename, &how);
+ if (flags & O_NODENTRY)
+ current->flags &= ~PF_REMOVE_DENTRY;
+ return err;
}
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index bff956f7b2b9..82ba79bc0072 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -215,7 +215,7 @@ struct dentry_operations {
#define DCACHE_NOKEY_NAME BIT(25) /* Encrypted name encoded without key */
#define DCACHE_OP_REAL BIT(26)
-
+#define DCACHE_FILE_REMOVE BIT(27) /* remove this dentry when file is removed */
#define DCACHE_PAR_LOOKUP BIT(28) /* being looked up (with parent locked shared) */
#define DCACHE_DENTRY_CURSOR BIT(29)
#define DCACHE_NORCU BIT(30) /* No RCU delay for freeing */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index f8d150343d42..f931a3a882e0 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1649,7 +1649,7 @@ extern struct pid *cad_pid;
#define PF_USED_MATH 0x00002000 /* If unset the fpu must be initialized before use */
#define PF_USER_WORKER 0x00004000 /* Kernel thread cloned from userspace thread */
#define PF_NOFREEZE 0x00008000 /* This thread should not be frozen */
-#define PF__HOLE__00010000 0x00010000
+#define PF_REMOVE_DENTRY 0x00010000 /* Remove the dentry when the file is removed */
#define PF_KSWAPD 0x00020000 /* I am kswapd */
#define PF_MEMALLOC_NOFS 0x00040000 /* All allocations inherit GFP_NOFS. See memalloc_nfs_save() */
#define PF_MEMALLOC_NOIO 0x00080000 /* All allocations inherit GFP_NOIO. See memalloc_noio_save() */
diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
index 80f37a0d40d7..ca5f402d5e7d 100644
--- a/include/uapi/asm-generic/fcntl.h
+++ b/include/uapi/asm-generic/fcntl.h
@@ -89,6 +89,10 @@
#define __O_TMPFILE 020000000
#endif
+#ifndef O_NODENTRY
+#define O_NODENTRY 040000000
+#endif
+
/* a horrid kludge trying to make sure that this will fail on old kernels */
#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
--
2.43.5
next reply other threads:[~2024-09-12 9:16 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-12 9:15 Yafang Shao [this message]
2024-09-12 10:53 ` [PATCH RFC] vfs: Introduce a new open flag to imply dentry deletion on file removal Jan Kara
2024-09-12 11:36 ` Mateusz Guzik
2024-09-15 22:50 ` Matthew Wilcox
2024-09-12 12:04 ` Christian Brauner
2024-09-12 13:32 ` Yafang Shao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240912091548.98132-1-laoar.shao@gmail.com \
--to=laoar.shao@gmail.com \
--cc=brauner@kernel.org \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).