]> granicus.if.org Git - zfs/commitdiff
Fix zfs_vdev_aggregation_limit bounds checking
authorBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 17 Dec 2015 17:26:05 +0000 (09:26 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 18 Dec 2015 21:32:06 +0000 (13:32 -0800)
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 <behlendorf1@llnl.gov>
module/zfs/vdev_queue.c

index 0c62a6fa3c7df4b3de618166dab6c710d7b6642a..e828ce9176f5801fb1b7c21965ed5cebe753c6ad 100644 (file)
@@ -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)