randtrimwrite: fix offsets for corner case
[fio.git] / io_u.c
diff --git a/io_u.c b/io_u.c
index 3f6c60ee887ef0e3aa74908fb73d0ddc36f32fbd..2c37720f05b6873c6b35c0747b3b67bf80e0099f 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -513,6 +513,24 @@ static int get_next_offset(struct thread_data *td, struct io_u *io_u,
                return 1;
        }
 
+       /*
+        * For randtrimwrite, we decide whether to issue a trim or a write
+        * based on whether the offsets for the most recent trim and write
+        * operations match. If they don't match that means we just issued a
+        * new trim and the next operation should be a write. If they *do*
+        * match that means we just completed a trim+write pair and the next
+        * command should be a trim.
+        *
+        * This works fine for sequential workloads but for random workloads
+        * it's possible to complete a trim+write pair and then have the next
+        * randomly generated offset match the previous offset. If that happens
+        * we need to alter the offset for the last write operation in order
+        * to ensure that we issue a write operation the next time through.
+        */
+       if (td_randtrimwrite(td) && ddir == DDIR_TRIM &&
+           f->last_start[DDIR_TRIM] == io_u->offset)
+               f->last_pos[DDIR_WRITE]--;
+
        io_u->verify_offset = io_u->offset;
        return 0;
 }