+static int fill_multi_range_io_u(struct thread_data *td, struct io_u *io_u)
+{
+ bool is_random;
+ uint64_t buflen, i = 0;
+ struct trim_range *range;
+ struct fio_file *f = io_u->file;
+ uint8_t *buf;
+
+ buf = io_u->buf;
+ buflen = 0;
+
+ while (i < td->o.num_range) {
+ range = (struct trim_range *)buf;
+ if (get_next_offset(td, io_u, &is_random)) {
+ dprint(FD_IO, "io_u %p, failed getting offset\n",
+ io_u);
+ break;
+ }
+
+ io_u->buflen = get_next_buflen(td, io_u, is_random);
+ if (!io_u->buflen) {
+ dprint(FD_IO, "io_u %p, failed getting buflen\n", io_u);
+ break;
+ }
+
+ if (io_u->offset + io_u->buflen > io_u->file->real_file_size) {
+ dprint(FD_IO, "io_u %p, off=0x%llx + len=0x%llx exceeds file size=0x%llx\n",
+ io_u,
+ (unsigned long long) io_u->offset, io_u->buflen,
+ (unsigned long long) io_u->file->real_file_size);
+ break;
+ }
+
+ range->start = io_u->offset;
+ range->len = io_u->buflen;
+ buflen += io_u->buflen;
+ f->last_start[io_u->ddir] = io_u->offset;
+ f->last_pos[io_u->ddir] = io_u->offset + range->len;
+
+ buf += sizeof(struct trim_range);
+ i++;
+
+ if (td_random(td) && file_randommap(td, io_u->file))
+ mark_random_map(td, io_u, io_u->offset, io_u->buflen);
+ dprint_io_u(io_u, "fill");
+ }
+ if (buflen) {
+ /*
+ * Set buffer length as overall trim length for this IO, and
+ * tell the ioengine about the number of ranges to be trimmed.
+ */
+ io_u->buflen = buflen;
+ io_u->number_trim = i;
+ return 0;
+ }
+
+ return 1;
+}
+