Skip to content

Commit

Permalink
Add option none to zfs redundant_metadata property
Browse files Browse the repository at this point in the history
Currently, additional/extra copies are created for metadata in
addition to the redundancy provided by the pool(mirror/raidz/draid),
due to this 2 times more space is utilized per inode and this decreases
the total number of inodes that can be created in the filesystem. By
setting redundant_metadata to none, no additional copies of metadata
are created, hence can reduce the space consumed by the additional
metadata copies and increase the total number of inodes that can be
created in the filesystem.

Reviewed-by: Dipak Ghosh <[email protected]>
Signed-off-by: Akash B <[email protected]>
  • Loading branch information
akashb-22 committed Sep 2, 2022
1 parent 2d5622f commit a0055f0
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 6 deletions.
3 changes: 3 additions & 0 deletions include/sys/dsl_prop.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ int dsl_prop_set_string(const char *dsname, const char *propname,
zprop_source_t source, const char *value);
int dsl_prop_inherit(const char *dsname, const char *propname,
zprop_source_t source);
boolean_t dsl_prop_val_understood(zfs_prop_t prop, uint64_t value);
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);

int dsl_prop_predict(dsl_dir_t *dd, const char *propname,
zprop_source_t source, uint64_t value, uint64_t *newvalp);
Expand Down
3 changes: 2 additions & 1 deletion include/sys/fs/zfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,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 {
Expand Down
8 changes: 6 additions & 2 deletions man/man7/zfsprops.7
Original file line number Diff line number Diff line change
Expand Up @@ -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
.
Expand Down Expand Up @@ -1454,7 +1454,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.
Expand Down Expand Up @@ -1495,6 +1495,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
Expand Down
3 changes: 2 additions & 1 deletion module/zcommon/zfs_prop.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
};

Expand All @@ -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,
Expand Down
3 changes: 2 additions & 1 deletion module/zfs/dmu_objset.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
78 changes: 78 additions & 0 deletions module/zfs/dsl_prop.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

#define ZPROP_INHERIT_SUFFIX "$inherit"
#define ZPROP_RECVD_SUFFIX "$recvd"
#define ZPROP_IUV_SUFFIX "$iuv"

static int
dodefault(zfs_prop_t prop, int intsz, int numints, void *buf)
Expand Down Expand Up @@ -81,6 +82,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 +93,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 +108,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_val_understood(zfs_name_to_prop(propname),
*(uint64_t *)buf))
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 +170,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 @@ -659,6 +675,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 +709,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 +727,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 Down Expand Up @@ -763,6 +784,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 @@ -860,6 +882,49 @@ dsl_prop_inherit(const char *dsname, const char *propname,
return (error);
}

boolean_t
dsl_prop_val_understood(zfs_prop_t prop, uint64_t value)
{
const char *str;
if (zfs_prop_get_type(prop) == PROP_TYPE_INDEX) {
if (!zfs_prop_index_to_string(prop, value, &str))
return 1;
else
return 0;
} else {
return 1;
}
}

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);
uint64_t val;
int iuv_flag = 0;
zfs_prop_t prop = zfs_name_to_prop(propname);
switch (prop) {
case ZFS_PROP_REDUNDANT_METADATA:
if (*(uint64_t *)value >= ZFS_REDUNDANT_METADATA_NONE)
iuv_flag = 1;
break;
default:
break;
}

if (iuv_flag) {
VERIFY0(zap_update(mos, zapobj, iuvstr, intsz, numints,
value, tx));
val = zfs_prop_default_numeric(prop);
VERIFY0(zap_update(mos, zapobj, propname, intsz, numints,
&val, tx));
} else if (0 == zap_contains(mos, zapobj, iuvstr)) {
zap_remove(mos, zapobj, iuvstr, tx);
}
kmem_strfree(iuvstr);
}

int
dsl_props_set_check(void *arg, dmu_tx_t *tx)
{
Expand Down Expand Up @@ -1044,6 +1109,15 @@ 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) strncpy(buf, za.za_name, (suffix - za.za_name));
buf[suffix - za.za_name] = '\0';
propname = buf;
source = setpoint;
prop = zfs_name_to_prop(propname);
if (!dsl_prop_val_understood(prop,
za.za_first_integer))
continue;
} else {
/*
* For backward compatibility, skip suffixes we don't
Expand All @@ -1064,6 +1138,10 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
!zfs_prop_valid_for_type(prop, ZFS_TYPE_SNAPSHOT, B_FALSE))
continue;

/* We only want propname$iuv for new property values */
if (suffix && (strcmp(suffix, ZPROP_IUV_SUFFIX) == 0))
nvlist_remove_all(nv, propname);

/* Skip properties already defined. */
if (nvlist_exists(nv, propname))
continue;
Expand Down
2 changes: 1 addition & 1 deletion tests/zfs-tests/include/properties.shlib
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,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' '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

0 comments on commit a0055f0

Please sign in to comment.