*/
/*
- * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
/*
* Walk backwards through sufficiently contiguous I/Os
- * recording the last non-option I/O.
+ * recording the last non-optional I/O.
*/
while ((dio = AVL_PREV(t, first)) != NULL &&
(dio->io_flags & ZIO_FLAG_AGG_INHERIT) == flags &&
/*
* Walk forward through sufficiently contiguous I/Os.
+ * The aggregation limit does not apply to optional i/os, so that
+ * we can issue contiguous writes even if they are larger than the
+ * aggregation limit.
*/
while ((dio = AVL_NEXT(t, last)) != NULL &&
(dio->io_flags & ZIO_FLAG_AGG_INHERIT) == flags &&
- IO_SPAN(first, dio) <= limit &&
+ (IO_SPAN(first, dio) <= limit ||
+ (dio->io_flags & ZIO_FLAG_OPTIONAL)) &&
IO_GAP(last, dio) <= maxgap) {
last = dio;
if (!(last->io_flags & ZIO_FLAG_OPTIONAL))
}
if (stretch) {
- /* This may be a no-op. */
+ /*
+ * We are going to include an optional io in our aggregated
+ * span, thus closing the write gap. Only mandatory i/os can
+ * start aggregated spans, so make sure that the next i/o
+ * after our span is mandatory.
+ */
dio = AVL_NEXT(t, last);
dio->io_flags &= ~ZIO_FLAG_OPTIONAL;
} else {
+ /* do not include the optional i/o */
while (last != mandatory && last != first) {
ASSERT(last->io_flags & ZIO_FLAG_OPTIONAL);
last = AVL_PREV(t, last);
return (NULL);
size = IO_SPAN(first, last);
- ASSERT3U(size, <=, limit);
abd = abd_alloc_for_io(size, B_TRUE);
if (abd == NULL)