Skip to content

Commit bd5cce2

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. Signed-off-by: Rob Norris <[email protected]> Sponsored-by: Klara, Inc. Sponsored-by: Fastmail Pty Ltd
1 parent 15cc15e commit bd5cce2

File tree

4 files changed

+65
-0
lines changed

4 files changed

+65
-0
lines changed

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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1553,6 +1553,7 @@ zfs_domount(struct super_block *sb, zfs_mnt_t *zm, int silent)
15531553

15541554
/* Set callback operations for the file system. */
15551555
sb->s_op = &zpl_super_operations;
1556+
sb->s_d_op = &zpl_dentry_operations;
15561557
sb->s_xattr = zpl_xattr_handlers;
15571558
sb->s_export_op = &zpl_export_operations;
15581559

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)