Skip to content

Commit 3c4baf6

Browse files
committed
linux/super: add tunable to request immediate reclaim of unused dentries
Traditionally, unused dentries would be cached in the dentry cache until the associated entry is no longer on disk. The cached dentry continues to hold an inode reference, causing the inode to be pinned (see previous commit). Here we implement the dentry op d_delete, which is roughly analogous to the drop_inode superblock op, and add a zfs_delete_dentry tunable to control its behaviour. By default it continues the traditional behaviour, but when the tunable is enabled, we signal that an unused dentry should be freed immediately, releasing its inode reference, and so allowing that inode to be deleted if no longer in use. Sponsored-by: Klara, Inc. Sponsored-by: Fastmail Pty Ltd Signed-off-by: Rob Norris <[email protected]>
1 parent 29bf7dd commit 3c4baf6

File tree

5 files changed

+95
-0
lines changed

5 files changed

+95
-0
lines changed

config/kernel-dentry-operations.m4

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,37 @@ AC_DEFUN([ZFS_AC_KERNEL_D_SET_D_OP], [
4646
])
4747
])
4848

49+
dnl #
50+
dnl # 6.17 API change
51+
dnl # sb->s_d_op removed; set_default_d_op(sb, dop) added
52+
dnl #
53+
AC_DEFUN([ZFS_AC_KERNEL_SRC_SET_DEFAULT_D_OP], [
54+
ZFS_LINUX_TEST_SRC([set_default_d_op], [
55+
#include <linux/dcache.h>
56+
], [
57+
set_default_d_op(NULL, NULL);
58+
])
59+
])
60+
61+
AC_DEFUN([ZFS_AC_KERNEL_SET_DEFAULT_D_OP], [
62+
AC_MSG_CHECKING([whether set_default_d_op() is available])
63+
ZFS_LINUX_TEST_RESULT([set_default_d_op], [
64+
AC_MSG_RESULT(yes)
65+
AC_DEFINE(HAVE_SET_DEFAULT_D_OP, 1,
66+
[Define if set_default_d_op() is available])
67+
], [
68+
AC_MSG_RESULT(no)
69+
])
70+
])
71+
4972
AC_DEFUN([ZFS_AC_KERNEL_SRC_DENTRY], [
5073
ZFS_AC_KERNEL_SRC_D_OBTAIN_ALIAS
5174
ZFS_AC_KERNEL_SRC_D_SET_D_OP
75+
ZFS_AC_KERNEL_SRC_SET_DEFAULT_D_OP
5276
])
5377

5478
AC_DEFUN([ZFS_AC_KERNEL_DENTRY], [
5579
ZFS_AC_KERNEL_D_OBTAIN_ALIAS
5680
ZFS_AC_KERNEL_D_SET_D_OP
81+
ZFS_AC_KERNEL_SET_DEFAULT_D_OP
5782
])

include/os/linux/zfs/sys/zpl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ extern const struct file_operations zpl_dir_file_operations;
5555
extern void zpl_prune_sb(uint64_t nr_to_scan, void *arg);
5656

5757
extern const struct super_operations zpl_super_operations;
58+
extern const struct dentry_operations zpl_dentry_operations;
5859
extern const struct export_operations zpl_export_operations;
5960
extern struct file_system_type zpl_fs_type;
6061

man/man4/zfs.4

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2603,6 +2603,28 @@ frequently evicted and reloaded.
26032603
.Pp
26042604
This parameter is only available on Linux.
26052605
.
2606+
.It Sy zfs_delete_dentry Ns = Ns Sy 0 Ns | Ns 1 Pq int
2607+
.
2608+
Sets whether the kernel should free a dentry structure when it is no longer
2609+
required, or hold it in the dentry cache.
2610+
.
2611+
Since a dentry structure holds an inode reference, a cached dentry can "pin"
2612+
an inode in memory indefinitely, along with associated OpenZFS structures ( See
2613+
.Sy zfs_delete_inode
2614+
.Pp
2615+
The default value of
2616+
.Sy 0
2617+
instructs the kernel to cache entries and their associated inodes when they
2618+
are no longer directly referenced.
2619+
They will be reclaimed as part of the kernel's normal cache management
2620+
processes.
2621+
Setting it to
2622+
.Sy 1
2623+
will instruct the kernel to release directory entries and their inodes as soon
2624+
as they are no longer referenced by the filesystem.
2625+
.
2626+
This parameter is only available on Linux.
2627+
.
26062628
.It Sy zio_taskq_batch_pct Ns = Ns Sy 80 Ns % Pq uint
26072629
Percentage of online CPUs which will run a worker thread for I/O.
26082630
These workers are responsible for I/O work such as compression, encryption,

module/os/linux/zfs/zfs_vfsops.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,6 +1556,12 @@ zfs_domount(struct super_block *sb, zfs_mnt_t *zm, int silent)
15561556
sb->s_xattr = zpl_xattr_handlers;
15571557
sb->s_export_op = &zpl_export_operations;
15581558

1559+
#ifdef HAVE_SET_DEFAULT_D_OP
1560+
set_default_d_op(sb, &zpl_dentry_operations);
1561+
#else
1562+
sb->s_d_op = &zpl_dentry_operations;
1563+
#endif
1564+
15591565
/* Set features for file system. */
15601566
zfs_set_fuid_feature(zfsvfs);
15611567

module/os/linux/zfs/zpl_super.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@
4141
*/
4242
int zfs_delete_inode = 0;
4343

44+
/*
45+
* What to do when the last reference to a dentry is released. If 0, the kernel
46+
* will cache it until the entry (file) is destroyed. If 1, the dentry will be
47+
* marked for cleanup, at which time its inode reference will be released. See
48+
* zpl_dentry_delete().
49+
*/
50+
int zfs_delete_dentry = 0;
51+
4452
static struct inode *
4553
zpl_inode_alloc(struct super_block *sb)
4654
{
@@ -513,6 +521,35 @@ const struct super_operations zpl_super_operations = {
513521
.show_stats = NULL,
514522
};
515523

524+
/*
525+
* ->d_delete() is called when the last reference to a dentry is released. Its
526+
* return value indicates if the dentry should be destroyed immediately, or
527+
* retained in the dentry cache.
528+
*
529+
* By default (zfs_delete_dentry=0) the kernel will always cache unused
530+
* entries. Each dentry holds an inode reference, so cached dentries can hold
531+
* the final inode reference indefinitely, leading to the inode and its related
532+
* data being pinned (see zpl_drop_inode()).
533+
*
534+
* When set to 1, we signal that the dentry should be destroyed immediately and
535+
* never cached. This reduces memory usage, at the cost of higher overheads to
536+
* lookup a file, as the inode and its underlying data (dnode/dbuf) need to be
537+
* reloaded and reinflated.
538+
*
539+
* Note that userspace does not have direct control over dentry references and
540+
* reclaim; rather, this is part of the kernel's caching and reclaim subsystems
541+
* (eg vm.vfs_cache_pressure).
542+
*/
543+
static int
544+
zpl_dentry_delete(const struct dentry *dentry)
545+
{
546+
return (zfs_delete_dentry ? 1 : 0);
547+
}
548+
549+
const struct dentry_operations zpl_dentry_operations = {
550+
.d_delete = zpl_dentry_delete,
551+
};
552+
516553
struct file_system_type zpl_fs_type = {
517554
.owner = THIS_MODULE,
518555
.name = ZFS_DRIVER,
@@ -527,3 +564,7 @@ struct file_system_type zpl_fs_type = {
527564

528565
ZFS_MODULE_PARAM(zfs, zfs_, delete_inode, INT, ZMOD_RW,
529566
"Delete inodes as soon as the last reference is released.");
567+
568+
ZFS_MODULE_PARAM(zfs, zfs_, delete_dentry, INT, ZMOD_RW,
569+
"Delete dentries from dentry cache as soon as the last reference is "
570+
"released.");

0 commit comments

Comments
 (0)