Skip to content

Commit

Permalink
Fix zfs_vdev_aggregation_limit bounds checking
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
behlendorf committed Dec 18, 2015
1 parent 6fe5378 commit a58df6f
Showing 1 changed file with 8 additions and 11 deletions.
19 changes: 8 additions & 11 deletions module/zfs/vdev_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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))
Expand All @@ -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))
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit a58df6f

Please sign in to comment.