Offset modifiers such as rw=readwrite:8 or rw=write:4K can create overlaps. For these cases use RB tree instead of list to log the I/O entries. Add a helper function fio_offset_overlap_risk() to decide whether to log the I/O entry in an RB tree or a list. Disable header seed verification if there are offset modifiers, unless its explicitly enabled. fixes #1503 Signed-off-by: Ankit Kumar <ankit.kumar@xxxxxxxxxxx> --- HOWTO.rst | 4 +++- fio.1 | 4 +++- fio.h | 8 ++++++++ init.c | 6 ++++-- iolog.c | 9 +++++---- 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/HOWTO.rst b/HOWTO.rst index 4293c03c..bb5da1cc 100644 --- a/HOWTO.rst +++ b/HOWTO.rst @@ -1185,7 +1185,9 @@ I/O type pattern, then the *<nr>* value specified will be **added** to the generated offset for each I/O turning sequential I/O into sequential I/O with holes. For instance, using ``rw=write:4k`` will skip 4k for every write. Also see - the :option:`rw_sequencer` option. + the :option:`rw_sequencer` option. If this is used with :option:`verify` + then :option:`verify_header_seed` will be disabled, unless its explicitly + enabled. .. option:: rw_sequencer=str diff --git a/fio.1 b/fio.1 index a0f204c0..4755ca19 100644 --- a/fio.1 +++ b/fio.1 @@ -955,7 +955,9 @@ modifier with a value of 8. If the suffix is used with a sequential I/O pattern, then the `<nr>' value specified will be added to the generated offset for each I/O turning sequential I/O into sequential I/O with holes. For instance, using `rw=write:4k' will skip 4k for every write. Also see -the \fBrw_sequencer\fR option. +the \fBrw_sequencer\fR option. If this is used with \fBverify\fR then +\fBverify_header_seed\fR option will be disabled, unless its explicitly +enabled. .RE .TP .BI rw_sequencer \fR=\fPstr diff --git a/fio.h b/fio.h index b8cf3229..c7c0d147 100644 --- a/fio.h +++ b/fio.h @@ -800,6 +800,14 @@ extern void lat_target_reset(struct thread_data *); (i) < (td)->o.nr_files && ((f) = (td)->files[i]) != NULL; \ (i)++) +static inline bool fio_offset_overlap_risk(struct thread_data *td) +{ + if (td->o.ddir_seq_add || (td->o.ddir_seq_nr > 1)) + return true; + + return false; +} + static inline bool fio_fill_issue_time(struct thread_data *td) { if (td->o.read_iolog_file || diff --git a/init.c b/init.c index bf257ea1..feaa3f28 100644 --- a/init.c +++ b/init.c @@ -886,11 +886,13 @@ static int fixup_options(struct thread_data *td) /* * Disable rand_seed check when we have verify_backlog, - * zone reset frequency for zonemode=zbd, or norandommap. + * zone reset frequency for zonemode=zbd, norandommap, or + * offset modifiers. * Unless we were explicitly asked to enable it. */ if (!td_write(td) || (td->flags & TD_F_VER_BACKLOG) || - o->zrf.u.f || o->norandommap) { + o->zrf.u.f || o->norandommap || + fio_offset_overlap_risk(td)) { if (!fio_option_is_set(o, verify_header_seed)) o->verify_header_seed = 0; } diff --git a/iolog.c b/iolog.c index ef173b09..6b5dc9ab 100644 --- a/iolog.c +++ b/iolog.c @@ -301,11 +301,12 @@ void log_io_piece(struct thread_data *td, struct io_u *io_u) } /* - * Only sort writes if we don't have a random map in which case we need - * to check for duplicate blocks and drop the old one, which we rely on - * the rb insert/lookup for handling. + * Sort writes if we don't have a random map in which case we need to + * check for duplicate blocks and drop the old one, which we rely on + * the rb insert/lookup for handling. Sort writes if we have offset + * modifier which can also create duplicate blocks. */ - if (file_randommap(td, ipo->file)) { + if (file_randommap(td, ipo->file) && !fio_offset_overlap_risk(td)) { INIT_FLIST_HEAD(&ipo->list); flist_add_tail(&ipo->list, &td->io_hist_list); ipo->flags |= IP_F_ONLIST; -- 2.25.1