Skip to content

Commit 6718ba5

Browse files
author
Paul Dagnelie
committed
mav feedback
Signed-off-by: Paul Dagnelie <[email protected]>
1 parent b19be06 commit 6718ba5

File tree

8 files changed

+123
-83
lines changed

8 files changed

+123
-83
lines changed

cmd/zdb/zdb.c

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

5596-
uint32_t conf_size, toc_size, bootenv_size;
5597-
if (nvlist_lookup_uint32(toc, VDEV_TOC_TOC_SIZE,
5598-
&toc_size) != 0) {
5599-
if (!dump_opt['q'])
5600-
(void) printf("failed to read size of "
5601-
"TOC of label %d\n", l);
5602-
error = B_TRUE;
5603-
continue;
5604-
}
5605-
int err;
5606-
if ((err = nvlist_lookup_uint32(toc,
5607-
VDEV_TOC_BOOT_REGION, &bootenv_size)) != 0) {
5608-
if (!dump_opt['q'])
5609-
(void) printf("failed to read size of "
5610-
"bootenv of label %d %s\n", l,
5611-
strerror(err));
5612-
error = B_TRUE;
5613-
continue;
5614-
}
5615-
if (nvlist_lookup_uint32(toc, VDEV_TOC_VDEV_CONFIG,
5616-
&conf_size) != 0) {
5596+
uint32_t conf_size, conf_off;
5597+
if (!vdev_toc_get_secinfo(toc, VDEV_TOC_VDEV_CONFIG,
5598+
&conf_size, &conf_off)) {
56175599
if (!dump_opt['q'])
56185600
(void) printf("failed to read size of "
56195601
"vdev config of label %d\n", l);
56205602
error = B_TRUE;
5603+
fnvlist_free(toc);
56215604
continue;
56225605
}
5606+
fnvlist_free(toc);
56235607
buf = alloca(conf_size);
56245608
buflen = conf_size;
56255609
uint64_t phys_off = label->label_offset +
5626-
VDEV_LARGE_PAD_SIZE + toc_size + bootenv_size;
5610+
VDEV_LARGE_PAD_SIZE + conf_off;
56275611
if (pread64(fd, buf, conf_size, phys_off) !=
56285612
conf_size) {
56295613
if (!dump_opt['q'])

cmd/zhack.c

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,25 +1145,29 @@ zhack_repair_one_label_large(const zhack_repair_op_t op, const int fd,
11451145
}
11461146

11471147
uint32_t bootenv_size, vc_size, sc_size;
1148-
if ((err = nvlist_lookup_uint32(toc, VDEV_TOC_BOOT_REGION,
1149-
&bootenv_size)) || (err = nvlist_lookup_uint32(toc,
1150-
VDEV_TOC_VDEV_CONFIG, &vc_size)) || (err = nvlist_lookup_uint32(toc,
1151-
VDEV_TOC_POOL_CONFIG, &sc_size))) {
1148+
uint32_t bootenv_offset, vc_offset, sc_offset;
1149+
if (!vdev_toc_get_secinfo(toc, VDEV_TOC_BOOT_REGION,
1150+
&bootenv_size, &bootenv_offset) || !vdev_toc_get_secinfo(toc,
1151+
VDEV_TOC_VDEV_CONFIG, &vc_size, &vc_offset) ||
1152+
!vdev_toc_get_secinfo(toc, VDEV_TOC_POOL_CONFIG, &sc_size,
1153+
&sc_offset)) {
1154+
fnvlist_free(toc);
11521155
(void) fprintf(stderr,
11531156
"error: TOC missing core fields %d\n", l);
11541157
goto out;
11551158
}
1159+
fnvlist_free(toc);
11561160
bootenv = malloc(bootenv_size);
11571161
zio_eck_t *bootenv_eck = (zio_eck_t *)(bootenv + bootenv_size) - 1;
11581162
vdev_config = malloc(vc_size);
11591163
zio_eck_t *vc_eck = (zio_eck_t *)(vdev_config + vc_size) - 1;
11601164
spa_config = malloc(sc_size);
11611165
zio_eck_t *sc_eck = (zio_eck_t *)(spa_config + sc_size) - 1;
11621166

1163-
uint64_t offset = label_offset + VDEV_TOC_SIZE;
1167+
uint64_t base_offset = label_offset;
11641168
if (bootenv_size != 0) {
11651169
if ((err = zhack_repair_read(fd, bootenv,
1166-
bootenv_size, offset, l)))
1170+
bootenv_size, base_offset + bootenv_offset, l)))
11671171
goto out;
11681172
if (byteswap) {
11691173
byteswap_uint64_array(&bootenv_eck->zec_cksum,
@@ -1173,15 +1177,15 @@ zhack_repair_one_label_large(const zhack_repair_op_t op, const int fd,
11731177
}
11741178
if ((op & ZHACK_REPAIR_OP_CKSUM) == 0 &&
11751179
zhack_repair_test_cksum(byteswap, bootenv, bootenv_size,
1176-
bootenv_eck, offset, l) != 0) {
1180+
bootenv_eck, base_offset + bootenv_offset, l) != 0) {
11771181
(void) fprintf(stderr, "It would appear checksums are "
11781182
"corrupted. Try zhack repair label -c <device>\n");
11791183
goto out;
11801184
}
11811185
}
11821186

1183-
offset += bootenv_size;
1184-
if ((err = zhack_repair_read(fd, vdev_config, vc_size, offset, l)))
1187+
if ((err = zhack_repair_read(fd, vdev_config, vc_size,
1188+
base_offset + vc_offset, l)))
11851189
goto out;
11861190

11871191
if (byteswap) {
@@ -1191,13 +1195,13 @@ zhack_repair_one_label_large(const zhack_repair_op_t op, const int fd,
11911195
}
11921196
if ((op & ZHACK_REPAIR_OP_CKSUM) == 0 &&
11931197
zhack_repair_test_cksum(byteswap, vdev_config, vc_size,
1194-
vc_eck, offset, l) != 0) {
1198+
vc_eck, base_offset + vc_offset, l) != 0) {
11951199
(void) fprintf(stderr, "It would appear checksums are "
11961200
"corrupted. Try zhack repair label -c <device>\n");
11971201
goto out;
11981202
}
1199-
offset += vc_size;
1200-
if ((err = zhack_repair_read(fd, spa_config, sc_size, offset, l)))
1203+
if ((err = zhack_repair_read(fd, spa_config, sc_size,
1204+
base_offset + sc_offset, l)))
12011205
goto out;
12021206

12031207
if (byteswap) {
@@ -1207,7 +1211,7 @@ zhack_repair_one_label_large(const zhack_repair_op_t op, const int fd,
12071211
}
12081212
if ((op & ZHACK_REPAIR_OP_CKSUM) == 0 &&
12091213
zhack_repair_test_cksum(byteswap, spa_config, sc_size,
1210-
sc_eck, offset, l) != 0) {
1214+
sc_eck, base_offset + sc_offset, l) != 0) {
12111215
(void) fprintf(stderr, "It would appear checksums are "
12121216
"corrupted. Try zhack repair label -c <device>\n");
12131217
goto out;
@@ -1256,21 +1260,17 @@ zhack_repair_one_label_large(const zhack_repair_op_t op, const int fd,
12561260
label_offset, labels_repaired);
12571261
}
12581262

1259-
offset = label_offset;
12601263
if (zhack_repair_write_label(l, fd, byteswap, toc_data, toc_eck,
1261-
offset, VDEV_TOC_SIZE))
1264+
base_offset, VDEV_TOC_SIZE))
12621265
labels_repaired[l] |= REPAIR_LABEL_STATUS_CKSUM;
1263-
offset += VDEV_TOC_SIZE;
12641266
if (zhack_repair_write_label(l, fd, byteswap, bootenv, bootenv_eck,
1265-
offset, bootenv_size))
1267+
base_offset + bootenv_offset, bootenv_size))
12661268
labels_repaired[l] |= REPAIR_LABEL_STATUS_CKSUM;
1267-
offset += bootenv_size;
12681269
if (zhack_repair_write_label(l, fd, byteswap, vdev_config, vc_eck,
1269-
offset, vc_size))
1270+
base_offset + vc_offset, vc_size))
12701271
labels_repaired[l] |= REPAIR_LABEL_STATUS_CKSUM;
1271-
offset += vc_size;
12721272
if (zhack_repair_write_label(l, fd, byteswap, spa_config, sc_eck,
1273-
offset, sc_size))
1273+
base_offset + sc_offset, sc_size))
12741274
labels_repaired[l] |= REPAIR_LABEL_STATUS_CKSUM;
12751275

12761276
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
@@ -639,7 +639,7 @@
639639
<elf-symbol name='fletcher_4_superscalar_ops' size='128' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
640640
<elf-symbol name='libzfs_config_ops' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
641641
<elf-symbol name='sa_protocol_names' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
642-
<elf-symbol name='spa_feature_table' size='2632' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
642+
<elf-symbol name='spa_feature_table' size='2688' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
643643
<elf-symbol name='zfeature_checks_disable' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
644644
<elf-symbol name='zfs_deleg_perm_tab' size='528' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
645645
<elf-symbol name='zfs_history_event_names' size='328' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -9618,8 +9618,8 @@
96189618
</function-decl>
96199619
</abi-instr>
96209620
<abi-instr address-size='64' path='module/zcommon/zfeature_common.c' language='LANG_C99'>
9621-
<array-type-def dimensions='1' type-id='83f29ca2' size-in-bits='21056' id='fd43354e'>
9622-
<subrange length='47' type-id='7359adad' id='8f8900fe'/>
9621+
<array-type-def dimensions='1' type-id='83f29ca2' size-in-bits='21504' id='bd288d11'>
9622+
<subrange length='48' type-id='7359adad' id='8f6d2a81'/>
96239623
</array-type-def>
96249624
<enum-decl name='zfeature_flags' id='6db816a4'>
96259625
<underlying-type type-id='9cac1fee'/>
@@ -9697,7 +9697,7 @@
96979697
<pointer-type-def type-id='611586a1' size-in-bits='64' id='2e243169'/>
96989698
<qualified-type-def type-id='eaa32e2f' const='yes' id='83be723c'/>
96999699
<pointer-type-def type-id='83be723c' size-in-bits='64' id='7acd98a2'/>
9700-
<var-decl name='spa_feature_table' type-id='fd43354e' mangled-name='spa_feature_table' visibility='default' elf-symbol-id='spa_feature_table'/>
9700+
<var-decl name='spa_feature_table' type-id='bd288d11' mangled-name='spa_feature_table' visibility='default' elf-symbol-id='spa_feature_table'/>
97019701
<var-decl name='zfeature_checks_disable' type-id='c19b74c3' mangled-name='zfeature_checks_disable' visibility='default' elf-symbol-id='zfeature_checks_disable'/>
97029702
<function-decl name='opendir' visibility='default' binding='global' size-in-bits='64'>
97039703
<parameter type-id='80f4b756'/>

module/zfs/vdev_label.c

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

853853
if (zio_wait(zio[l]) == 0 && nvlist_unpack(
854854
(char *)vp[l], VDEV_TOC_SIZE, &toc, 0) == 0) {
855-
uint32_t bootconf_size;
856-
if (nvlist_lookup_uint32(toc,
857-
VDEV_TOC_BOOT_REGION, &bootconf_size) != 0)
855+
uint32_t off;
856+
if (!vdev_toc_get_secinfo(toc,
857+
VDEV_TOC_VDEV_CONFIG,
858+
&vp_size[l], &off))
858859
continue;
859-
if (nvlist_lookup_uint32(toc,
860-
VDEV_TOC_VDEV_CONFIG, &vp_size[l]) != 0)
861-
continue;
862-
vp_off[l] = VDEV_LARGE_PAD_SIZE + toc_size +
863-
bootconf_size;
860+
vp_off[l] = VDEV_LARGE_PAD_SIZE + off;
864861
fnvlist_free(toc);
865862
}
866863
}
@@ -1321,9 +1318,14 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason)
13211318
NV_ENCODE_XDR, KM_SLEEP));
13221319
fnvlist_free(spa_config);
13231320
fnvlist_add_uint32(toc, VDEV_TOC_TOC_SIZE, writesize);
1324-
fnvlist_add_uint32(toc, VDEV_TOC_BOOT_REGION, 0);
1325-
fnvlist_add_uint32(toc, VDEV_TOC_VDEV_CONFIG, vp_size);
1326-
fnvlist_add_uint32(toc, VDEV_TOC_POOL_CONFIG, sc_buflen);
1321+
1322+
nvlist_t *sections = fnvlist_alloc();
1323+
vdev_toc_add_secinfo(sections, VDEV_TOC_VDEV_CONFIG, vp_size,
1324+
writesize);
1325+
vdev_toc_add_secinfo(sections, VDEV_TOC_POOL_CONFIG, sc_buflen,
1326+
writesize + vp_size);
1327+
fnvlist_add_nvlist(toc, VDEV_TOC_SECTIONS, sections);
1328+
fnvlist_free(sections);
13271329

13281330
if (ub_abd2 == NULL)
13291331
ub_abd2 = abd_alloc_linear(SPA_MAXBLOCKSIZE, B_TRUE);
@@ -1457,18 +1459,22 @@ vdev_label_read_bootenv_impl(zio_t *zio, vdev_t *vd, int flags)
14571459
continue;
14581460
}
14591461
nvlist_t *toc;
1460-
uint32_t bootenv_size;
14611462
if (!nvlist_unpack(abd_to_buf(toc_abds[l]), toc_size,
1462-
&toc, KM_SLEEP) || !nvlist_lookup_uint32(toc,
1463-
VDEV_TOC_BOOT_REGION, &bootenv_size)) {
1463+
&toc, KM_SLEEP)) {
14641464
abd_free(toc_abds[l]);
14651465
continue;
14661466
}
14671467
abd_free(toc_abds[l]);
1468+
uint32_t bootenv_size, bootenv_offset;
1469+
if (!vdev_toc_get_secinfo(toc, VDEV_TOC_BOOT_REGION,
1470+
&bootenv_size, &bootenv_offset)) {
1471+
fnvlist_free(toc);
1472+
continue;
1473+
}
14681474

14691475
vdev_label_read(zio, vd, l, B_FALSE,
14701476
abd_alloc_linear(bootenv_size, B_FALSE),
1471-
VDEV_LARGE_PAD_SIZE + toc_size, bootenv_size,
1477+
VDEV_LARGE_PAD_SIZE + bootenv_offset, bootenv_size,
14721478
vdev_label_read_bootenv_done, zio, flags);
14731479
}
14741480
} else {
@@ -1662,18 +1668,23 @@ vdev_label_write_bootenv(vdev_t *vd, nvlist_t *env)
16621668
continue;
16631669
}
16641670
nvlist_t *toc;
1665-
uint32_t bootenv_size;
1671+
uint32_t bootenv_size, bootenv_offset;
16661672
if (!(error = nvlist_unpack(abd_to_buf(toc_abds[l]),
1667-
toc_size, &toc, KM_SLEEP)) ||
1668-
(error = !nvlist_lookup_uint32(toc,
1669-
VDEV_TOC_BOOT_REGION, &bootenv_size))) {
1673+
toc_size, &toc, KM_SLEEP))) {
16701674
all_writeable = B_FALSE;
16711675
continue;
16721676
}
1677+
if (!vdev_toc_get_secinfo(toc, VDEV_TOC_BOOT_REGION,
1678+
&bootenv_size, &bootenv_offset)) {
1679+
fnvlist_free(toc);
1680+
all_writeable = B_FALSE;
1681+
continue;
1682+
}
1683+
fnvlist_free(toc);
16731684

16741685
if (new_abd_size == bootenv_size) {
16751686
vdev_label_write(zio, vd, l, B_TRUE, abd,
1676-
VDEV_LARGE_PAD_SIZE + toc_size,
1687+
VDEV_LARGE_PAD_SIZE + bootenv_offset,
16771688
new_abd_size, NULL, NULL, flags);
16781689
} else {
16791690
all_writeable = B_FALSE;
@@ -2170,9 +2181,18 @@ vdev_label_sync_large(vdev_t *vd, zio_t *zio, uint64_t *good_writes,
21702181
size_t writesize = P2ROUNDUP(toc_buflen, 1 << vd->vdev_ashift);
21712182
nvlist_t *toc = fnvlist_alloc();
21722183
fnvlist_add_uint32(toc, VDEV_TOC_TOC_SIZE, writesize);
2173-
fnvlist_add_uint32(toc, VDEV_TOC_BOOT_REGION, bootenv_size);
2174-
fnvlist_add_uint32(toc, VDEV_TOC_VDEV_CONFIG, vdev_config_size);
2175-
fnvlist_add_uint32(toc, VDEV_TOC_POOL_CONFIG, pool_config_size);
2184+
2185+
nvlist_t *sections = fnvlist_alloc();
2186+
if (bootenv_size != 0) {
2187+
vdev_toc_add_secinfo(sections, VDEV_TOC_BOOT_REGION,
2188+
bootenv_size, writesize);
2189+
}
2190+
vdev_toc_add_secinfo(sections, VDEV_TOC_VDEV_CONFIG, vdev_config_size,
2191+
writesize + bootenv_size);
2192+
vdev_toc_add_secinfo(sections, VDEV_TOC_POOL_CONFIG, pool_config_size,
2193+
writesize + bootenv_size + vdev_config_size);
2194+
fnvlist_add_nvlist(toc, VDEV_TOC_SECTIONS, sections);
2195+
fnvlist_free(sections);
21762196

21772197
ASSERT3U(fnvlist_size(toc) + sizeof (zio_eck_t), <=, VDEV_TOC_SIZE);
21782198

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

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ log_assert "Verify that new label works for more advanced pool operations"
4343
log_onexit cleanup
4444

4545
mntpnt="$TESTDIR1"
46-
log_must truncate --size=2T $mntpnt/dsk{0,1,2,3,4,5,6,7}
46+
log_must truncate -s 2T $mntpnt/dsk{0,1,2,3,4,5,6,7}
4747

4848
DSK="$mntpnt/dsk"
4949

0 commit comments

Comments
 (0)