Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option none to zfs redundant_metadata property #13680

Merged
merged 1 commit into from
Oct 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions include/sys/dmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
* Copyright 2013 Saso Kiselkov. All rights reserved.
* Copyright (c) 2017, Intel Corporation.
* Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
*/

/* Portions Copyright 2010 Robert Milkowski */
Expand Down Expand Up @@ -142,6 +143,12 @@ typedef enum dmu_object_byteswap {
#define DMU_OT_IS_DDT(ot) \
((ot) == DMU_OT_DDT_ZAP)

#define DMU_OT_IS_CRITICAL(ot) \
(DMU_OT_IS_METADATA(ot) && \
(ot) != DMU_OT_DNODE && \
(ot) != DMU_OT_DIRECTORY_CONTENTS && \
(ot) != DMU_OT_SA)

/* Note: ztest uses DMU_OT_UINT64_OTHER as a proxy for file blocks */
#define DMU_OT_IS_FILE(ot) \
((ot) == DMU_OT_PLAIN_FILE_CONTENTS || (ot) == DMU_OT_UINT64_OTHER)
Expand Down
5 changes: 4 additions & 1 deletion include/sys/fs/zfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
* Copyright (c) 2019 Datto Inc.
* Portions Copyright 2010 Robert Milkowski
* Copyright (c) 2021, Colm Buckley <[email protected]>
* Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
*/

#ifndef _SYS_FS_ZFS_H
Expand Down Expand Up @@ -501,7 +502,9 @@ typedef enum {

typedef enum {
ZFS_REDUNDANT_METADATA_ALL,
ZFS_REDUNDANT_METADATA_MOST
ZFS_REDUNDANT_METADATA_MOST,
ZFS_REDUNDANT_METADATA_SOME,
ZFS_REDUNDANT_METADATA_NONE
behlendorf marked this conversation as resolved.
Show resolved Hide resolved
} zfs_redundant_metadata_type_t;

typedef enum {
Expand Down
18 changes: 15 additions & 3 deletions man/man7/zfsprops.7
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@
.\" Copyright 2018 Nexenta Systems, Inc.
.\" Copyright 2019 Joyent, Inc.
.\" Copyright (c) 2019, Kjeld Schouten-Lebbing
.\" Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
.\"
.Dd May 24, 2021
.Dd July 21, 2022
.Dt ZFSPROPS 7
.Os
.
Expand Down Expand Up @@ -1454,7 +1455,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 some 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.
Expand Down Expand Up @@ -1486,7 +1487,7 @@ When set to
ZFS stores an extra copy of most types of metadata.
This can improve performance of random writes, because less metadata must be
written.
In practice, at worst about 100 blocks
In practice, at worst about 1000 blocks
.Po of
.Sy recordsize
bytes each
Expand All @@ -1495,6 +1496,17 @@ 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 some ,
ZFS stores an extra copy of only critical metadata.
This can improve file create performance since less metadata needs to be written.
If a single on-disk block is corrupt, at worst a single user file can be lost.
akashb-22 marked this conversation as resolved.
Show resolved Hide resolved
.Pp
When set to
.Sy none ,
ZFS does not store any copies of metadata redundantly.
If a single on-disk block is corrupt, an entire dataset can be lost.
.Pp
The default value is
.Sy all .
.It Sy refquota Ns = Ns Ar size Ns | Ns Sy none
Expand Down
5 changes: 4 additions & 1 deletion module/zcommon/zfs_prop.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
* Copyright 2016, Joyent, Inc.
* Copyright (c) 2019, Klara Inc.
* Copyright (c) 2019, Allan Jude
* Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
*/

/* Portions Copyright 2010 Robert Milkowski */
Expand Down Expand Up @@ -369,6 +370,8 @@ zfs_prop_init(void)
static const zprop_index_t redundant_metadata_table[] = {
{ "all", ZFS_REDUNDANT_METADATA_ALL },
{ "most", ZFS_REDUNDANT_METADATA_MOST },
{ "some", ZFS_REDUNDANT_METADATA_SOME },
{ "none", ZFS_REDUNDANT_METADATA_NONE },
{ NULL }
};

Expand All @@ -388,7 +391,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 | some | 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,
Expand Down
21 changes: 16 additions & 5 deletions module/zfs/dmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
* Copyright (c) 2019 Datto Inc.
* Copyright (c) 2019, Klara Inc.
* Copyright (c) 2019, Allan Jude
* Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
*/

#include <sys/dmu.h>
Expand Down Expand Up @@ -1992,12 +1993,22 @@ dmu_write_policy(objset_t *os, dnode_t *dn, int level, int wp, zio_prop_t *zp)
ZCHECKSUM_FLAG_EMBEDDED))
checksum = ZIO_CHECKSUM_FLETCHER_4;

if (os->os_redundant_metadata == ZFS_REDUNDANT_METADATA_ALL ||
(os->os_redundant_metadata ==
ZFS_REDUNDANT_METADATA_MOST &&
(level >= zfs_redundant_metadata_most_ditto_level ||
DMU_OT_IS_METADATA(type) || (wp & WP_SPILL))))
switch (os->os_redundant_metadata) {
case ZFS_REDUNDANT_METADATA_ALL:
copies++;
break;
case ZFS_REDUNDANT_METADATA_MOST:
if (level >= zfs_redundant_metadata_most_ditto_level ||
DMU_OT_IS_METADATA(type) || (wp & WP_SPILL))
copies++;
break;
case ZFS_REDUNDANT_METADATA_SOME:
if (DMU_OT_IS_CRITICAL(type))
copies++;
break;
case ZFS_REDUNDANT_METADATA_NONE:
break;
}
} else if (wp & WP_NOFILL) {
ASSERT(level == 0);

Expand Down
5 changes: 4 additions & 1 deletion module/zfs/dmu_objset.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
* Copyright (c) 2018, loli10K <[email protected]>. All rights reserved.
* Copyright (c) 2019, Klara Inc.
* Copyright (c) 2019, Allan Jude
* Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
*/

/* Portions Copyright 2010 Robert Milkowski */
Expand Down Expand Up @@ -287,7 +288,9 @@ 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_SOME ||
newval == ZFS_REDUNDANT_METADATA_NONE);
behlendorf marked this conversation as resolved.
Show resolved Hide resolved

os->os_redundant_metadata = newval;
}
Expand Down
92 changes: 92 additions & 0 deletions module/zfs/dsl_prop.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* Copyright (c) 2012, 2015 by Delphix. All rights reserved.
* Copyright (c) 2013 Martin Matuska. All rights reserved.
* Copyright 2019 Joyent, Inc.
* Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
*/

#include <sys/zfs_context.h>
Expand All @@ -41,6 +42,7 @@

#define ZPROP_INHERIT_SUFFIX "$inherit"
#define ZPROP_RECVD_SUFFIX "$recvd"
#define ZPROP_IUV_SUFFIX "$iuv"
akashb-22 marked this conversation as resolved.
Show resolved Hide resolved

static int
dodefault(zfs_prop_t prop, int intsz, int numints, void *buf)
Expand Down Expand Up @@ -69,6 +71,16 @@ dodefault(zfs_prop_t prop, int intsz, int numints, void *buf)
return (0);
}

static int
dsl_prop_known_index(zfs_prop_t prop, uint64_t value)
{
const char *str = NULL;
if (zfs_prop_get_type(prop) == PROP_TYPE_INDEX)
return (!zfs_prop_index_to_string(prop, value, &str));

return (-1);
akashb-22 marked this conversation as resolved.
Show resolved Hide resolved
}

int
dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
int intsz, int numints, void *buf, char *setpoint, boolean_t snapshot)
Expand All @@ -81,6 +93,7 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
boolean_t inheriting = B_FALSE;
char *inheritstr;
char *recvdstr;
char *iuvstr;

ASSERT(dsl_pool_config_held(dd->dd_pool));

Expand All @@ -91,6 +104,7 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
inheritable = (prop == ZPROP_USERPROP || zfs_prop_inheritable(prop));
inheritstr = kmem_asprintf("%s%s", propname, ZPROP_INHERIT_SUFFIX);
recvdstr = kmem_asprintf("%s%s", propname, ZPROP_RECVD_SUFFIX);
iuvstr = kmem_asprintf("%s%s", propname, ZPROP_IUV_SUFFIX);

/*
* Note: dd may become NULL, therefore we shouldn't dereference it
Expand All @@ -105,6 +119,18 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
inheriting = B_TRUE;
}

/* Check for a iuv value. */
err = zap_lookup(mos, dsl_dir_phys(dd)->dd_props_zapobj,
iuvstr, intsz, numints, buf);
if (dsl_prop_known_index(zfs_name_to_prop(propname),
*(uint64_t *)buf) != 1)
err = ENOENT;
if (err != ENOENT) {
if (setpoint != NULL && err == 0)
dsl_dir_name(dd, setpoint);
break;
}

/* Check for a local value. */
err = zap_lookup(mos, dsl_dir_phys(dd)->dd_props_zapobj,
propname, intsz, numints, buf);
Expand Down Expand Up @@ -155,6 +181,7 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,

kmem_strfree(inheritstr);
kmem_strfree(recvdstr);
kmem_strfree(iuvstr);

return (err);
}
Expand Down Expand Up @@ -647,6 +674,45 @@ dsl_prop_changed_notify(dsl_pool_t *dp, uint64_t ddobj,
dsl_dir_rele(dd, FTAG);
}


/*
* For newer values in zfs index type properties, we add a new key
* propname$iuv (iuv = Ignore Unknown Values) to the properties zap object
* to store the new property value and store the default value in the
* existing prop key. So that the propname$iuv key is ignored by the older zfs
* versions and the default property value from the existing prop key is
* used.
*/
static void
dsl_prop_set_iuv(objset_t *mos, uint64_t zapobj, const char *propname,
int intsz, int numints, const void *value, dmu_tx_t *tx)
{
char *iuvstr = kmem_asprintf("%s%s", propname, ZPROP_IUV_SUFFIX);
boolean_t iuv = B_FALSE;
zfs_prop_t prop = zfs_name_to_prop(propname);

switch (prop) {
case ZFS_PROP_REDUNDANT_METADATA:
if (*(uint64_t *)value == ZFS_REDUNDANT_METADATA_SOME ||
*(uint64_t *)value == ZFS_REDUNDANT_METADATA_NONE)
iuv = B_TRUE;
break;
default:
break;
}

if (iuv) {
VERIFY0(zap_update(mos, zapobj, iuvstr, intsz, numints,
value, tx));
uint64_t val = zfs_prop_default_numeric(prop);
VERIFY0(zap_update(mos, zapobj, propname, intsz, numints,
&val, tx));
} else {
zap_remove(mos, zapobj, iuvstr, tx);
akashb-22 marked this conversation as resolved.
Show resolved Hide resolved
}
kmem_strfree(iuvstr);
}

void
dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
zprop_source_t source, int intsz, int numints, const void *value,
Expand All @@ -659,6 +725,7 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
const char *valstr = NULL;
char *inheritstr;
char *recvdstr;
char *iuvstr;
char *tbuf = NULL;
int err;
uint64_t version = spa_version(ds->ds_dir->dd_pool->dp_spa);
Expand Down Expand Up @@ -692,6 +759,7 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,

inheritstr = kmem_asprintf("%s%s", propname, ZPROP_INHERIT_SUFFIX);
recvdstr = kmem_asprintf("%s%s", propname, ZPROP_RECVD_SUFFIX);
iuvstr = kmem_asprintf("%s%s", propname, ZPROP_IUV_SUFFIX);

switch ((int)source) {
case ZPROP_SRC_NONE:
Expand All @@ -709,11 +777,14 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
/*
* remove propname$inherit
* set propname -> value
* set propname$iuv -> new property value
*/
err = zap_remove(mos, zapobj, inheritstr, tx);
ASSERT(err == 0 || err == ENOENT);
VERIFY0(zap_update(mos, zapobj, propname,
intsz, numints, value, tx));
(void) dsl_prop_set_iuv(mos, zapobj, propname, intsz,
numints, value, tx);
break;
case ZPROP_SRC_INHERITED:
/*
Expand All @@ -723,6 +794,8 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
*/
err = zap_remove(mos, zapobj, propname, tx);
ASSERT(err == 0 || err == ENOENT);
err = zap_remove(mos, zapobj, iuvstr, tx);
ASSERT(err == 0 || err == ENOENT);
if (version >= SPA_VERSION_RECVD_PROPS &&
dsl_prop_get_int_ds(ds, ZPROP_HAS_RECVD, &dummy) == 0) {
dummy = 0;
Expand Down Expand Up @@ -763,6 +836,7 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,

kmem_strfree(inheritstr);
kmem_strfree(recvdstr);
kmem_strfree(iuvstr);

/*
* If we are left with an empty snap zap we can destroy it.
Expand Down Expand Up @@ -1012,6 +1086,14 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,

propname = za.za_name;
source = setpoint;

/* Skip if iuv entries are preset. */
valstr = kmem_asprintf("%s%s", propname,
ZPROP_IUV_SUFFIX);
err = zap_contains(mos, propobj, valstr);
kmem_strfree(valstr);
if (err == 0)
continue;
} else if (strcmp(suffix, ZPROP_INHERIT_SUFFIX) == 0) {
/* Skip explicitly inherited entries. */
continue;
Expand Down Expand Up @@ -1044,6 +1126,16 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,

source = ((flags & DSL_PROP_GET_INHERITING) ?
setpoint : ZPROP_SOURCE_VAL_RECVD);
} else if (strcmp(suffix, ZPROP_IUV_SUFFIX) == 0) {
(void) strlcpy(buf, za.za_name,
MIN(sizeof (buf), suffix - za.za_name + 1));
propname = buf;
source = setpoint;
prop = zfs_name_to_prop(propname);

if (dsl_prop_known_index(prop,
za.za_first_integer) != 1)
continue;
} else {
/*
* For backward compatibility, skip suffixes we don't
Expand Down
3 changes: 2 additions & 1 deletion tests/zfs-tests/include/properties.shlib
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#
# Copyright (c) 2012, 2016, Delphix. All rights reserved.
# Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
#

. $STF_SUITE/include/libtest.shlib
Expand All @@ -27,7 +28,7 @@ typeset -a canmount_prop_vals=('on' 'off' 'noauto')
typeset -a copies_prop_vals=('1' '2' '3')
typeset -a logbias_prop_vals=('latency' 'throughput')
typeset -a primarycache_prop_vals=('all' 'none' 'metadata')
typeset -a redundant_metadata_prop_vals=('all' 'most')
typeset -a redundant_metadata_prop_vals=('all' 'most' 'some' 'none')
typeset -a secondarycache_prop_vals=('all' 'none' 'metadata')
typeset -a snapdir_prop_vals=('hidden' 'visible')
typeset -a sync_prop_vals=('standard' 'always' 'disabled')
Expand Down
Loading