diff --git a/include/sys/dsl_prop.h b/include/sys/dsl_prop.h index 7a84f2b6922a..de64849d63b8 100644 --- a/include/sys/dsl_prop.h +++ b/include/sys/dsl_prop.h @@ -78,6 +78,7 @@ void dsl_prop_unregister_all(struct dsl_dataset *ds, void *cbarg); void dsl_prop_notify_all(struct dsl_dir *dd); boolean_t dsl_prop_hascb(struct dsl_dataset *ds); +void dsl_prop_validate(zfs_prop_t prop, uint64_t *val); int dsl_prop_get(const char *ddname, const char *propname, int intsz, int numints, void *buf, char *setpoint); int dsl_prop_get_integer(const char *ddname, const char *propname, diff --git a/include/sys/fs/zfs.h b/include/sys/fs/zfs.h index 237b503626d3..0d216a28330b 100644 --- a/include/sys/fs/zfs.h +++ b/include/sys/fs/zfs.h @@ -500,7 +500,8 @@ typedef enum { typedef enum { ZFS_REDUNDANT_METADATA_ALL, - ZFS_REDUNDANT_METADATA_MOST + ZFS_REDUNDANT_METADATA_MOST, + ZFS_REDUNDANT_METADATA_NONE } zfs_redundant_metadata_type_t; typedef enum { diff --git a/man/man7/zfsprops.7 b/man/man7/zfsprops.7 index 5a6b9594d9a7..3517ca82ea2f 100644 --- a/man/man7/zfsprops.7 +++ b/man/man7/zfsprops.7 @@ -37,7 +37,7 @@ .\" Copyright 2019 Joyent, Inc. .\" Copyright (c) 2019, Kjeld Schouten-Lebbing .\" -.Dd May 24, 2021 +.Dd July 21, 2022 .Dt ZFSPROPS 7 .Os . @@ -1444,7 +1444,7 @@ affects only files created afterward; existing files are unaffected. .Pp This property can also be referred to by its shortened column name, .Sy recsize . -.It Sy redundant_metadata Ns = Ns Sy all Ns | Ns Sy most +.It Sy redundant_metadata Ns = Ns Sy all Ns | Ns Sy most Ns | Ns Sy none Controls what types of metadata are stored redundantly. ZFS stores an extra copy of metadata, so that if a single block is corrupted, the amount of user data lost is limited. @@ -1485,6 +1485,10 @@ of user data can be lost if a single on-disk block is corrupt. The exact behavior of which metadata blocks are stored redundantly may change in future releases. .Pp +When set to +.Sy none , +ZFS does not store any copies of metadata redundantly through this property. +.Pp The default value is .Sy all . .It Sy refquota Ns = Ns Ar size Ns | Ns Sy none diff --git a/module/zcommon/zfs_prop.c b/module/zcommon/zfs_prop.c index 0b0fc9015fa0..02082e756c08 100644 --- a/module/zcommon/zfs_prop.c +++ b/module/zcommon/zfs_prop.c @@ -369,6 +369,7 @@ zfs_prop_init(void) static const zprop_index_t redundant_metadata_table[] = { { "all", ZFS_REDUNDANT_METADATA_ALL }, { "most", ZFS_REDUNDANT_METADATA_MOST }, + { "none", ZFS_REDUNDANT_METADATA_NONE }, { NULL } }; @@ -388,7 +389,7 @@ zfs_prop_init(void) zprop_register_index(ZFS_PROP_REDUNDANT_METADATA, "redundant_metadata", ZFS_REDUNDANT_METADATA_ALL, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, - "all | most", "REDUND_MD", + "all | most | none", "REDUND_MD", redundant_metadata_table, sfeatures); zprop_register_index(ZFS_PROP_SYNC, "sync", ZFS_SYNC_STANDARD, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, diff --git a/module/zfs/dmu_objset.c b/module/zfs/dmu_objset.c index b9e16f79efc5..46d1754687a8 100644 --- a/module/zfs/dmu_objset.c +++ b/module/zfs/dmu_objset.c @@ -287,7 +287,8 @@ redundant_metadata_changed_cb(void *arg, uint64_t newval) * Inheritance and range checking should have been done by now. */ ASSERT(newval == ZFS_REDUNDANT_METADATA_ALL || - newval == ZFS_REDUNDANT_METADATA_MOST); + newval == ZFS_REDUNDANT_METADATA_MOST || + newval == ZFS_REDUNDANT_METADATA_NONE); os->os_redundant_metadata = newval; } diff --git a/module/zfs/dsl_prop.c b/module/zfs/dsl_prop.c index 1d3d26124949..15729da4d3d4 100644 --- a/module/zfs/dsl_prop.c +++ b/module/zfs/dsl_prop.c @@ -219,6 +219,18 @@ dsl_prop_get_ds(dsl_dataset_t *ds, const char *propname, intsz, numints, buf, setpoint, ds->ds_is_snapshot)); } +void +dsl_prop_validate(zfs_prop_t prop, uint64_t *val) +{ + const char *str; + int err; + if (zfs_prop_get_type(prop) == PROP_TYPE_INDEX) { + err = zfs_prop_index_to_string(prop, *val, &str); + if (err != 0 ) + *val = zfs_prop_default_numeric(prop); + } +} + static dsl_prop_record_t * dsl_prop_record_find(dsl_dir_t *dd, const char *propname) { @@ -292,6 +304,7 @@ dsl_prop_register(dsl_dataset_t *ds, const char *propname, ASSERT(dsl_pool_config_held(dp)); err = dsl_prop_get_int_ds(ds, propname, &value); + (void) dsl_prop_validate(zfs_name_to_prop(propname), &value); if (err != 0) return (err);