Skip to content

Commit

Permalink
zfs: read all disk labels concurrently in vdev_label_read_config
Browse files Browse the repository at this point in the history
This is similar to what we already do in vdev_geom_read_config.

openzfs/zfs#11470

Sponsored by:   Axcient
  • Loading branch information
asomers committed Jan 19, 2021
1 parent bdd1db5 commit 1053384
Showing 1 changed file with 21 additions and 14 deletions.
35 changes: 21 additions & 14 deletions sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c
Original file line number Diff line number Diff line change
Expand Up @@ -577,9 +577,9 @@ vdev_label_read_config(vdev_t *vd, uint64_t txg)
{
spa_t *spa = vd->vdev_spa;
nvlist_t *config = NULL;
vdev_phys_t *vp;
abd_t *vp_abd;
zio_t *zio;
vdev_phys_t *vp[VDEV_LABELS];
abd_t *vp_abd[VDEV_LABELS];
zio_t *zio[VDEV_LABELS];
uint64_t best_txg = 0;
uint64_t label_txg = 0;
int error = 0;
Expand All @@ -591,21 +591,24 @@ vdev_label_read_config(vdev_t *vd, uint64_t txg)
if (!vdev_readable(vd))
return (NULL);

vp_abd = abd_alloc_linear(sizeof (vdev_phys_t), B_TRUE);
vp = abd_to_buf(vp_abd);
for (int l = 0; l < VDEV_LABELS; l++) {
vp_abd[l] = abd_alloc_linear(sizeof (vdev_phys_t), B_TRUE);
vp[l] = abd_to_buf(vp_abd[l]);
}

retry:
for (int l = 0; l < VDEV_LABELS; l++) {
nvlist_t *label = NULL;

zio = zio_root(spa, NULL, NULL, flags);
zio[l] = zio_root(spa, NULL, NULL, flags);

vdev_label_read(zio, vd, l, vp_abd,
offsetof(vdev_label_t, vl_vdev_phys),
sizeof (vdev_phys_t), NULL, NULL, flags);
vdev_label_read(zio[l], vd, l, vp_abd[l],
offsetof(vdev_label_t, vl_vdev_phys), sizeof (vdev_phys_t),
NULL, NULL, flags);
}
for (int l = 0; l < VDEV_LABELS; l++) {
nvlist_t *label = NULL;

if (zio_wait(zio) == 0 &&
nvlist_unpack(vp->vp_nvlist, sizeof (vp->vp_nvlist),
if (zio_wait(zio[l]) == 0 &&
nvlist_unpack(vp[l]->vp_nvlist, sizeof (vp[l]->vp_nvlist),
&label, 0) == 0) {
/*
* Auxiliary vdevs won't have txg values in their
Expand All @@ -618,6 +621,8 @@ vdev_label_read_config(vdev_t *vd, uint64_t txg)
ZPOOL_CONFIG_POOL_TXG, &label_txg);
if ((error || label_txg == 0) && !config) {
config = label;
for (l++; l < VDEV_LABELS; l++)
zio_wait(zio[l]);
break;
} else if (label_txg <= txg && label_txg > best_txg) {
best_txg = label_txg;
Expand Down Expand Up @@ -646,7 +651,9 @@ vdev_label_read_config(vdev_t *vd, uint64_t txg)
(u_longlong_t)txg);
}

abd_free(vp_abd);
for (int l = 0; l < VDEV_LABELS; l++) {
abd_free(vp_abd[l]);
}

return (config);
}
Expand Down

0 comments on commit 1053384

Please sign in to comment.