Fix failure to verify in mixed read/write workload with backlog
authorJens Axboe <axboe@kernel.dk>
Tue, 13 Mar 2012 12:45:58 +0000 (13:45 +0100)
committerJens Axboe <axboe@kernel.dk>
Tue, 13 Mar 2012 12:49:36 +0000 (13:49 +0100)
If you run a workload like this:

fio --rw=randrw --bs=4k --direct=1 --ioengine=libaio --iodepth=32
--verify=meta --verify_backlog=1024 --verify_fatal=1 --name=ver-test
--filename=foo --size=1G --verify_pattern=0xaaa

Fio ends up never actually verifying the written blocks. This happens
because as we generate an entry to be verified, the backend checks
whether this is a read/write mixed workload. It then thinks that the
READ is just that, a normal READ, when in fact it could be coming
from our verify list.

Mark such a read as coming from our verify list, so that we know if
it's a "normal" read or one generated to verify previously written
data.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
backend.c
io_u.c
ioengine.h
verify.c

index 814d244cadf241028efdf268692201ce6c9a84aa..7343286d53219b0c8d4e8a44ec586f1cd66ac6b8 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -586,11 +586,12 @@ static void do_io(struct thread_data *td)
                ddir = io_u->ddir;
 
                /*
-                * Add verification end_io handler, if asked to verify
-                * a previously written file.
+                * Add verification end_io handler if:
+                *      - Asked to verify (!td_rw(td))
+                *      - Or the io_u is from our verify list (mixed write/ver)
                 */
                if (td->o.verify != VERIFY_NONE && io_u->ddir == DDIR_READ &&
-                   !td_rw(td)) {
+                   ((io_u->flags & IO_U_F_VER_LIST) || !td_rw(td))) {
                        if (td->o.verify_async)
                                io_u->end_io = verify_io_u_async;
                        else
diff --git a/io_u.c b/io_u.c
index a0020d27b427e9bc21b184238898ac89bddd1e0c..20794c38a88c5d9bea08d50f8865fe398576a235 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -1070,6 +1070,7 @@ again:
                assert(io_u->flags & IO_U_F_FREE);
                io_u->flags &= ~(IO_U_F_FREE | IO_U_F_FREE_DEF);
                io_u->flags &= ~(IO_U_F_TRIMMED | IO_U_F_BARRIER);
+               io_u->flags &= ~IO_U_F_VER_LIST;
 
                io_u->error = 0;
                flist_del(&io_u->list);
index efca45e2744fd6222cb0b516be793371293dc33e..61cb396f5e0e792f87b862976a426695338e524b 100644 (file)
@@ -11,6 +11,7 @@ enum {
        IO_U_F_BUSY_OK          = 1 << 4,
        IO_U_F_TRIMMED          = 1 << 5,
        IO_U_F_BARRIER          = 1 << 6,
+       IO_U_F_VER_LIST         = 1 << 7,
 };
 
 /*
index 6dd7f6a0285df0613d15d6590f9a604e90cd6b49..f25eab921fc379691466b9e8c3866efd3a2133eb 100644 (file)
--- a/verify.c
+++ b/verify.c
@@ -973,6 +973,7 @@ int get_next_verify(struct thread_data *td, struct io_u *io_u)
                io_u->offset = ipo->offset;
                io_u->buflen = ipo->len;
                io_u->file = ipo->file;
+               io_u->flags |= IO_U_F_VER_LIST;
 
                if (ipo->flags & IP_F_TRIMMED)
                        io_u->flags |= IO_U_F_TRIMMED;