MFV/ZoL: 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. Author: Brian Behlendorf <behlendorf1@llnl.gov> zfsonlinux/zfs@a58df6f536 MFV/ZoL: 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. Author: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed by: Matthew Ahrens <mahrens@delphix.com> Reviewed-by: George Melikov <mail@gmelikov.ru> Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #6259 Closes #6270 zfsonlinux/zfs@2d678f779a
This commit is contained in:
parent
1e1af27f31
commit
ac6361987e
@ -673,13 +673,18 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
|
||||
zio_link_t *zl = NULL;
|
||||
uint64_t maxgap = 0;
|
||||
uint64_t size;
|
||||
uint64_t limit;
|
||||
int maxblocksize;
|
||||
boolean_t stretch;
|
||||
avl_tree_t *t;
|
||||
enum zio_flag flags;
|
||||
|
||||
ASSERT(MUTEX_HELD(&vq->vq_lock));
|
||||
|
||||
if (zio->io_flags & ZIO_FLAG_DONT_AGGREGATE)
|
||||
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);
|
||||
|
||||
first = last = zio;
|
||||
@ -710,7 +715,7 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
|
||||
t = vdev_queue_type_tree(vq, zio->io_type);
|
||||
while (t != NULL && (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 &&
|
||||
dio->io_type == zio->io_type) {
|
||||
first = dio;
|
||||
@ -734,8 +739,9 @@ 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 ||
|
||||
(dio->io_flags & ZIO_FLAG_OPTIONAL)) &&
|
||||
IO_SPAN(first, dio) <= maxblocksize &&
|
||||
IO_GAP(last, dio) <= maxgap &&
|
||||
dio->io_type == zio->io_type) {
|
||||
last = dio;
|
||||
@ -789,7 +795,7 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
|
||||
return (NULL);
|
||||
|
||||
size = IO_SPAN(first, last);
|
||||
ASSERT3U(size, <=, SPA_MAXBLOCKSIZE);
|
||||
ASSERT3U(size, <=, maxblocksize);
|
||||
|
||||
aio = zio_vdev_delegated_io(first->io_vd, first->io_offset,
|
||||
abd_alloc_for_io(size, B_TRUE), size, first->io_type,
|
||||
|
Loading…
Reference in New Issue
Block a user