Fix resilver writes in vdev_indirect_io_start
This patch addresses an issue found in ztest where resilver write zios that were passed to an indirect vdev would end up being handled as though they were resilver read zios. This caused issues where the zio->io_abd would be both read to and written from at the same time, causing asserts to fail. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed by: Matt Ahrens <matt@delphix.com> Reviewed-by: Serapheim Dimitropoulos <serapheim@delphix.com> Signed-off-by: Tom Caputi <tcaputi@datto.com> Closes #8193
This commit is contained in:
parent
4b70290163
commit
5aa95ba0d3
|
@ -1265,6 +1265,8 @@ vdev_indirect_read_all(zio_t *zio)
|
||||||
{
|
{
|
||||||
indirect_vsd_t *iv = zio->io_vsd;
|
indirect_vsd_t *iv = zio->io_vsd;
|
||||||
|
|
||||||
|
ASSERT3U(zio->io_type, ==, ZIO_TYPE_READ);
|
||||||
|
|
||||||
for (indirect_split_t *is = list_head(&iv->iv_splits);
|
for (indirect_split_t *is = list_head(&iv->iv_splits);
|
||||||
is != NULL; is = list_next(&iv->iv_splits, is)) {
|
is != NULL; is = list_next(&iv->iv_splits, is)) {
|
||||||
for (int i = 0; i < is->is_children; i++) {
|
for (int i = 0; i < is->is_children; i++) {
|
||||||
|
@ -1347,7 +1349,8 @@ vdev_indirect_io_start(zio_t *zio)
|
||||||
vdev_indirect_child_io_done, zio));
|
vdev_indirect_child_io_done, zio));
|
||||||
} else {
|
} else {
|
||||||
iv->iv_split_block = B_TRUE;
|
iv->iv_split_block = B_TRUE;
|
||||||
if (zio->io_flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER)) {
|
if (zio->io_type == ZIO_TYPE_READ &&
|
||||||
|
zio->io_flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER)) {
|
||||||
/*
|
/*
|
||||||
* Read all copies. Note that for simplicity,
|
* Read all copies. Note that for simplicity,
|
||||||
* we don't bother consulting the DTL in the
|
* we don't bother consulting the DTL in the
|
||||||
|
@ -1356,13 +1359,17 @@ vdev_indirect_io_start(zio_t *zio)
|
||||||
vdev_indirect_read_all(zio);
|
vdev_indirect_read_all(zio);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Read one copy of each split segment, from the
|
* If this is a read zio, we read one copy of each
|
||||||
* top-level vdev. Since we don't know the
|
* split segment, from the top-level vdev. Since
|
||||||
* checksum of each split individually, the child
|
* we don't know the checksum of each split
|
||||||
* zio can't ensure that we get the right data.
|
* individually, the child zio can't ensure that
|
||||||
* E.g. if it's a mirror, it will just read from a
|
* we get the right data. E.g. if it's a mirror,
|
||||||
* random (healthy) leaf vdev. We have to verify
|
* it will just read from a random (healthy) leaf
|
||||||
* the checksum in vdev_indirect_io_done().
|
* vdev. We have to verify the checksum in
|
||||||
|
* vdev_indirect_io_done().
|
||||||
|
*
|
||||||
|
* For write zios, the vdev code will ensure we write
|
||||||
|
* to all children.
|
||||||
*/
|
*/
|
||||||
for (indirect_split_t *is = list_head(&iv->iv_splits);
|
for (indirect_split_t *is = list_head(&iv->iv_splits);
|
||||||
is != NULL; is = list_next(&iv->iv_splits, is)) {
|
is != NULL; is = list_next(&iv->iv_splits, is)) {
|
||||||
|
|
Loading…
Reference in New Issue