Skip to content

Commit 3dfd72c

Browse files
author
Paul Dagnelie
committed
Handle replacing/spares on anyraid children
Signed-off-by: Paul Dagnelie <[email protected]> Sponsored-by: Eshtek, creators of HexOS Sponsored-by: Klara, Inc.
1 parent fb12a58 commit 3dfd72c

File tree

1 file changed

+44
-10
lines changed

1 file changed

+44
-10
lines changed

module/zfs/vdev_anyraid.c

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,41 @@ create_tile_entry(vdev_anyraid_t *var, anyraid_map_loc_entry_t *amle,
265265
*out_ar = ar;
266266
}
267267

268+
static void
269+
child_read_done(zio_t *zio)
270+
{
271+
zio_t *pio = zio_unique_parent(zio);
272+
abd_t **cbp = pio->io_private;
273+
274+
if (zio->io_error == 0) {
275+
mutex_enter(&pio->io_lock);
276+
if (*cbp == NULL)
277+
*cbp = zio->io_abd;
278+
else
279+
abd_free(zio->io_abd);
280+
mutex_exit(&pio->io_lock);
281+
} else {
282+
abd_free(zio->io_abd);
283+
}
284+
}
285+
286+
static void
287+
child_read(zio_t *zio, vdev_t *vd, uint64_t offset, uint64_t size,
288+
int checksum, void *private, int flags)
289+
{
290+
for (int c = 0; c < vd->vdev_children; c++) {
291+
child_read(zio, vd->vdev_child[c], offset, size, checksum,
292+
private, flags);
293+
}
294+
295+
if (vd->vdev_ops->vdev_op_leaf && vdev_readable(vd)) {
296+
zio_nowait(zio_read_phys(zio, vd, offset, size,
297+
abd_alloc_linear(size, B_TRUE), checksum,
298+
child_read_done, private, ZIO_PRIORITY_SYNC_READ, flags,
299+
B_FALSE));
300+
}
301+
}
302+
268303
/*
269304
* This function is non-static for ZDB, and shouldn't be used for anything else.
270305
* Utility function that issues the read for the header and parses out the
@@ -281,11 +316,11 @@ vdev_anyraid_open_header(vdev_t *cvd, int header, anyraid_header_t *out_header)
281316
int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL |
282317
ZIO_FLAG_SPECULATIVE;
283318

284-
abd_t *header_abd = abd_alloc_linear(header_size, B_TRUE);
285-
zio_t *rio = zio_root(spa, NULL, NULL, flags);
286-
zio_nowait(zio_read_phys(rio, cvd, header_offset, header_size,
287-
header_abd, ZIO_CHECKSUM_LABEL, NULL, NULL, ZIO_PRIORITY_SYNC_READ,
288-
flags, B_FALSE));
319+
abd_t *header_abd = NULL;
320+
zio_t *rio = zio_root(spa, NULL, &header_abd, flags);
321+
child_read(rio, cvd, header_offset, header_size, ZIO_CHECKSUM_LABEL,
322+
NULL, flags);
323+
289324
int error;
290325
if ((error = zio_wait(rio)) != 0) {
291326
zfs_dbgmsg("Error %d reading anyraid header %d on vdev %s",
@@ -514,11 +549,10 @@ anyraid_open_existing(vdev_t *vd, uint64_t child, uint16_t **child_capacities)
514549
zio_eck_t *cksum = (zio_eck_t *)
515550
&header.ah_buf[VDEV_ANYRAID_NVL_BYTES(ashift) +
516551
i * sizeof (*cksum)];
517-
map_abds[i] = abd_alloc_linear(SPA_MAXBLOCKSIZE, B_TRUE);
518-
zio_nowait(zio_read_phys(rio, cvd, map_offset +
519-
i * SPA_MAXBLOCKSIZE, SPA_MAXBLOCKSIZE, map_abds[i],
520-
ZIO_CHECKSUM_ANYRAID_MAP, NULL, cksum,
521-
ZIO_PRIORITY_SYNC_READ, flags, B_FALSE));
552+
zio_t *nio = zio_null(rio, spa, cvd, NULL, &map_abds[i], flags);
553+
child_read(nio, cvd, map_offset + i * SPA_MAXBLOCKSIZE,
554+
SPA_MAXBLOCKSIZE, ZIO_CHECKSUM_ANYRAID_MAP, cksum, flags);
555+
zio_nowait(nio);
522556
}
523557
i--;
524558

0 commit comments

Comments
 (0)