diff options
author | Brian Behlendorf <[email protected]> | 2015-12-17 09:26:05 -0800 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2015-12-18 13:32:06 -0800 |
commit | a58df6f53687ac6d1dee21f60de41b2552a43201 (patch) | |
tree | acf683082fa88ee8f9ea5924cbec4a30210e4e4a | |
parent | 6fe53787f38f10956b8d375133ed4559f8ce847b (diff) |
Fix zfs_vdev_aggregation_limit bounds checking
Update the bounds checking for zfs_vdev_aggregation_limit so that
it has a floor of zero and a maximum value of the supported block
size for the pool.
Additionally add an early return when zfs_vdev_aggregation_limit
equals zero to disable aggregation. For very fast solid state or
memory devices it may be more expensive to perform the aggregation
than to issue the IO immediately.
Signed-off-by: Brian Behlendorf <[email protected]>
-rw-r--r-- | module/zfs/vdev_queue.c | 19 |
1 files changed, 8 insertions, 11 deletions
diff --git a/module/zfs/vdev_queue.c b/module/zfs/vdev_queue.c index 0c62a6fa3..e828ce917 100644 --- a/module/zfs/vdev_queue.c +++ b/module/zfs/vdev_queue.c @@ -499,20 +499,17 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio) zio_t *first, *last, *aio, *dio, *mandatory, *nio; uint64_t maxgap = 0; uint64_t size; + uint64_t limit; 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; void *buf; - if (zio->io_flags & ZIO_FLAG_DONT_AGGREGATE) - return (NULL); + limit = MAX(MIN(zfs_vdev_aggregation_limit, + spa_maxblocksize(vq->vq_vdev->vdev_spa)), 0); - /* - * Prevent users from setting the zfs_vdev_aggregation_limit - * tuning larger than SPA_MAXBLOCKSIZE. - */ - zfs_vdev_aggregation_limit = - MIN(zfs_vdev_aggregation_limit, SPA_MAXBLOCKSIZE); + if (zio->io_flags & ZIO_FLAG_DONT_AGGREGATE || limit == 0) + return (NULL); first = last = zio; @@ -540,7 +537,7 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio) */ while ((dio = AVL_PREV(t, first)) != NULL && (dio->io_flags & ZIO_FLAG_AGG_INHERIT) == flags && - IO_SPAN(dio, last) <= zfs_vdev_aggregation_limit && + IO_SPAN(dio, last) <= limit && IO_GAP(dio, first) <= maxgap) { first = dio; if (mandatory == NULL && !(first->io_flags & ZIO_FLAG_OPTIONAL)) @@ -561,7 +558,7 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio) */ while ((dio = AVL_NEXT(t, last)) != NULL && (dio->io_flags & ZIO_FLAG_AGG_INHERIT) == flags && - IO_SPAN(first, dio) <= zfs_vdev_aggregation_limit && + IO_SPAN(first, dio) <= limit && IO_GAP(last, dio) <= maxgap) { last = dio; if (!(last->io_flags & ZIO_FLAG_OPTIONAL)) @@ -607,7 +604,7 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio) return (NULL); size = IO_SPAN(first, last); - ASSERT3U(size, <=, zfs_vdev_aggregation_limit); + ASSERT3U(size, <=, limit); buf = zio_buf_alloc_flags(size, KM_NOSLEEP); if (buf == NULL) |