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 remains a system-wide switch for enable/disable prefetch. However, to avoid duplication, it would be preferable to deprecate and then remove the module tunable. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Ameer Hamza <ahamza@ixsystems.com> Signed-off-by: Gionatan Danti <g.danti@assyoma.it> Co-authored-by: Gionatan Danti <g.danti@assyoma.it> Closes #15237 Closes #15436
This commit is contained in:
parent
e57909265b
commit
07345ac252
|
@ -132,6 +132,7 @@ struct objset {
|
||||||
zfs_logbias_op_t os_logbias;
|
zfs_logbias_op_t os_logbias;
|
||||||
zfs_cache_type_t os_primary_cache;
|
zfs_cache_type_t os_primary_cache;
|
||||||
zfs_cache_type_t os_secondary_cache;
|
zfs_cache_type_t os_secondary_cache;
|
||||||
|
zfs_prefetch_type_t os_prefetch;
|
||||||
zfs_sync_type_t os_sync;
|
zfs_sync_type_t os_sync;
|
||||||
zfs_redundant_metadata_type_t os_redundant_metadata;
|
zfs_redundant_metadata_type_t os_redundant_metadata;
|
||||||
uint64_t os_recordsize;
|
uint64_t os_recordsize;
|
||||||
|
|
|
@ -191,6 +191,7 @@ typedef enum {
|
||||||
ZFS_PROP_REDACTED,
|
ZFS_PROP_REDACTED,
|
||||||
ZFS_PROP_REDACT_SNAPS,
|
ZFS_PROP_REDACT_SNAPS,
|
||||||
ZFS_PROP_SNAPSHOTS_CHANGED,
|
ZFS_PROP_SNAPSHOTS_CHANGED,
|
||||||
|
ZFS_PROP_PREFETCH,
|
||||||
ZFS_NUM_PROPS
|
ZFS_NUM_PROPS
|
||||||
} zfs_prop_t;
|
} zfs_prop_t;
|
||||||
|
|
||||||
|
@ -543,6 +544,12 @@ typedef enum zfs_key_location {
|
||||||
ZFS_KEYLOCATION_LOCATIONS
|
ZFS_KEYLOCATION_LOCATIONS
|
||||||
} zfs_keylocation_t;
|
} zfs_keylocation_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ZFS_PREFETCH_NONE = 0,
|
||||||
|
ZFS_PREFETCH_METADATA = 1,
|
||||||
|
ZFS_PREFETCH_ALL = 2
|
||||||
|
} zfs_prefetch_type_t;
|
||||||
|
|
||||||
#define DEFAULT_PBKDF2_ITERATIONS 350000
|
#define DEFAULT_PBKDF2_ITERATIONS 350000
|
||||||
#define MIN_PBKDF2_ITERATIONS 100000
|
#define MIN_PBKDF2_ITERATIONS 100000
|
||||||
|
|
||||||
|
|
|
@ -1867,7 +1867,8 @@
|
||||||
<enumerator name='ZFS_PROP_REDACTED' value='93'/>
|
<enumerator name='ZFS_PROP_REDACTED' value='93'/>
|
||||||
<enumerator name='ZFS_PROP_REDACT_SNAPS' value='94'/>
|
<enumerator name='ZFS_PROP_REDACT_SNAPS' value='94'/>
|
||||||
<enumerator name='ZFS_PROP_SNAPSHOTS_CHANGED' value='95'/>
|
<enumerator name='ZFS_PROP_SNAPSHOTS_CHANGED' value='95'/>
|
||||||
<enumerator name='ZFS_NUM_PROPS' value='96'/>
|
<enumerator name='ZFS_PROP_PREFETCH' value='96'/>
|
||||||
|
<enumerator name='ZFS_NUM_PROPS' value='97'/>
|
||||||
</enum-decl>
|
</enum-decl>
|
||||||
<typedef-decl name='zfs_prop_t' type-id='4b000d60' id='58603c44'/>
|
<typedef-decl name='zfs_prop_t' type-id='4b000d60' id='58603c44'/>
|
||||||
<enum-decl name='zprop_source_t' naming-typedef-id='a2256d42' id='5903f80e'>
|
<enum-decl name='zprop_source_t' naming-typedef-id='a2256d42' id='5903f80e'>
|
||||||
|
|
|
@ -1613,6 +1613,23 @@ If this property is set to
|
||||||
then only metadata is cached.
|
then only metadata is cached.
|
||||||
The default value is
|
The default value is
|
||||||
.Sy all .
|
.Sy all .
|
||||||
|
.It Sy prefetch Ns = Ns Sy all Ns | Ns Sy none Ns | Ns Sy metadata
|
||||||
|
Controls what speculative prefetch does.
|
||||||
|
If this property is set to
|
||||||
|
.Sy all ,
|
||||||
|
then both user data and metadata are prefetched.
|
||||||
|
If this property is set to
|
||||||
|
.Sy none ,
|
||||||
|
then neither user data nor metadata are prefetched.
|
||||||
|
If this property is set to
|
||||||
|
.Sy metadata ,
|
||||||
|
then only metadata are prefetched.
|
||||||
|
The default value is
|
||||||
|
.Sy all .
|
||||||
|
.Pp
|
||||||
|
Please note that the module parameter zfs_disable_prefetch=1 can
|
||||||
|
be used to totally disable speculative prefetch, bypassing anything
|
||||||
|
this property does.
|
||||||
.It Sy setuid Ns = Ns Sy on Ns | Ns Sy off
|
.It Sy setuid Ns = Ns Sy on Ns | Ns Sy off
|
||||||
Controls whether the setuid bit is respected for the file system.
|
Controls whether the setuid bit is respected for the file system.
|
||||||
The default value is
|
The default value is
|
||||||
|
|
|
@ -345,6 +345,13 @@ zfs_prop_init(void)
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const zprop_index_t prefetch_table[] = {
|
||||||
|
{ "none", ZFS_PREFETCH_NONE },
|
||||||
|
{ "metadata", ZFS_PREFETCH_METADATA },
|
||||||
|
{ "all", ZFS_PREFETCH_ALL },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
static const zprop_index_t sync_table[] = {
|
static const zprop_index_t sync_table[] = {
|
||||||
{ "standard", ZFS_SYNC_STANDARD },
|
{ "standard", ZFS_SYNC_STANDARD },
|
||||||
{ "always", ZFS_SYNC_ALWAYS },
|
{ "always", ZFS_SYNC_ALWAYS },
|
||||||
|
@ -453,6 +460,10 @@ zfs_prop_init(void)
|
||||||
ZFS_CACHE_ALL, PROP_INHERIT,
|
ZFS_CACHE_ALL, PROP_INHERIT,
|
||||||
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME,
|
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME,
|
||||||
"all | none | metadata", "SECONDARYCACHE", cache_table, sfeatures);
|
"all | none | metadata", "SECONDARYCACHE", cache_table, sfeatures);
|
||||||
|
zprop_register_index(ZFS_PROP_PREFETCH, "prefetch",
|
||||||
|
ZFS_PREFETCH_ALL, PROP_INHERIT,
|
||||||
|
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME,
|
||||||
|
"none | metadata | all", "PREFETCH", prefetch_table, sfeatures);
|
||||||
zprop_register_index(ZFS_PROP_LOGBIAS, "logbias", ZFS_LOGBIAS_LATENCY,
|
zprop_register_index(ZFS_PROP_LOGBIAS, "logbias", ZFS_LOGBIAS_LATENCY,
|
||||||
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
|
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
|
||||||
"latency | throughput", "LOGBIAS", logbias_table, sfeatures);
|
"latency | throughput", "LOGBIAS", logbias_table, sfeatures);
|
||||||
|
|
|
@ -263,6 +263,19 @@ secondary_cache_changed_cb(void *arg, uint64_t newval)
|
||||||
os->os_secondary_cache = 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 == ZFS_PREFETCH_ALL || newval == ZFS_PREFETCH_NONE ||
|
||||||
|
newval == ZFS_PREFETCH_METADATA);
|
||||||
|
os->os_prefetch = newval;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sync_changed_cb(void *arg, uint64_t newval)
|
sync_changed_cb(void *arg, uint64_t newval)
|
||||||
{
|
{
|
||||||
|
@ -562,6 +575,11 @@ dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp,
|
||||||
zfs_prop_to_name(ZFS_PROP_SECONDARYCACHE),
|
zfs_prop_to_name(ZFS_PROP_SECONDARYCACHE),
|
||||||
secondary_cache_changed_cb, os);
|
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 (!ds->ds_is_snapshot) {
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
err = dsl_prop_register(ds,
|
err = dsl_prop_register(ds,
|
||||||
|
@ -635,6 +653,7 @@ dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp,
|
||||||
os->os_primary_cache = ZFS_CACHE_ALL;
|
os->os_primary_cache = ZFS_CACHE_ALL;
|
||||||
os->os_secondary_cache = ZFS_CACHE_ALL;
|
os->os_secondary_cache = ZFS_CACHE_ALL;
|
||||||
os->os_dnodesize = DNODE_MIN_SIZE;
|
os->os_dnodesize = DNODE_MIN_SIZE;
|
||||||
|
os->os_prefetch = ZFS_PREFETCH_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ds == NULL || !ds->ds_is_snapshot)
|
if (ds == NULL || !ds->ds_is_snapshot)
|
||||||
|
|
|
@ -329,9 +329,14 @@ dmu_zfetch_prepare(zfetch_t *zf, uint64_t blkid, uint64_t nblks,
|
||||||
{
|
{
|
||||||
zstream_t *zs;
|
zstream_t *zs;
|
||||||
spa_t *spa = zf->zf_dnode->dn_objset->os_spa;
|
spa_t *spa = zf->zf_dnode->dn_objset->os_spa;
|
||||||
|
zfs_prefetch_type_t os_prefetch = zf->zf_dnode->dn_objset->os_prefetch;
|
||||||
|
|
||||||
if (zfs_prefetch_disable)
|
if (zfs_prefetch_disable || os_prefetch == ZFS_PREFETCH_NONE)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
|
if (os_prefetch == ZFS_PREFETCH_METADATA)
|
||||||
|
fetch_data = B_FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we haven't yet loaded the indirect vdevs' mappings, we
|
* If we haven't yet loaded the indirect vdevs' mappings, we
|
||||||
* can only read from blocks that we carefully ensure are on
|
* can only read from blocks that we carefully ensure are on
|
||||||
|
|
Loading…
Reference in New Issue