Skip to content

Commit bc7f8a7

Browse files
committed
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" tri-state 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 <[email protected]>
1 parent 95f71c0 commit bc7f8a7

File tree

6 files changed

+61
-1
lines changed

6 files changed

+61
-1
lines changed

include/sys/dmu_objset.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ struct objset {
132132
zfs_logbias_op_t os_logbias;
133133
zfs_cache_type_t os_primary_cache;
134134
zfs_cache_type_t os_secondary_cache;
135+
zfs_prefetch_type_t os_prefetch;
135136
zfs_sync_type_t os_sync;
136137
zfs_redundant_metadata_type_t os_redundant_metadata;
137138
uint64_t os_recordsize;

include/sys/fs/zfs.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ typedef enum {
191191
ZFS_PROP_REDACTED,
192192
ZFS_PROP_REDACT_SNAPS,
193193
ZFS_PROP_SNAPSHOTS_CHANGED,
194+
ZFS_PROP_PREFETCH,
194195
ZFS_NUM_PROPS
195196
} zfs_prop_t;
196197

@@ -543,6 +544,12 @@ typedef enum zfs_key_location {
543544
ZFS_KEYLOCATION_LOCATIONS
544545
} zfs_keylocation_t;
545546

547+
typedef enum {
548+
ZFS_PREFETCH_NONE = 0,
549+
ZFS_PREFETCH_METADATA = 1,
550+
ZFS_PREFETCH_ALL = 2
551+
} zfs_prefetch_type_t;
552+
546553
#define DEFAULT_PBKDF2_ITERATIONS 350000
547554
#define MIN_PBKDF2_ITERATIONS 100000
548555

man/man7/zfsprops.7

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1605,6 +1605,23 @@ If this property is set to
16051605
then only metadata is cached.
16061606
The default value is
16071607
.Sy all .
1608+
.It Sy prefetch Ns = Ns Sy all Ns | Ns Sy none Ns | Ns Sy metadata
1609+
Controls what speculative prefetch does.
1610+
If this property is set to
1611+
.Sy all ,
1612+
then both user data and metadata are prefetched.
1613+
If this property is set to
1614+
.Sy none ,
1615+
then neither user data nor metadata are prefetched.
1616+
If this property is set to
1617+
.Sy metadata ,
1618+
then only metadata are prefetched.
1619+
The default value is
1620+
.Sy all .
1621+
.Pp
1622+
Please note that the module parameter zfs_disable_prefetch=1 can
1623+
be used to totally disable speculative prefetch, bypassing anything
1624+
this property does.
16081625
.It Sy setuid Ns = Ns Sy on Ns | Ns Sy off
16091626
Controls whether the setuid bit is respected for the file system.
16101627
The default value is

module/zcommon/zfs_prop.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,13 @@ zfs_prop_init(void)
345345
{ NULL }
346346
};
347347

348+
static const zprop_index_t prefetch_table[] = {
349+
{ "none", ZFS_PREFETCH_NONE },
350+
{ "metadata", ZFS_PREFETCH_METADATA },
351+
{ "all", ZFS_PREFETCH_ALL },
352+
{ NULL }
353+
};
354+
348355
static const zprop_index_t sync_table[] = {
349356
{ "standard", ZFS_SYNC_STANDARD },
350357
{ "always", ZFS_SYNC_ALWAYS },
@@ -453,6 +460,10 @@ zfs_prop_init(void)
453460
ZFS_CACHE_ALL, PROP_INHERIT,
454461
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME,
455462
"all | none | metadata", "SECONDARYCACHE", cache_table, sfeatures);
463+
zprop_register_index(ZFS_PROP_PREFETCH, "prefetch",
464+
ZFS_PREFETCH_ALL, PROP_INHERIT,
465+
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME,
466+
"none | metadata | all", "PREFETCH", prefetch_table, sfeatures);
456467
zprop_register_index(ZFS_PROP_LOGBIAS, "logbias", ZFS_LOGBIAS_LATENCY,
457468
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
458469
"latency | throughput", "LOGBIAS", logbias_table, sfeatures);

module/zfs/dmu_objset.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,19 @@ secondary_cache_changed_cb(void *arg, uint64_t newval)
263263
os->os_secondary_cache = newval;
264264
}
265265

266+
static void
267+
prefetch_changed_cb(void *arg, uint64_t newval)
268+
{
269+
objset_t *os = arg;
270+
271+
/*
272+
* Inheritance should have been done by now.
273+
*/
274+
ASSERT(newval == ZFS_PREFETCH_ALL || newval == ZFS_PREFETCH_NONE ||
275+
newval == ZFS_PREFETCH_METADATA);
276+
os->os_prefetch = newval;
277+
}
278+
266279
static void
267280
sync_changed_cb(void *arg, uint64_t newval)
268281
{
@@ -562,6 +575,11 @@ dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp,
562575
zfs_prop_to_name(ZFS_PROP_SECONDARYCACHE),
563576
secondary_cache_changed_cb, os);
564577
}
578+
if (err == 0) {
579+
err = dsl_prop_register(ds,
580+
zfs_prop_to_name(ZFS_PROP_PREFETCH),
581+
prefetch_changed_cb, os);
582+
}
565583
if (!ds->ds_is_snapshot) {
566584
if (err == 0) {
567585
err = dsl_prop_register(ds,
@@ -635,6 +653,7 @@ dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp,
635653
os->os_primary_cache = ZFS_CACHE_ALL;
636654
os->os_secondary_cache = ZFS_CACHE_ALL;
637655
os->os_dnodesize = DNODE_MIN_SIZE;
656+
os->os_prefetch = ZFS_PREFETCH_ALL;
638657
}
639658

640659
if (ds == NULL || !ds->ds_is_snapshot)

module/zfs/dmu_zfetch.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,14 @@ dmu_zfetch_prepare(zfetch_t *zf, uint64_t blkid, uint64_t nblks,
329329
{
330330
zstream_t *zs;
331331
spa_t *spa = zf->zf_dnode->dn_objset->os_spa;
332+
zfs_prefetch_type_t os_prefetch = zf->zf_dnode->dn_objset->os_prefetch;
332333

333-
if (zfs_prefetch_disable)
334+
if (zfs_prefetch_disable || os_prefetch == ZFS_PREFETCH_NONE)
334335
return (NULL);
336+
337+
if (os_prefetch == ZFS_PREFETCH_METADATA)
338+
fetch_data = B_FALSE;
339+
335340
/*
336341
* If we haven't yet loaded the indirect vdevs' mappings, we
337342
* can only read from blocks that we carefully ensure are on

0 commit comments

Comments
 (0)