From 0c757530e4a47d4ff299f112a9a9849aa54f4478 Mon Sep 17 00:00:00 2001 From: Gionatan Danti <g.danti@assyoma.it> Date: Sun, 3 Sep 2023 12:17:43 +0200 Subject: [PATCH] add prefetch property ZFS prefetch is currently governed by the zfs_prefetch_disable tunable. However, this is a module-wide settings - if a specific dataset benefits from prefetch, while others have issue with it, an optimal solution does not exists. This commit introduce the "prefetch" property, which enable granular control (at dataset/volume level) for prefetching. This patch does not remove the zfs_prefetch_disable, which reimains a system-wide switch for enable/disable prefetch. However, to avoid duplication, it would be preferable to deprecate and then remove the module tunable. Signed-off-by: Gionatan Danti <g.danti@assyoma.it> --- include/sys/dmu_objset.h | 3 +++ include/sys/fs/zfs.h | 1 + module/zcommon/zfs_prop.c | 4 ++++ module/zfs/dmu_objset.c | 17 +++++++++++++++++ module/zfs/dmu_zfetch.c | 4 +++- 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/include/sys/dmu_objset.h b/include/sys/dmu_objset.h index 9f6e0fdd601b..4878a6bee105 100644 --- a/include/sys/dmu_objset.h +++ b/include/sys/dmu_objset.h @@ -197,6 +197,9 @@ struct objset { dmu_objset_upgrade_cb_t os_upgrade_cb; boolean_t os_upgrade_exit; int os_upgrade_status; + + /* prefetch */ + boolean_t os_prefetch; }; #define DMU_META_OBJSET 0 diff --git a/include/sys/fs/zfs.h b/include/sys/fs/zfs.h index bc940e8a7929..87356f32ba42 100644 --- a/include/sys/fs/zfs.h +++ b/include/sys/fs/zfs.h @@ -191,6 +191,7 @@ typedef enum { ZFS_PROP_REDACTED, ZFS_PROP_REDACT_SNAPS, ZFS_PROP_SNAPSHOTS_CHANGED, + ZFS_PROP_PREFETCH, ZFS_NUM_PROPS } zfs_prop_t; diff --git a/module/zcommon/zfs_prop.c b/module/zcommon/zfs_prop.c index 3db6fd13f4ae..525f18aedc6d 100644 --- a/module/zcommon/zfs_prop.c +++ b/module/zcommon/zfs_prop.c @@ -746,6 +746,10 @@ zfs_prop_init(void) ZFS_TYPE_VOLUME, "<date>", "SNAPSHOTS_CHANGED", B_FALSE, B_TRUE, B_TRUE, NULL, sfeatures); + zprop_register_index(ZFS_PROP_PREFETCH, "prefetch", 1, PROP_INHERIT, + ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME, + "on | off", "PREFETCH", boolean_table, sfeatures); + zfs_mod_list_supported_free(sfeatures); } diff --git a/module/zfs/dmu_objset.c b/module/zfs/dmu_objset.c index d134d4958f7c..f980e709cea3 100644 --- a/module/zfs/dmu_objset.c +++ b/module/zfs/dmu_objset.c @@ -263,6 +263,18 @@ secondary_cache_changed_cb(void *arg, uint64_t newval) os->os_secondary_cache = newval; } +static void +prefetch_changed_cb(void *arg, uint64_t newval) +{ + objset_t *os = arg; + + /* + * Inheritance should have been done by now. + */ + ASSERT(newval == B_TRUE || newval == B_FALSE); + os->os_prefetch = newval; +} + static void sync_changed_cb(void *arg, uint64_t newval) { @@ -562,6 +574,11 @@ dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, zfs_prop_to_name(ZFS_PROP_SECONDARYCACHE), secondary_cache_changed_cb, os); } + if (err == 0) { + err = dsl_prop_register(ds, + zfs_prop_to_name(ZFS_PROP_PREFETCH), + prefetch_changed_cb, os); + } if (!ds->ds_is_snapshot) { if (err == 0) { err = dsl_prop_register(ds, diff --git a/module/zfs/dmu_zfetch.c b/module/zfs/dmu_zfetch.c index d0acaf502066..d82a7e3a3e77 100644 --- a/module/zfs/dmu_zfetch.c +++ b/module/zfs/dmu_zfetch.c @@ -329,9 +329,11 @@ dmu_zfetch_prepare(zfetch_t *zf, uint64_t blkid, uint64_t nblks, { zstream_t *zs; spa_t *spa = zf->zf_dnode->dn_objset->os_spa; + boolean_t os_prefetch = zf->zf_dnode->dn_objset->os_prefetch; - if (zfs_prefetch_disable) + if (zfs_prefetch_disable || !os_prefetch) return (NULL); + /* * If we haven't yet loaded the indirect vdevs' mappings, we * can only read from blocks that we carefully ensure are on