diff options
-rw-r--r-- | module/zfs/vdev_queue.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/module/zfs/vdev_queue.c b/module/zfs/vdev_queue.c index f121eddc7..5d2c98013 100644 --- a/module/zfs/vdev_queue.c +++ b/module/zfs/vdev_queue.c @@ -517,6 +517,7 @@ static zio_t * vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio) { zio_t *first, *last, *aio, *dio, *mandatory, *nio; + zio_link_t *zl = NULL; uint64_t maxgap = 0; uint64_t size; uint64_t limit; @@ -665,9 +666,18 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio) zio_add_child(dio, aio); vdev_queue_io_remove(vq, dio); + } while (dio != last); + + /* + * We need to drop the vdev queue's lock to avoid a deadlock that we + * could encounter since this I/O will complete immediately. + */ + mutex_exit(&vq->vq_lock); + while ((dio = zio_walk_parents(aio, &zl)) != NULL) { zio_vdev_io_bypass(dio); zio_execute(dio); - } while (dio != last); + } + mutex_enter(&vq->vq_lock); return (aio); } |