mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-26 19:19:32 +03:00
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 <behlendorf1@llnl.gov>
This commit is contained in:
parent
6fe53787f3
commit
a58df6f536
@ -499,20 +499,17 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
|
|||||||
zio_t *first, *last, *aio, *dio, *mandatory, *nio;
|
zio_t *first, *last, *aio, *dio, *mandatory, *nio;
|
||||||
uint64_t maxgap = 0;
|
uint64_t maxgap = 0;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
|
uint64_t limit;
|
||||||
boolean_t stretch = B_FALSE;
|
boolean_t stretch = B_FALSE;
|
||||||
avl_tree_t *t = vdev_queue_type_tree(vq, zio->io_type);
|
avl_tree_t *t = vdev_queue_type_tree(vq, zio->io_type);
|
||||||
enum zio_flag flags = zio->io_flags & ZIO_FLAG_AGG_INHERIT;
|
enum zio_flag flags = zio->io_flags & ZIO_FLAG_AGG_INHERIT;
|
||||||
void *buf;
|
void *buf;
|
||||||
|
|
||||||
if (zio->io_flags & ZIO_FLAG_DONT_AGGREGATE)
|
limit = MAX(MIN(zfs_vdev_aggregation_limit,
|
||||||
return (NULL);
|
spa_maxblocksize(vq->vq_vdev->vdev_spa)), 0);
|
||||||
|
|
||||||
/*
|
if (zio->io_flags & ZIO_FLAG_DONT_AGGREGATE || limit == 0)
|
||||||
* Prevent users from setting the zfs_vdev_aggregation_limit
|
return (NULL);
|
||||||
* tuning larger than SPA_MAXBLOCKSIZE.
|
|
||||||
*/
|
|
||||||
zfs_vdev_aggregation_limit =
|
|
||||||
MIN(zfs_vdev_aggregation_limit, SPA_MAXBLOCKSIZE);
|
|
||||||
|
|
||||||
first = last = zio;
|
first = last = zio;
|
||||||
|
|
||||||
@ -540,7 +537,7 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
|
|||||||
*/
|
*/
|
||||||
while ((dio = AVL_PREV(t, first)) != NULL &&
|
while ((dio = AVL_PREV(t, first)) != NULL &&
|
||||||
(dio->io_flags & ZIO_FLAG_AGG_INHERIT) == flags &&
|
(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) {
|
IO_GAP(dio, first) <= maxgap) {
|
||||||
first = dio;
|
first = dio;
|
||||||
if (mandatory == NULL && !(first->io_flags & ZIO_FLAG_OPTIONAL))
|
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 &&
|
while ((dio = AVL_NEXT(t, last)) != NULL &&
|
||||||
(dio->io_flags & ZIO_FLAG_AGG_INHERIT) == flags &&
|
(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) {
|
IO_GAP(last, dio) <= maxgap) {
|
||||||
last = dio;
|
last = dio;
|
||||||
if (!(last->io_flags & ZIO_FLAG_OPTIONAL))
|
if (!(last->io_flags & ZIO_FLAG_OPTIONAL))
|
||||||
@ -607,7 +604,7 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
size = IO_SPAN(first, last);
|
size = IO_SPAN(first, last);
|
||||||
ASSERT3U(size, <=, zfs_vdev_aggregation_limit);
|
ASSERT3U(size, <=, limit);
|
||||||
|
|
||||||
buf = zio_buf_alloc_flags(size, KM_NOSLEEP);
|
buf = zio_buf_alloc_flags(size, KM_NOSLEEP);
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
|
Loading…
Reference in New Issue
Block a user