diff options
author | Brian Behlendorf <[email protected]> | 2017-06-27 10:09:16 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2017-06-27 10:09:16 -0700 |
commit | 2d678f779aba26a93314c8ee1142c3985fa25cb6 (patch) | |
tree | e399bbc2885589226d5fbb8f7c9f3f13a2fa5189 /module/zfs/vdev_queue.c | |
parent | 47770d30f205b81ece1f60760f3edb5c04574e6e (diff) |
Cap maximum aggregate IO size
Commit 8542ef8 allowed optional IOs to be aggregated beyond
the specified aggregation limit. Since the aggregation limit
was also used to enforce the maximum block size, setting
`zfs_vdev_aggregation_limit=16777216` could result in an
attempt to allocate an ABD larger than 16M.
Reviewed by: Matthew Ahrens <[email protected]>
Reviewed-by: George Melikov <[email protected]>
Reviewed-by: Giuseppe Di Natale <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #6259
Closes #6270
Diffstat (limited to 'module/zfs/vdev_queue.c')
-rw-r--r-- | module/zfs/vdev_queue.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/module/zfs/vdev_queue.c b/module/zfs/vdev_queue.c index 2439f2951..6b3e87291 100644 --- a/module/zfs/vdev_queue.c +++ b/module/zfs/vdev_queue.c @@ -521,13 +521,14 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio) uint64_t maxgap = 0; uint64_t size; uint64_t limit; + int maxblocksize; boolean_t stretch = B_FALSE; avl_tree_t *t = vdev_queue_type_tree(vq, zio->io_type); enum zio_flag flags = zio->io_flags & ZIO_FLAG_AGG_INHERIT; abd_t *abd; - limit = MAX(MIN(zfs_vdev_aggregation_limit, - spa_maxblocksize(vq->vq_vdev->vdev_spa)), 0); + maxblocksize = spa_maxblocksize(vq->vq_vdev->vdev_spa); + limit = MAX(MIN(zfs_vdev_aggregation_limit, maxblocksize), 0); if (zio->io_flags & ZIO_FLAG_DONT_AGGREGATE || limit == 0) return (NULL); @@ -584,6 +585,7 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio) (dio->io_flags & ZIO_FLAG_AGG_INHERIT) == flags && (IO_SPAN(first, dio) <= limit || (dio->io_flags & ZIO_FLAG_OPTIONAL)) && + IO_SPAN(first, dio) <= maxblocksize && IO_GAP(last, dio) <= maxgap) { last = dio; if (!(last->io_flags & ZIO_FLAG_OPTIONAL)) @@ -635,6 +637,7 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio) return (NULL); size = IO_SPAN(first, last); + ASSERT3U(size, <=, maxblocksize); abd = abd_alloc_for_io(size, B_TRUE); if (abd == NULL) |