verify: fix verify issue with offest modifiers
authorAnkit Kumar <ankit.kumar@samsung.com>
Fri, 14 Feb 2025 19:48:34 +0000 (01:18 +0530)
committerVincent Fu <vincentfu@gmail.com>
Thu, 6 Mar 2025 18:58:43 +0000 (13:58 -0500)
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@samsung.com>
HOWTO.rst
fio.1
fio.h
init.c
iolog.c

index fb6dddcfdd43592f40951afa2667c4175b64a977..bde3496e1b5b2089f7da7479e0a35bb9f745a3f8 100644 (file)
--- 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 83e77678072e20865d2b978c260a7fadf89d6cfd..0ea239b828c64e5185061063150cae2b1e87bb7a 100644 (file)
--- 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 b8cf3229ef513e998aa88b40576d5afd71467785..c7c0d147c4dbb6b1591ab3645e21277f2fb9cf72 100644 (file)
--- 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 bf257ea1687be43abfb37de1718c9082c197883d..feaa3f28435b3a1d15aafc6935149c4a9239e87c 100644 (file)
--- 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 ef173b092947fd4aad54f8b583af9a27f7526a76..6b5dc9abbae051f1aeb47365d19ea6ea3d67d763 100644 (file)
--- 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;