struct fio_sem;
+#define MAX_TRIM_RANGE 256
+
+/*
+ * Range for trim command
+ */
+struct trim_range {
+ unsigned long long start;
+ unsigned long long len;
+};
+
/*
* offset generator types
*/
FIO_RAND_POISSON3_OFF,
FIO_RAND_PRIO_CMDS,
FIO_RAND_DEDUPE_WORKING_SET_IX,
+ FIO_RAND_FDP_OFF,
FIO_RAND_NR_OFFS,
};
F_ADV_TYPE,
F_ADV_RANDOM,
F_ADV_SEQUENTIAL,
+ F_ADV_NOREUSE,
};
/*
struct frand_state bsrange_state[DDIR_RWDIR_CNT];
struct frand_state verify_state;
+ struct frand_state verify_state_last_do_io;
struct frand_state trim_state;
struct frand_state delay_state;
+ struct frand_state fdp_state;
struct frand_state buf_state;
struct frand_state buf_state_prev;
unsigned long long num_unique_pages;
struct zone_split_index **zone_state_index;
- unsigned int num_open_zones;
+ unsigned int num_write_zones;
unsigned int verify_batch;
unsigned int trim_batch;
* Issue side
*/
uint64_t io_issues[DDIR_RWDIR_CNT];
+ uint64_t verify_read_issues;
uint64_t io_issue_bytes[DDIR_RWDIR_CNT];
uint64_t loops;
uint64_t *thinktime_blocks_counter;
struct timespec last_thinktime;
- uint64_t last_thinktime_blocks;
+ int64_t last_thinktime_blocks;
/*
* State for random io, a bitmap of blocks done vs not done
struct timespec start; /* start of this loop */
struct timespec epoch; /* time job was started */
- unsigned long long alternate_epoch; /* Time job was started, clock_gettime's clock_id epoch based. */
+ unsigned long long alternate_epoch; /* Time job was started, as clock_gettime(log_alternate_epoch_clock_id) */
+ unsigned long long job_start; /* Time job was started, as clock_gettime(job_start_clock_id) */
struct timespec last_issue;
long time_offset;
struct timespec ts_cache;
!(io_u->ddir == DDIR_TRIM && !td_trim(td)));
}
+static inline bool multi_range_trim(struct thread_data *td, struct io_u *io_u)
+{
+ if (io_u->ddir == DDIR_TRIM && td->o.num_range > 1)
+ return true;
+
+ return false;
+}
+
static inline bool should_fsync(struct thread_data *td)
{
if (td->last_was_sync)
extern char *fio_option_dup_subs(const char *);
extern void fio_options_mem_dupe(struct thread_data *);
extern void td_fill_rand_seeds(struct thread_data *);
-extern void td_fill_verify_state_seed(struct thread_data *);
extern void add_job_opts(const char **, int);
extern int ioengine_load(struct thread_data *);
extern bool parse_dryrun(void);
/*
* Iterates all threads/processes within all the defined jobs
+ * Usage:
+ * for_each_td(var_name_for_td) {
+ * << bodoy of your loop >>
+ * Note: internally-scoped loop index availble as __td_index
+ * } end_for_each_td()
*/
-#define for_each_td(td, i) \
- for ((i) = 0, (td) = &segments[0].threads[0]; (i) < (int) thread_number; (i)++, (td) = tnumber_to_td((i)))
+#define for_each_td(td) \
+{ \
+ int __td_index; \
+ struct thread_data *(td); \
+ for (__td_index = 0, (td) = &segments[0].threads[0];\
+ __td_index < (int) thread_number; __td_index++, (td) = tnumber_to_td(__td_index))
+#define for_each_td_index() \
+{ \
+ int __td_index; \
+ for (__td_index = 0; __td_index < (int) thread_number; __td_index++)
+#define end_for_each() }
+
#define for_each_file(td, f, i) \
if ((td)->files_index) \
for ((i) = 0, (f) = (td)->files[0]; \