Skip to content

Commit a0055f0

Browse files
committed
Add option none to zfs redundant_metadata property
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]>
1 parent 2d5622f commit a0055f0

File tree

7 files changed

+94
-6
lines changed

7 files changed

+94
-6
lines changed

include/sys/dsl_prop.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ int dsl_prop_set_string(const char *dsname, const char *propname,
106106
zprop_source_t source, const char *value);
107107
int dsl_prop_inherit(const char *dsname, const char *propname,
108108
zprop_source_t source);
109+
boolean_t dsl_prop_val_understood(zfs_prop_t prop, uint64_t value);
110+
void dsl_prop_set_iuv(objset_t *mos, uint64_t zapobj, const char *propname,
111+
int intsz, int numints, const void *value, dmu_tx_t *tx);
109112

110113
int dsl_prop_predict(dsl_dir_t *dd, const char *propname,
111114
zprop_source_t source, uint64_t value, uint64_t *newvalp);

include/sys/fs/zfs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,8 @@ typedef enum {
501501

502502
typedef enum {
503503
ZFS_REDUNDANT_METADATA_ALL,
504-
ZFS_REDUNDANT_METADATA_MOST
504+
ZFS_REDUNDANT_METADATA_MOST,
505+
ZFS_REDUNDANT_METADATA_NONE
505506
} zfs_redundant_metadata_type_t;
506507

507508
typedef enum {

man/man7/zfsprops.7

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
.\" Copyright 2019 Joyent, Inc.
3838
.\" Copyright (c) 2019, Kjeld Schouten-Lebbing
3939
.\"
40-
.Dd May 24, 2021
40+
.Dd July 21, 2022
4141
.Dt ZFSPROPS 7
4242
.Os
4343
.
@@ -1454,7 +1454,7 @@ affects only files created afterward; existing files are unaffected.
14541454
.Pp
14551455
This property can also be referred to by its shortened column name,
14561456
.Sy recsize .
1457-
.It Sy redundant_metadata Ns = Ns Sy all Ns | Ns Sy most
1457+
.It Sy redundant_metadata Ns = Ns Sy all Ns | Ns Sy most Ns | Ns Sy none
14581458
Controls what types of metadata are stored redundantly.
14591459
ZFS stores an extra copy of metadata, so that if a single block is corrupted,
14601460
the amount of user data lost is limited.
@@ -1495,6 +1495,10 @@ of user data can be lost if a single on-disk block is corrupt.
14951495
The exact behavior of which metadata blocks are stored redundantly may change in
14961496
future releases.
14971497
.Pp
1498+
When set to
1499+
.Sy none ,
1500+
ZFS does not store any copies of metadata redundantly through this property.
1501+
.Pp
14981502
The default value is
14991503
.Sy all .
15001504
.It Sy refquota Ns = Ns Ar size Ns | Ns Sy none

module/zcommon/zfs_prop.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ zfs_prop_init(void)
369369
static const zprop_index_t redundant_metadata_table[] = {
370370
{ "all", ZFS_REDUNDANT_METADATA_ALL },
371371
{ "most", ZFS_REDUNDANT_METADATA_MOST },
372+
{ "none", ZFS_REDUNDANT_METADATA_NONE },
372373
{ NULL }
373374
};
374375

@@ -388,7 +389,7 @@ zfs_prop_init(void)
388389
zprop_register_index(ZFS_PROP_REDUNDANT_METADATA, "redundant_metadata",
389390
ZFS_REDUNDANT_METADATA_ALL,
390391
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
391-
"all | most", "REDUND_MD",
392+
"all | most | none", "REDUND_MD",
392393
redundant_metadata_table, sfeatures);
393394
zprop_register_index(ZFS_PROP_SYNC, "sync", ZFS_SYNC_STANDARD,
394395
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,

module/zfs/dmu_objset.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,8 @@ redundant_metadata_changed_cb(void *arg, uint64_t newval)
287287
* Inheritance and range checking should have been done by now.
288288
*/
289289
ASSERT(newval == ZFS_REDUNDANT_METADATA_ALL ||
290-
newval == ZFS_REDUNDANT_METADATA_MOST);
290+
newval == ZFS_REDUNDANT_METADATA_MOST ||
291+
newval == ZFS_REDUNDANT_METADATA_NONE);
291292

292293
os->os_redundant_metadata = newval;
293294
}

module/zfs/dsl_prop.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
#define ZPROP_INHERIT_SUFFIX "$inherit"
4343
#define ZPROP_RECVD_SUFFIX "$recvd"
44+
#define ZPROP_IUV_SUFFIX "$iuv"
4445

4546
static int
4647
dodefault(zfs_prop_t prop, int intsz, int numints, void *buf)
@@ -81,6 +82,7 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
8182
boolean_t inheriting = B_FALSE;
8283
char *inheritstr;
8384
char *recvdstr;
85+
char *iuvstr;
8486

8587
ASSERT(dsl_pool_config_held(dd->dd_pool));
8688

@@ -91,6 +93,7 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
9193
inheritable = (prop == ZPROP_USERPROP || zfs_prop_inheritable(prop));
9294
inheritstr = kmem_asprintf("%s%s", propname, ZPROP_INHERIT_SUFFIX);
9395
recvdstr = kmem_asprintf("%s%s", propname, ZPROP_RECVD_SUFFIX);
96+
iuvstr = kmem_asprintf("%s%s", propname, ZPROP_IUV_SUFFIX);
9497

9598
/*
9699
* Note: dd may become NULL, therefore we shouldn't dereference it
@@ -105,6 +108,18 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
105108
inheriting = B_TRUE;
106109
}
107110

111+
/* Check for a IUV value. */
112+
err = zap_lookup(mos, dsl_dir_phys(dd)->dd_props_zapobj,
113+
iuvstr, intsz, numints, buf);
114+
if (!dsl_prop_val_understood(zfs_name_to_prop(propname),
115+
*(uint64_t *)buf))
116+
err = ENOENT;
117+
if (err != ENOENT) {
118+
if (setpoint != NULL && err == 0)
119+
dsl_dir_name(dd, setpoint);
120+
break;
121+
}
122+
108123
/* Check for a local value. */
109124
err = zap_lookup(mos, dsl_dir_phys(dd)->dd_props_zapobj,
110125
propname, intsz, numints, buf);
@@ -155,6 +170,7 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
155170

156171
kmem_strfree(inheritstr);
157172
kmem_strfree(recvdstr);
173+
kmem_strfree(iuvstr);
158174

159175
return (err);
160176
}
@@ -659,6 +675,7 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
659675
const char *valstr = NULL;
660676
char *inheritstr;
661677
char *recvdstr;
678+
char *iuvstr;
662679
char *tbuf = NULL;
663680
int err;
664681
uint64_t version = spa_version(ds->ds_dir->dd_pool->dp_spa);
@@ -692,6 +709,7 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
692709

693710
inheritstr = kmem_asprintf("%s%s", propname, ZPROP_INHERIT_SUFFIX);
694711
recvdstr = kmem_asprintf("%s%s", propname, ZPROP_RECVD_SUFFIX);
712+
iuvstr = kmem_asprintf("%s%s", propname, ZPROP_IUV_SUFFIX);
695713

696714
switch ((int)source) {
697715
case ZPROP_SRC_NONE:
@@ -709,11 +727,14 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
709727
/*
710728
* remove propname$inherit
711729
* set propname -> value
730+
* set propname$iuv -> new property value
712731
*/
713732
err = zap_remove(mos, zapobj, inheritstr, tx);
714733
ASSERT(err == 0 || err == ENOENT);
715734
VERIFY0(zap_update(mos, zapobj, propname,
716735
intsz, numints, value, tx));
736+
(void) dsl_prop_set_iuv(mos, zapobj, propname, intsz,
737+
numints, value, tx);
717738
break;
718739
case ZPROP_SRC_INHERITED:
719740
/*
@@ -763,6 +784,7 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
763784

764785
kmem_strfree(inheritstr);
765786
kmem_strfree(recvdstr);
787+
kmem_strfree(iuvstr);
766788

767789
/*
768790
* If we are left with an empty snap zap we can destroy it.
@@ -860,6 +882,49 @@ dsl_prop_inherit(const char *dsname, const char *propname,
860882
return (error);
861883
}
862884

885+
boolean_t
886+
dsl_prop_val_understood(zfs_prop_t prop, uint64_t value)
887+
{
888+
const char *str;
889+
if (zfs_prop_get_type(prop) == PROP_TYPE_INDEX) {
890+
if (!zfs_prop_index_to_string(prop, value, &str))
891+
return 1;
892+
else
893+
return 0;
894+
} else {
895+
return 1;
896+
}
897+
}
898+
899+
void
900+
dsl_prop_set_iuv(objset_t *mos, uint64_t zapobj, const char *propname,
901+
int intsz, int numints, const void *value, dmu_tx_t *tx)
902+
{
903+
char *iuvstr = kmem_asprintf("%s%s", propname, ZPROP_IUV_SUFFIX);
904+
uint64_t val;
905+
int iuv_flag = 0;
906+
zfs_prop_t prop = zfs_name_to_prop(propname);
907+
switch (prop) {
908+
case ZFS_PROP_REDUNDANT_METADATA:
909+
if (*(uint64_t *)value >= ZFS_REDUNDANT_METADATA_NONE)
910+
iuv_flag = 1;
911+
break;
912+
default:
913+
break;
914+
}
915+
916+
if (iuv_flag) {
917+
VERIFY0(zap_update(mos, zapobj, iuvstr, intsz, numints,
918+
value, tx));
919+
val = zfs_prop_default_numeric(prop);
920+
VERIFY0(zap_update(mos, zapobj, propname, intsz, numints,
921+
&val, tx));
922+
} else if (0 == zap_contains(mos, zapobj, iuvstr)) {
923+
zap_remove(mos, zapobj, iuvstr, tx);
924+
}
925+
kmem_strfree(iuvstr);
926+
}
927+
863928
int
864929
dsl_props_set_check(void *arg, dmu_tx_t *tx)
865930
{
@@ -1044,6 +1109,15 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
10441109

10451110
source = ((flags & DSL_PROP_GET_INHERITING) ?
10461111
setpoint : ZPROP_SOURCE_VAL_RECVD);
1112+
} else if (strcmp(suffix, ZPROP_IUV_SUFFIX) == 0) {
1113+
(void) strncpy(buf, za.za_name, (suffix - za.za_name));
1114+
buf[suffix - za.za_name] = '\0';
1115+
propname = buf;
1116+
source = setpoint;
1117+
prop = zfs_name_to_prop(propname);
1118+
if (!dsl_prop_val_understood(prop,
1119+
za.za_first_integer))
1120+
continue;
10471121
} else {
10481122
/*
10491123
* For backward compatibility, skip suffixes we don't
@@ -1064,6 +1138,10 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
10641138
!zfs_prop_valid_for_type(prop, ZFS_TYPE_SNAPSHOT, B_FALSE))
10651139
continue;
10661140

1141+
/* We only want propname$iuv for new property values */
1142+
if (suffix && (strcmp(suffix, ZPROP_IUV_SUFFIX) == 0))
1143+
nvlist_remove_all(nv, propname);
1144+
10671145
/* Skip properties already defined. */
10681146
if (nvlist_exists(nv, propname))
10691147
continue;

tests/zfs-tests/include/properties.shlib

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ typeset -a canmount_prop_vals=('on' 'off' 'noauto')
2727
typeset -a copies_prop_vals=('1' '2' '3')
2828
typeset -a logbias_prop_vals=('latency' 'throughput')
2929
typeset -a primarycache_prop_vals=('all' 'none' 'metadata')
30-
typeset -a redundant_metadata_prop_vals=('all' 'most')
30+
typeset -a redundant_metadata_prop_vals=('all' 'most' 'none')
3131
typeset -a secondarycache_prop_vals=('all' 'none' 'metadata')
3232
typeset -a snapdir_prop_vals=('hidden' 'visible')
3333
typeset -a sync_prop_vals=('standard' 'always' 'disabled')

0 commit comments

Comments
 (0)