Skip to content

Commit 9b03467

Browse files
committed
Try multi-ring setup for large labels
Signed-off-by: Paul Dagnelie <paul.dagnelie@klarasystems.com>
1 parent 26528d0 commit 9b03467

File tree

3 files changed

+41
-12
lines changed

3 files changed

+41
-12
lines changed

cmd/zdb/zdb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4808,7 +4808,7 @@ print_label_header(zdb_label_t *label, boolean_t large_label, int l)
48084808
return;
48094809

48104810
(void) printf("------------------------------------\n");
4811-
(void) printf("LABEL(%s) %d %s\n", large_label ? "new" : "old", l,
4811+
(void) printf("LABEL(%s) %d %s\n", large_label ? "large" : "small", l,
48124812
label->cksum_valid ? "" : "(Bad label cksum)");
48134813
(void) printf("------------------------------------\n");
48144814

include/sys/vdev_impl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ struct vdev {
493493
#define VDEV_PHYS_SIZE (112 << 10)
494494
#define VDEV_UBERBLOCK_RING (128 << 10)
495495
#define VDEV_LARGE_UBERBLOCK_RING (128 << 20) // The last 128MiB
496+
#define VDEV_UBERBLOCK_SMALL_RING 8
496497

497498
/*
498499
* MMP blocks occupy the last MMP_BLOCKS_PER_LABEL slots in the uberblock
@@ -519,6 +520,7 @@ struct vdev {
519520
VDEV_UBERBLOCK_OFFSET_OLD(vd, n))
520521
#define VDEV_UBERBLOCK_SIZE(vd) (1ULL << VDEV_UBERBLOCK_SHIFT(vd))
521522

523+
522524
typedef struct vdev_phys {
523525
char vp_nvlist[VDEV_PHYS_SIZE - sizeof (zio_eck_t)];
524526
zio_eck_t vp_zbt;

module/zfs/vdev_label.c

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,16 +1818,23 @@ vdev_uberblock_load_done(zio_t *zio)
18181818

18191819
static void
18201820
vdev_uberblock_load_impl(zio_t **zio, vdev_t *vd, int flags,
1821-
struct ubl_cbdata *cbp, uint32_t *ios)
1821+
struct ubl_cbdata *cbp, uint32_t *ios, boolean_t try_hard)
18221822
{
18231823
for (int c = 0; c < vd->vdev_children; c++)
18241824
vdev_uberblock_load_impl(zio, vd->vdev_child[c], flags, cbp,
1825-
ios);
1825+
ios, try_hard);
18261826

18271827
if (vd->vdev_ops->vdev_op_leaf && vdev_readable(vd) &&
18281828
vd->vdev_ops != &vdev_draid_spare_ops) {
18291829
for (int l = 0; l < VDEV_LABELS; l++) {
1830-
for (int n = 0; n < VDEV_UBERBLOCK_COUNT(vd); n++) {
1830+
int n = 0, lim = VDEV_UBERBLOCK_COUNT(vd);
1831+
if (vd->vdev_large_label) {
1832+
if (!try_hard)
1833+
lim = VDEV_UBERBLOCK_SMALL_RING;
1834+
else
1835+
n = VDEV_UBERBLOCK_SMALL_RING;
1836+
}
1837+
for (; n < lim; n++) {
18311838
(*ios)++;
18321839
if (*ios > 1 << 16) {
18331840
(void) zio_wait(*zio);
@@ -1863,7 +1870,8 @@ vdev_uberblock_load(vdev_t *rvd, uberblock_t *ub, nvlist_t **config)
18631870

18641871
ASSERT(ub);
18651872
ASSERT(config);
1866-
1873+
boolean_t try_hard = B_FALSE;
1874+
retry:
18671875
memset(ub, 0, sizeof (uberblock_t));
18681876
memset(&cb, 0, sizeof (cb));
18691877
*config = NULL;
@@ -1873,7 +1881,7 @@ vdev_uberblock_load(vdev_t *rvd, uberblock_t *ub, nvlist_t **config)
18731881
spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
18741882
zio = zio_root(spa, NULL, &cb, flags);
18751883
uint32_t ios = 0;
1876-
vdev_uberblock_load_impl(&zio, rvd, flags, &cb, &ios);
1884+
vdev_uberblock_load_impl(&zio, rvd, flags, &cb, &ios, try_hard);
18771885
(void) zio_wait(zio);
18781886

18791887
/*
@@ -1912,6 +1920,12 @@ vdev_uberblock_load(vdev_t *rvd, uberblock_t *ub, nvlist_t **config)
19121920
vdev_dbgmsg(cb.ubl_vd, "failed to read label config");
19131921
}
19141922
}
1923+
if (*config == NULL && rvd->vdev_large_label && !try_hard) {
1924+
vdev_dbgmsg(rvd, "failed to read label config. "
1925+
"Trying again without full uberblock ring.");
1926+
try_hard = B_TRUE;
1927+
goto retry;
1928+
}
19151929
spa_config_exit(spa, SCL_ALL, FTAG);
19161930
}
19171931

@@ -2039,8 +2053,16 @@ vdev_uberblock_sync(zio_t *zio, uint64_t *good_writes,
20392053
* uberblock.
20402054
*/
20412055
int m = spa_multihost(vd->vdev_spa) ? MMP_BLOCKS_PER_LABEL : 0;
2042-
int n = (ub->ub_txg - (RRSS_GET_STATE(ub) == RRSS_SCRATCH_VALID)) %
2056+
int n = (ub->ub_txg - (RRSS_GET_STATE(ub) == RRSS_SCRATCH_VALID));
2057+
boolean_t update_archive = (n % VDEV_UBERBLOCK_SMALL_RING) == 0;
2058+
int n2 =
2059+
((n / VDEV_UBERBLOCK_SMALL_RING) + VDEV_UBERBLOCK_SMALL_RING) %
20432060
(VDEV_UBERBLOCK_COUNT(vd) - m);
2061+
if (vd->vdev_large_label &&
2062+
VDEV_UBERBLOCK_COUNT(vd) > VDEV_UBERBLOCK_SMALL_RING)
2063+
n %= VDEV_UBERBLOCK_SMALL_RING;
2064+
else
2065+
n %= VDEV_UBERBLOCK_COUNT(vd) - m;
20442066

20452067
/* Copy the uberblock_t into the ABD */
20462068
abd_t *ub_abd = abd_alloc_for_io(VDEV_UBERBLOCK_SIZE(vd), B_TRUE);
@@ -2062,6 +2084,12 @@ vdev_uberblock_sync(zio_t *zio, uint64_t *good_writes,
20622084
VDEV_UBERBLOCK_OFFSET(vd, n), VDEV_UBERBLOCK_SIZE(vd),
20632085
vdev_uberblock_sync_done, good_writes,
20642086
flags | ZIO_FLAG_DONT_PROPAGATE);
2087+
if (vd->vdev_large_label && update_archive) {
2088+
vdev_label_write(zio, vd, l, vd->vdev_large_label,
2089+
ub_abd, VDEV_UBERBLOCK_OFFSET(vd, n2),
2090+
VDEV_UBERBLOCK_SIZE(vd), vdev_uberblock_sync_done,
2091+
good_writes, flags | ZIO_FLAG_DONT_PROPAGATE);
2092+
}
20652093
}
20662094

20672095
abd_free(ub_abd);
@@ -2288,15 +2316,14 @@ vdev_label_sync(zio_t *zio, uint64_t *good_writes,
22882316
buflen = sizeof (vp->vp_nvlist);
22892317

22902318
if (!nvlist_pack(label, &buf, &buflen, NV_ENCODE_XDR, KM_SLEEP)) {
2291-
vdev_label_sync_large(vd, zio, good_writes,
2292-
l, flags, sc_abd, vp_abd);
2319+
vdev_label_sync_large(vd, zio, good_writes, l, flags, sc_abd,
2320+
vp_abd);
22932321
for (; l < VDEV_LABELS &&
22942322
!(vd->vdev_large_label && l >= (VDEV_LABELS / 2)); l += 2) {
22952323
vdev_label_write(zio, vd, l, B_FALSE, vp_abd,
22962324
offsetof(vdev_label_t, vl_vdev_phys),
2297-
sizeof (vdev_phys_t),
2298-
vdev_label_sync_done, good_writes,
2299-
flags | ZIO_FLAG_DONT_PROPAGATE);
2325+
sizeof (vdev_phys_t), vdev_label_sync_done,
2326+
good_writes, flags | ZIO_FLAG_DONT_PROPAGATE);
23002327
}
23012328
}
23022329

0 commit comments

Comments
 (0)