+ /*
+ * now file sizes are known, so we can set ->io_size. if size= is
+ * not given, ->io_size is just equal to ->real_file_size. if size
+ * is given, ->io_size is size / nr_files.
+ */
+ extend_size = total_size = 0;
+ need_extend = 0;
+ for_each_file(td, f, i) {
+ f->file_offset = get_start_offset(td);
+
+ if (!o->file_size_low) {
+ /*
+ * no file size range given, file size is equal to
+ * total size divided by number of files. if that is
+ * zero, set it to the real file size.
+ */
+ f->io_size = o->size / o->nr_files;
+ if (!f->io_size)
+ f->io_size = f->real_file_size - f->file_offset;
+ } else if (f->real_file_size < o->file_size_low ||
+ f->real_file_size > o->file_size_high) {
+ if (f->file_offset > o->file_size_low)
+ goto err_offset;
+ /*
+ * file size given. if it's fixed, use that. if it's a
+ * range, generate a random size in-between.
+ */
+ if (o->file_size_low == o->file_size_high)
+ f->io_size = o->file_size_low - f->file_offset;
+ else {
+ f->io_size = get_rand_file_size(td)
+ - f->file_offset;
+ }
+ } else
+ f->io_size = f->real_file_size - f->file_offset;
+
+ if (f->io_size == -1ULL)
+ total_size = -1ULL;
+ else {
+ if (o->size_percent)
+ f->io_size = (f->io_size * o->size_percent) / 100;
+ total_size += f->io_size;
+ }
+
+ if (f->filetype == FIO_TYPE_FILE &&
+ (f->io_size + f->file_offset) > f->real_file_size &&
+ !(td->io_ops->flags & FIO_DISKLESSIO)) {
+ if (!o->create_on_open) {
+ need_extend++;
+ extend_size += (f->io_size + f->file_offset);
+ } else
+ f->real_file_size = f->io_size + f->file_offset;
+ fio_file_set_extend(f);
+ }
+ }
+
+ if (!o->size || o->size > total_size)
+ o->size = total_size;
+
+ /*
+ * See if we need to extend some files
+ */
+ if (need_extend) {
+ temp_stall_ts = 1;
+ if (output_format == FIO_OUTPUT_NORMAL)
+ log_info("%s: Laying out IO file(s) (%u file(s) /"
+ " %lluMB)\n", o->name, need_extend,
+ extend_size >> 20);
+
+ for_each_file(td, f, i) {
+ unsigned long long old_len = -1ULL, extend_len = -1ULL;
+
+ if (!fio_file_extend(f))
+ continue;
+
+ assert(f->filetype == FIO_TYPE_FILE);
+ fio_file_clear_extend(f);
+ if (!o->fill_device) {
+ old_len = f->real_file_size;
+ extend_len = f->io_size + f->file_offset -
+ old_len;
+ }
+ f->real_file_size = (f->io_size + f->file_offset);
+ err = extend_file(td, f);
+ if (err)
+ break;
+
+ err = __file_invalidate_cache(td, f, old_len,
+ extend_len);
+ close(f->fd);
+ f->fd = -1;
+ if (err)
+ break;
+ }
+ temp_stall_ts = 0;
+ }
+
+ if (err)
+ goto err_out;
+
+ if (!o->zone_size)
+ o->zone_size = o->size;
+
+ /*
+ * iolog already set the total io size, if we read back
+ * stored entries.
+ */
+ if (!o->read_iolog_file)
+ td->total_io_size = o->size * o->loops;
+
+done:
+ if (o->create_only)
+ td->done = 1;
+
+ td_set_runstate(td, old_state);
+ return 0;
+err_offset:
+ log_err("%s: you need to specify valid offset=\n", o->name);
+err_out:
+ td_set_runstate(td, old_state);
+ return 1;
+}
+
+int pre_read_files(struct thread_data *td)
+{
+ struct fio_file *f;
+ unsigned int i;