+ if (td->io_ops->option_struct_size && td->io_ops->options) {
+ /*
+ * In cases where td->eo is set, clone it for a child thread.
+ * This requires that the parent thread has the same ioengine,
+ * but that requirement must be enforced by the code which
+ * cloned the thread.
+ */
+ void *origeo = td->eo;
+ /*
+ * Otherwise use the default thread options.
+ */
+ if (!origeo && td != &def_thread && def_thread.eo &&
+ def_thread.io_ops->options == td->io_ops->options)
+ origeo = def_thread.eo;
+
+ options_init(td->io_ops->options);
+ td->eo = malloc(td->io_ops->option_struct_size);
+ /*
+ * Use the default thread as an option template if this uses the
+ * same options structure and there are non-default options
+ * used.
+ */
+ if (origeo) {
+ memcpy(td->eo, origeo, td->io_ops->option_struct_size);
+ options_mem_dupe(td->eo, td->io_ops->options);
+ } else {
+ memset(td->eo, 0, td->io_ops->option_struct_size);
+ fill_default_options(td->eo, td->io_ops->options);
+ }
+ *(struct thread_data **)td->eo = td;
+ }
+
+ return 0;
+}
+
+static void init_flags(struct thread_data *td)
+{
+ struct thread_options *o = &td->o;
+
+ if (o->verify_backlog)
+ td->flags |= TD_F_VER_BACKLOG;
+ if (o->trim_backlog)
+ td->flags |= TD_F_TRIM_BACKLOG;
+ if (o->read_iolog_file)
+ td->flags |= TD_F_READ_IOLOG;
+ if (o->refill_buffers)
+ td->flags |= TD_F_REFILL_BUFFERS;
+ if (o->scramble_buffers)
+ td->flags |= TD_F_SCRAMBLE_BUFFERS;
+ if (o->verify != VERIFY_NONE)
+ td->flags |= TD_F_VER_NONE;
+}
+
+static int setup_random_seeds(struct thread_data *td)
+{
+ unsigned long seed;
+ unsigned int i;
+
+ if (!td->o.rand_repeatable)
+ return init_random_state(td, td->rand_seeds, sizeof(td->rand_seeds));
+
+ for (seed = 0x89, i = 0; i < 4; i++)
+ seed *= 0x9e370001UL;
+
+ for (i = 0; i < FIO_RAND_NR_OFFS; i++) {
+ td->rand_seeds[i] = seed;
+ seed *= 0x9e370001UL;