Skip to content

Commit c55a9e3

Browse files
committed
mav feedback
Signed-off-by: Paul Dagnelie <paul.dagnelie@klarasystems.com>
1 parent f086d6d commit c55a9e3

File tree

8 files changed

+124
-87
lines changed

8 files changed

+124
-87
lines changed

cmd/zdb/zdb.c

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5637,37 +5637,21 @@ dump_label(const char *dev)
56375637
if (dump_opt['l'] > 2)
56385638
nvlist_print(stdout, toc);
56395639

5640-
uint32_t conf_size, toc_size, bootenv_size;
5641-
if (nvlist_lookup_uint32(toc, VDEV_TOC_TOC_SIZE,
5642-
&toc_size) != 0) {
5643-
if (!dump_opt['q'])
5644-
(void) printf("failed to read size of "
5645-
"TOC of label %d\n", l);
5646-
error = B_TRUE;
5647-
continue;
5648-
}
5649-
int err;
5650-
if ((err = nvlist_lookup_uint32(toc,
5651-
VDEV_TOC_BOOT_REGION, &bootenv_size)) != 0) {
5652-
if (!dump_opt['q'])
5653-
(void) printf("failed to read size of "
5654-
"bootenv of label %d %s\n", l,
5655-
strerror(err));
5656-
error = B_TRUE;
5657-
continue;
5658-
}
5659-
if (nvlist_lookup_uint32(toc, VDEV_TOC_VDEV_CONFIG,
5660-
&conf_size) != 0) {
5640+
uint32_t conf_size, conf_off;
5641+
if (!vdev_toc_get_secinfo(toc, VDEV_TOC_VDEV_CONFIG,
5642+
&conf_size, &conf_off)) {
56615643
if (!dump_opt['q'])
56625644
(void) printf("failed to read size of "
56635645
"vdev config of label %d\n", l);
56645646
error = B_TRUE;
5647+
fnvlist_free(toc);
56655648
continue;
56665649
}
5650+
fnvlist_free(toc);
56675651
buf = alloca(conf_size);
56685652
buflen = conf_size;
56695653
uint64_t phys_off = label->label_offset +
5670-
VDEV_LARGE_PAD_SIZE + toc_size + bootenv_size;
5654+
VDEV_LARGE_PAD_SIZE + conf_off;
56715655
if (pread64(fd, buf, conf_size, phys_off) !=
56725656
conf_size) {
56735657
if (!dump_opt['q'])

cmd/zhack.c

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,25 +1168,29 @@ zhack_repair_one_label_large(const zhack_repair_op_t op, const int fd,
11681168
}
11691169

11701170
uint32_t bootenv_size, vc_size, sc_size;
1171-
if ((err = nvlist_lookup_uint32(toc, VDEV_TOC_BOOT_REGION,
1172-
&bootenv_size)) || (err = nvlist_lookup_uint32(toc,
1173-
VDEV_TOC_VDEV_CONFIG, &vc_size)) || (err = nvlist_lookup_uint32(toc,
1174-
VDEV_TOC_POOL_CONFIG, &sc_size))) {
1171+
uint32_t bootenv_offset, vc_offset, sc_offset;
1172+
if (!vdev_toc_get_secinfo(toc, VDEV_TOC_BOOT_REGION,
1173+
&bootenv_size, &bootenv_offset) || !vdev_toc_get_secinfo(toc,
1174+
VDEV_TOC_VDEV_CONFIG, &vc_size, &vc_offset) ||
1175+
!vdev_toc_get_secinfo(toc, VDEV_TOC_POOL_CONFIG, &sc_size,
1176+
&sc_offset)) {
1177+
fnvlist_free(toc);
11751178
(void) fprintf(stderr,
11761179
"error: TOC missing core fields %d\n", l);
11771180
goto out;
11781181
}
1182+
fnvlist_free(toc);
11791183
bootenv = malloc(bootenv_size);
11801184
zio_eck_t *bootenv_eck = (zio_eck_t *)(bootenv + bootenv_size) - 1;
11811185
vdev_config = malloc(vc_size);
11821186
zio_eck_t *vc_eck = (zio_eck_t *)(vdev_config + vc_size) - 1;
11831187
spa_config = malloc(sc_size);
11841188
zio_eck_t *sc_eck = (zio_eck_t *)(spa_config + sc_size) - 1;
11851189

1186-
uint64_t offset = label_offset + VDEV_TOC_SIZE;
1190+
uint64_t base_offset = label_offset;
11871191
if (bootenv_size != 0) {
11881192
if ((err = zhack_repair_read(fd, bootenv,
1189-
bootenv_size, offset, l)))
1193+
bootenv_size, base_offset + bootenv_offset, l)))
11901194
goto out;
11911195
if (byteswap) {
11921196
byteswap_uint64_array(&bootenv_eck->zec_cksum,
@@ -1196,15 +1200,15 @@ zhack_repair_one_label_large(const zhack_repair_op_t op, const int fd,
11961200
}
11971201
if ((op & ZHACK_REPAIR_OP_CKSUM) == 0 &&
11981202
zhack_repair_test_cksum(byteswap, bootenv, bootenv_size,
1199-
bootenv_eck, offset, l) != 0) {
1203+
bootenv_eck, base_offset + bootenv_offset, l) != 0) {
12001204
(void) fprintf(stderr, "It would appear checksums are "
12011205
"corrupted. Try zhack repair label -c <device>\n");
12021206
goto out;
12031207
}
12041208
}
12051209

1206-
offset += bootenv_size;
1207-
if ((err = zhack_repair_read(fd, vdev_config, vc_size, offset, l)))
1210+
if ((err = zhack_repair_read(fd, vdev_config, vc_size,
1211+
base_offset + vc_offset, l)))
12081212
goto out;
12091213

12101214
if (byteswap) {
@@ -1214,13 +1218,13 @@ zhack_repair_one_label_large(const zhack_repair_op_t op, const int fd,
12141218
}
12151219
if ((op & ZHACK_REPAIR_OP_CKSUM) == 0 &&
12161220
zhack_repair_test_cksum(byteswap, vdev_config, vc_size,
1217-
vc_eck, offset, l) != 0) {
1221+
vc_eck, base_offset + vc_offset, l) != 0) {
12181222
(void) fprintf(stderr, "It would appear checksums are "
12191223
"corrupted. Try zhack repair label -c <device>\n");
12201224
goto out;
12211225
}
1222-
offset += vc_size;
1223-
if ((err = zhack_repair_read(fd, spa_config, sc_size, offset, l)))
1226+
if ((err = zhack_repair_read(fd, spa_config, sc_size,
1227+
base_offset + sc_offset, l)))
12241228
goto out;
12251229

12261230
if (byteswap) {
@@ -1230,7 +1234,7 @@ zhack_repair_one_label_large(const zhack_repair_op_t op, const int fd,
12301234
}
12311235
if ((op & ZHACK_REPAIR_OP_CKSUM) == 0 &&
12321236
zhack_repair_test_cksum(byteswap, spa_config, sc_size,
1233-
sc_eck, offset, l) != 0) {
1237+
sc_eck, base_offset + sc_offset, l) != 0) {
12341238
(void) fprintf(stderr, "It would appear checksums are "
12351239
"corrupted. Try zhack repair label -c <device>\n");
12361240
goto out;
@@ -1250,11 +1254,8 @@ zhack_repair_one_label_large(const zhack_repair_op_t op, const int fd,
12501254
if (err)
12511255
goto out;
12521256

1253-
const char *cfg_keys[] = { ZPOOL_CONFIG_VERSION,
1254-
ZPOOL_CONFIG_POOL_STATE, ZPOOL_CONFIG_GUID };
1255-
nvlist_t *vdev_tree_cfg = NULL;
12561257
uint64_t ashift;
1257-
err = zhack_repair_get_ashift(cfg, l, cfg, &ashift);
1258+
err = zhack_repair_get_ashift(cfg, l, &ashift);
12581259
if (err)
12591260
return;
12601261

@@ -1278,21 +1279,17 @@ zhack_repair_one_label_large(const zhack_repair_op_t op, const int fd,
12781279
label_offset, labels_repaired);
12791280
}
12801281

1281-
offset = label_offset;
12821282
if (zhack_repair_write_label(l, fd, byteswap, toc_data, toc_eck,
1283-
offset, VDEV_TOC_SIZE))
1283+
base_offset, VDEV_TOC_SIZE))
12841284
labels_repaired[l] |= REPAIR_LABEL_STATUS_CKSUM;
1285-
offset += VDEV_TOC_SIZE;
12861285
if (zhack_repair_write_label(l, fd, byteswap, bootenv, bootenv_eck,
1287-
offset, bootenv_size))
1286+
base_offset + bootenv_offset, bootenv_size))
12881287
labels_repaired[l] |= REPAIR_LABEL_STATUS_CKSUM;
1289-
offset += bootenv_size;
12901288
if (zhack_repair_write_label(l, fd, byteswap, vdev_config, vc_eck,
1291-
offset, vc_size))
1289+
base_offset + vc_offset, vc_size))
12921290
labels_repaired[l] |= REPAIR_LABEL_STATUS_CKSUM;
1293-
offset += vc_size;
12941291
if (zhack_repair_write_label(l, fd, byteswap, spa_config, sc_eck,
1295-
offset, sc_size))
1292+
base_offset + sc_offset, sc_size))
12961293
labels_repaired[l] |= REPAIR_LABEL_STATUS_CKSUM;
12971294

12981295
fsync(fd);

include/sys/vdev_impl.h

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -581,9 +581,10 @@ typedef struct vdev_label {
581581
* config, etc). The sub-nvlist contains relevant information, mostly offset
582582
* and size.
583583
*
584-
* Each sub-section is protected with an embedded checksum. In the event that a
585-
* sub-section is larger than 16MiB, it will be split in 16MiB - sizeof
586-
* (zio_eck_t) chunks, which will each have their own checksum.
584+
* Currently, each sub-section is protected with an embedded checksum. In the
585+
* event that a sub-section is larger than 16MiB, it will be split in
586+
* 16MiB - sizeof (zio_eck_t) chunks, which will each have their own checksum.
587+
* Future sub-sections may have their own checksum mechanisms (or none at all).
587588
*/
588589
#define VDEV_LARGE_PAD_SIZE (1 << 24) // 16MiB
589590
#define VDEV_LARGE_DATA_SIZE ((1 << 27) - VDEV_LARGE_PAD_SIZE)
@@ -594,22 +595,57 @@ typedef struct vdev_label {
594595
#define VDEV_RESERVE_OFFSET (VDEV_LARGE_LABEL_SIZE * 2)
595596
#define VDEV_RESERVE_SIZE (1 << 29) // 512MiB
596597

597-
#define VDEV_TOC_SIZE (1 << 13)
598+
#define VDEV_TOC_SIZE (1 << 15)
599+
600+
/*
601+
* Each section in the label has its entry in the "sections" nvlist. This can
602+
* store any necessary data, but will usually contain at least these two
603+
* fields, representing the size and offset of the section.
604+
*/
605+
#define VDEV_SECTION_SIZE "section_size"
606+
#define VDEV_SECTION_OFFSET "section_offset"
598607

599608
/*
600609
* While the data part of the TOC is always VDEV_TOC_SIZE, the actual write
601610
* gets rounded up to the ashift. We don't know the ashift yet early in import,
602611
* when we need to read this info.
603612
*/
604613
#define VDEV_TOC_TOC_SIZE "toc_size"
605-
/* The size of the section that stores the boot region */
614+
#define VDEV_TOC_SECTIONS "sections"
615+
616+
/* The section that stores the boot region */
606617
#define VDEV_TOC_BOOT_REGION "boot_region"
607-
/* The size of the section that stores the vdev config */
618+
/* The section that stores the vdev config */
608619
#define VDEV_TOC_VDEV_CONFIG "vdev_config"
609-
/* The size of the section that stores the pool config */
620+
/* The section that stores the pool config */
610621
#define VDEV_TOC_POOL_CONFIG "pool_config"
611-
/* The size of the section that stores auxilliary uberblocks */
612-
#define VDEV_TOC_AUX_UBERBLOCK "aux_uberblock"
622+
623+
static inline boolean_t
624+
vdev_toc_get_secinfo(nvlist_t *toc, const char *section, uint32_t *size,
625+
uint32_t *offset)
626+
{
627+
nvlist_t *sections, *secinfo;
628+
if (nvlist_lookup_nvlist(toc, VDEV_TOC_SECTIONS, &sections) != 0)
629+
return (B_FALSE);
630+
if (nvlist_lookup_nvlist(sections, section, &secinfo) != 0)
631+
return (B_FALSE);
632+
if (nvlist_lookup_uint32(secinfo, VDEV_SECTION_SIZE, size) != 0)
633+
return (B_FALSE);
634+
if (nvlist_lookup_uint32(secinfo, VDEV_SECTION_OFFSET, offset) != 0)
635+
return (B_FALSE);
636+
return (B_TRUE);
637+
}
638+
639+
static inline void
640+
vdev_toc_add_secinfo(nvlist_t *sections, const char *section, uint32_t size,
641+
uint32_t offset)
642+
{
643+
nvlist_t *secinfo = fnvlist_alloc();
644+
fnvlist_add_uint32(secinfo, VDEV_SECTION_SIZE, size);
645+
fnvlist_add_uint32(secinfo, VDEV_SECTION_OFFSET, offset);
646+
fnvlist_add_nvlist(sections, section, secinfo);
647+
fnvlist_free(secinfo);
648+
}
613649

614650
/*
615651
* vdev_dirty() flags

lib/libzfs/libzfs.abi

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@
640640
<elf-symbol name='fletcher_4_superscalar_ops' size='128' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
641641
<elf-symbol name='libzfs_config_ops' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
642642
<elf-symbol name='sa_protocol_names' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
643-
<elf-symbol name='spa_feature_table' size='2632' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
643+
<elf-symbol name='spa_feature_table' size='2688' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
644644
<elf-symbol name='zfeature_checks_disable' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
645645
<elf-symbol name='zfs_deleg_perm_tab' size='544' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
646646
<elf-symbol name='zfs_history_event_names' size='328' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -9521,8 +9521,8 @@
95219521
</function-decl>
95229522
</abi-instr>
95239523
<abi-instr address-size='64' path='module/zcommon/zfeature_common.c' language='LANG_C99'>
9524-
<array-type-def dimensions='1' type-id='83f29ca2' size-in-bits='21056' id='fd43354e'>
9525-
<subrange length='47' type-id='7359adad' id='8f8900fe'/>
9524+
<array-type-def dimensions='1' type-id='83f29ca2' size-in-bits='21504' id='bd288d11'>
9525+
<subrange length='48' type-id='7359adad' id='8f6d2a81'/>
95269526
</array-type-def>
95279527
<enum-decl name='zfeature_flags' id='6db816a4'>
95289528
<underlying-type type-id='9cac1fee'/>
@@ -9600,7 +9600,7 @@
96009600
<pointer-type-def type-id='611586a1' size-in-bits='64' id='2e243169'/>
96019601
<qualified-type-def type-id='eaa32e2f' const='yes' id='83be723c'/>
96029602
<pointer-type-def type-id='83be723c' size-in-bits='64' id='7acd98a2'/>
9603-
<var-decl name='spa_feature_table' type-id='fd43354e' mangled-name='spa_feature_table' visibility='default' elf-symbol-id='spa_feature_table'/>
9603+
<var-decl name='spa_feature_table' type-id='bd288d11' mangled-name='spa_feature_table' visibility='default' elf-symbol-id='spa_feature_table'/>
96049604
<var-decl name='zfeature_checks_disable' type-id='c19b74c3' mangled-name='zfeature_checks_disable' visibility='default' elf-symbol-id='zfeature_checks_disable'/>
96059605
<function-decl name='opendir' visibility='default' binding='global' size-in-bits='64'>
96069606
<parameter type-id='80f4b756'/>

module/zfs/vdev_label.c

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -854,15 +854,12 @@ vdev_label_read_config(vdev_t *vd, uint64_t txg)
854854

855855
if (zio_wait(zio[l]) == 0 && nvlist_unpack(
856856
(char *)vp[l], VDEV_TOC_SIZE, &toc, 0) == 0) {
857-
uint32_t bootconf_size;
858-
if (nvlist_lookup_uint32(toc,
859-
VDEV_TOC_BOOT_REGION, &bootconf_size) != 0)
857+
uint32_t off;
858+
if (!vdev_toc_get_secinfo(toc,
859+
VDEV_TOC_VDEV_CONFIG,
860+
&vp_size[l], &off))
860861
continue;
861-
if (nvlist_lookup_uint32(toc,
862-
VDEV_TOC_VDEV_CONFIG, &vp_size[l]) != 0)
863-
continue;
864-
vp_off[l] = VDEV_LARGE_PAD_SIZE + toc_size +
865-
bootconf_size;
862+
vp_off[l] = VDEV_LARGE_PAD_SIZE + off;
866863
fnvlist_free(toc);
867864
}
868865
}
@@ -1323,9 +1320,14 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason)
13231320
NV_ENCODE_XDR, KM_SLEEP));
13241321
fnvlist_free(spa_config);
13251322
fnvlist_add_uint32(toc, VDEV_TOC_TOC_SIZE, writesize);
1326-
fnvlist_add_uint32(toc, VDEV_TOC_BOOT_REGION, 0);
1327-
fnvlist_add_uint32(toc, VDEV_TOC_VDEV_CONFIG, vp_size);
1328-
fnvlist_add_uint32(toc, VDEV_TOC_POOL_CONFIG, sc_buflen);
1323+
1324+
nvlist_t *sections = fnvlist_alloc();
1325+
vdev_toc_add_secinfo(sections, VDEV_TOC_VDEV_CONFIG, vp_size,
1326+
writesize);
1327+
vdev_toc_add_secinfo(sections, VDEV_TOC_POOL_CONFIG, sc_buflen,
1328+
writesize + vp_size);
1329+
fnvlist_add_nvlist(toc, VDEV_TOC_SECTIONS, sections);
1330+
fnvlist_free(sections);
13291331

13301332
if (ub_abd2 == NULL)
13311333
ub_abd2 = abd_alloc_linear(SPA_MAXBLOCKSIZE, B_TRUE);
@@ -1454,18 +1456,22 @@ vdev_label_read_bootenv_impl(zio_t *zio, vdev_t *vd, int flags)
14541456
continue;
14551457
}
14561458
nvlist_t *toc;
1457-
uint32_t bootenv_size;
14581459
if (!nvlist_unpack(abd_to_buf(toc_abds[l]), toc_size,
1459-
&toc, KM_SLEEP) || !nvlist_lookup_uint32(toc,
1460-
VDEV_TOC_BOOT_REGION, &bootenv_size)) {
1460+
&toc, KM_SLEEP)) {
14611461
abd_free(toc_abds[l]);
14621462
continue;
14631463
}
14641464
abd_free(toc_abds[l]);
1465+
uint32_t bootenv_size, bootenv_offset;
1466+
if (!vdev_toc_get_secinfo(toc, VDEV_TOC_BOOT_REGION,
1467+
&bootenv_size, &bootenv_offset)) {
1468+
fnvlist_free(toc);
1469+
continue;
1470+
}
14651471

14661472
vdev_label_read(zio, vd, l, B_FALSE,
14671473
abd_alloc_linear(bootenv_size, B_FALSE),
1468-
VDEV_LARGE_PAD_SIZE + toc_size, bootenv_size,
1474+
VDEV_LARGE_PAD_SIZE + bootenv_offset, bootenv_size,
14691475
vdev_label_read_bootenv_done, zio, flags);
14701476
}
14711477
} else {
@@ -1659,18 +1665,23 @@ vdev_label_write_bootenv(vdev_t *vd, nvlist_t *env)
16591665
continue;
16601666
}
16611667
nvlist_t *toc;
1662-
uint32_t bootenv_size;
1668+
uint32_t bootenv_size, bootenv_offset;
16631669
if (!(error = nvlist_unpack(abd_to_buf(toc_abds[l]),
1664-
toc_size, &toc, KM_SLEEP)) ||
1665-
(error = !nvlist_lookup_uint32(toc,
1666-
VDEV_TOC_BOOT_REGION, &bootenv_size))) {
1670+
toc_size, &toc, KM_SLEEP))) {
16671671
all_writeable = B_FALSE;
16681672
continue;
16691673
}
1674+
if (!vdev_toc_get_secinfo(toc, VDEV_TOC_BOOT_REGION,
1675+
&bootenv_size, &bootenv_offset)) {
1676+
fnvlist_free(toc);
1677+
all_writeable = B_FALSE;
1678+
continue;
1679+
}
1680+
fnvlist_free(toc);
16701681

16711682
if (new_abd_size == bootenv_size) {
16721683
vdev_label_write(zio, vd, l, B_TRUE, abd,
1673-
VDEV_LARGE_PAD_SIZE + toc_size,
1684+
VDEV_LARGE_PAD_SIZE + bootenv_offset,
16741685
new_abd_size, NULL, NULL, flags);
16751686
} else {
16761687
all_writeable = B_FALSE;
@@ -2163,9 +2174,18 @@ vdev_label_sync_large(vdev_t *vd, zio_t *zio, uint64_t *good_writes,
21632174
size_t writesize = P2ROUNDUP(toc_buflen, 1 << vd->vdev_ashift);
21642175
nvlist_t *toc = fnvlist_alloc();
21652176
fnvlist_add_uint32(toc, VDEV_TOC_TOC_SIZE, writesize);
2166-
fnvlist_add_uint32(toc, VDEV_TOC_BOOT_REGION, bootenv_size);
2167-
fnvlist_add_uint32(toc, VDEV_TOC_VDEV_CONFIG, vdev_config_size);
2168-
fnvlist_add_uint32(toc, VDEV_TOC_POOL_CONFIG, pool_config_size);
2177+
2178+
nvlist_t *sections = fnvlist_alloc();
2179+
if (bootenv_size != 0) {
2180+
vdev_toc_add_secinfo(sections, VDEV_TOC_BOOT_REGION,
2181+
bootenv_size, writesize);
2182+
}
2183+
vdev_toc_add_secinfo(sections, VDEV_TOC_VDEV_CONFIG, vdev_config_size,
2184+
writesize + bootenv_size);
2185+
vdev_toc_add_secinfo(sections, VDEV_TOC_POOL_CONFIG, pool_config_size,
2186+
writesize + bootenv_size + vdev_config_size);
2187+
fnvlist_add_nvlist(toc, VDEV_TOC_SECTIONS, sections);
2188+
fnvlist_free(sections);
21692189

21702190
ASSERT3U(fnvlist_size(toc) + sizeof (zio_eck_t), <=, VDEV_TOC_SIZE);
21712191

tests/zfs-tests/tests/functional/large_label/large_label_001_pos.ksh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ log_assert "Verify that new label works for basic pool operation"
4242
log_onexit cleanup
4343

4444
mntpnt="$TESTDIR1"
45-
log_must truncate --size=2T $mntpnt/dsk0
45+
log_must truncate -s 2T $mntpnt/dsk0
4646

4747
DSK="$mntpnt/dsk"
4848

0 commit comments

Comments
 (0)