summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2015-12-17 09:26:05 -0800
committerBrian Behlendorf <[email protected]>2015-12-18 13:32:06 -0800
commita58df6f53687ac6d1dee21f60de41b2552a43201 (patch)
treeacf683082fa88ee8f9ea5924cbec4a30210e4e4a
parent6fe53787f38f10956b8d375133ed4559f8ce847b (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.c19
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)