diff --git a/include/sys/vdev.h b/include/sys/vdev.h index f49086a4776c..5b742e11577f 100644 --- a/include/sys/vdev.h +++ b/include/sys/vdev.h @@ -69,6 +69,7 @@ extern void vdev_dtl_reassess(vdev_t *vd, uint64_t txg, uint64_t scrub_txg, extern boolean_t vdev_dtl_required(vdev_t *vd); extern boolean_t vdev_resilver_needed(vdev_t *vd, uint64_t *minp, uint64_t *maxp); +extern int vdev_pending_queued(vdev_t *vd); extern void vdev_hold(vdev_t *); extern void vdev_rele(vdev_t *); diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c index c44e4f67f068..797f8fe1bcc6 100644 --- a/module/zfs/vdev.c +++ b/module/zfs/vdev.c @@ -1948,6 +1948,20 @@ vdev_resilver_needed(vdev_t *vd, uint64_t *minp, uint64_t *maxp) return (needed); } +int +vdev_pending_queued(vdev_t *vd) +{ + int pending; + + vdev_queue_t *vq = &vd->vdev_queue; + + mutex_enter(&vq->vq_lock); + pending = avl_numnodes(&vq->vq_pending_tree); + mutex_exit(&vq->vq_lock); + + return pending; +} + void vdev_load(vdev_t *vd) { diff --git a/module/zfs/vdev_mirror.c b/module/zfs/vdev_mirror.c index a2671ca81a37..03005c0fa4f7 100644 --- a/module/zfs/vdev_mirror.c +++ b/module/zfs/vdev_mirror.c @@ -221,7 +221,9 @@ vdev_mirror_child_select(zio_t *zio) mirror_map_t *mm = zio->io_vsd; mirror_child_t *mc; uint64_t txg = zio->io_txg; - int i, c; + int pending_lowest_child = -1; + int pending_lowest_count = INT_MAX; + int i, c, pending; ASSERT(zio->io_bp == NULL || BP_PHYSICAL_BIRTH(zio->io_bp) == txg); @@ -243,12 +245,28 @@ vdev_mirror_child_select(zio_t *zio) continue; } if (!vdev_dtl_contains(mc->mc_vd, DTL_MISSING, txg, 1)) - return (c); + { + pending = vdev_pending_queued(mc->mc_vd); + if (pending == 0) + return (c); + if (pending < pending_lowest_count) { + pending_lowest_count = pending; + pending_lowest_child = c; + } + continue; + } mc->mc_error = ESTALE; mc->mc_skipped = 1; mc->mc_speculative = 1; } + /* + * See if we found multiple devices with pending io's + * and return the child with smallest queue. + */ + if ( pending_lowest_child != -1 ) + return (pending_lowest_child); + /* * Every device is either missing or has this txg in its DTL. * Look for any child we haven't already tried before giving up.