-
- while ((dio = AVL_PREV(tree, fio)) != NULL && IS_ADJACENT(dio, fio) &&
- !((dio->io_flags | fio->io_flags) & ZIO_FLAG_DONT_AGGREGATE) &&
- size + dio->io_size <= zfs_vdev_aggregation_limit) {
- dio->io_delegate_next = fio;
- fio = dio;
- size += dio->io_size;
- }
-
- while ((dio = AVL_NEXT(tree, lio)) != NULL && IS_ADJACENT(lio, dio) &&
- !((lio->io_flags | dio->io_flags) & ZIO_FLAG_DONT_AGGREGATE) &&
- size + dio->io_size <= zfs_vdev_aggregation_limit) {
- lio->io_delegate_next = dio;
- lio = dio;
- size += dio->io_size;
+ flags = fio->io_flags & ZIO_FLAG_AGG_INHERIT;
+
+ if (!(flags & ZIO_FLAG_DONT_AGGREGATE)) {
+ /*
+ * We can aggregate I/Os that are adjacent and of the
+ * same flavor, as expressed by the AGG_INHERIT flags.
+ * The latter is necessary so that certain attributes
+ * of the I/O, such as whether it's a normal I/O or a
+ * scrub/resilver, can be preserved in the aggregate.
+ */
+ while ((dio = AVL_PREV(tree, fio)) != NULL &&
+ IS_ADJACENT(dio, fio) &&
+ (dio->io_flags & ZIO_FLAG_AGG_INHERIT) == flags &&
+ size + dio->io_size <= zfs_vdev_aggregation_limit) {
+ dio->io_delegate_next = fio;
+ fio = dio;
+ size += dio->io_size;
+ }
+ while ((dio = AVL_NEXT(tree, lio)) != NULL &&
+ IS_ADJACENT(lio, dio) &&
+ (dio->io_flags & ZIO_FLAG_AGG_INHERIT) == flags &&
+ size + dio->io_size <= zfs_vdev_aggregation_limit) {
+ lio->io_delegate_next = dio;
+ lio = dio;
+ size += dio->io_size;
+ }