Full readonly check
authorJens Axboe <jens.axboe@oracle.com>
Wed, 12 Sep 2007 11:12:39 +0000 (13:12 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Wed, 12 Sep 2007 11:12:39 +0000 (13:12 +0200)
Both in core and in engines. To the extent possible, this should catch
even fio errors.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
13 files changed:
engines/guasi.c
engines/libaio.c
engines/mmap.c
engines/net.c
engines/null.c
engines/posixaio.c
engines/sg.c
engines/skeleton_external.c
engines/splice.c
engines/sync.c
engines/syslet-rw.c
fio.h
ioengines.c

index 7db09c30465c05b3763d223afbda4bb37aa9eb3b..69b2cd2a7f2435e692361cf2d437aff8ea9105eb 100644 (file)
@@ -124,6 +124,8 @@ static int fio_guasi_queue(struct thread_data *td, struct io_u *io_u)
 {
        struct guasi_data *ld = td->io_ops->data;
 
 {
        struct guasi_data *ld = td->io_ops->data;
 
+       fio_ro_check(td, io_u);
+
        GDBG_PRINT(("fio_guasi_queue(%p)\n", io_u));
        if (ld->queued_nr == (int) td->o.iodepth)
                return FIO_Q_BUSY;
        GDBG_PRINT(("fio_guasi_queue(%p)\n", io_u));
        if (ld->queued_nr == (int) td->o.iodepth)
                return FIO_Q_BUSY;
index f8990c1601ba801309d69e7ef84ceb7bfbfcd71c..8f677115056d2e922bda4eaa5f766423db07b6ec 100644 (file)
@@ -86,6 +86,8 @@ static int fio_libaio_queue(struct thread_data *td, struct io_u *io_u)
 {
        struct libaio_data *ld = td->io_ops->data;
 
 {
        struct libaio_data *ld = td->io_ops->data;
 
+       fio_ro_check(td, io_u);
+
        if (ld->iocbs_nr == (int) td->o.iodepth)
                return FIO_Q_BUSY;
 
        if (ld->iocbs_nr == (int) td->o.iodepth)
                return FIO_Q_BUSY;
 
index f3d55c167691616a9d6478dba51e51154475ff3f..604f8b0902e75d9c0af70eca7ad8996b4c77f57d 100644 (file)
@@ -19,6 +19,8 @@ static int fio_mmapio_queue(struct thread_data *td, struct io_u *io_u)
        struct fio_file *f = io_u->file;
        unsigned long long real_off = io_u->offset - f->file_offset;
 
        struct fio_file *f = io_u->file;
        unsigned long long real_off = io_u->offset - f->file_offset;
 
+       fio_ro_check(td, io_u);
+
        if (io_u->ddir == DDIR_READ)
                memcpy(io_u->xfer_buf, f->mmap + real_off, io_u->xfer_buflen);
        else if (io_u->ddir == DDIR_WRITE)
        if (io_u->ddir == DDIR_READ)
                memcpy(io_u->xfer_buf, f->mmap + real_off, io_u->xfer_buflen);
        else if (io_u->ddir == DDIR_WRITE)
index 0adc00647ed3fd1dea23875b3fbbdc6e27784707..552ad0bdb551abebb68f26571df5dc5e2ad20b8f 100644 (file)
@@ -198,6 +198,8 @@ static int fio_netio_queue(struct thread_data *td, struct io_u *io_u)
        struct netio_data *nd = td->io_ops->data;
        int ret;
 
        struct netio_data *nd = td->io_ops->data;
        int ret;
 
+       fio_ro_check(td, io_u);
+
        if (io_u->ddir == DDIR_WRITE) {
                if (nd->use_splice)
                        ret = fio_netio_splice_out(td, io_u);
        if (io_u->ddir == DDIR_WRITE) {
                if (nd->use_splice)
                        ret = fio_netio_splice_out(td, io_u);
index 823d40def272c820a2d635b994483af94a61b014..bbb4e8ab9a89521516694e14dc9dd7ea00e7f584 100644 (file)
@@ -56,6 +56,8 @@ static int fio_null_queue(struct thread_data fio_unused *td, struct io_u *io_u)
 {
        struct null_data *nd = td->io_ops->data;
 
 {
        struct null_data *nd = td->io_ops->data;
 
+       fio_ro_check(td, io_u);
+
        if (td->io_ops->flags & FIO_SYNCIO)
                return FIO_Q_COMPLETED;
        if (nd->events)
        if (td->io_ops->flags & FIO_SYNCIO)
                return FIO_Q_COMPLETED;
        if (nd->events)
index 88ed40266390a0b0e2d88420f3aef595a6fa7a10..9ff05c4914151387dae188d4c8798c7c3d0985c0 100644 (file)
@@ -148,6 +148,8 @@ static int fio_posixaio_queue(struct thread_data fio_unused *td,
        struct aiocb *aiocb = &io_u->aiocb;
        int ret;
 
        struct aiocb *aiocb = &io_u->aiocb;
        int ret;
 
+       fio_ro_check(td, io_u);
+
        if (io_u->ddir == DDIR_READ)
                ret = aio_read(aiocb);
        else if (io_u->ddir == DDIR_WRITE)
        if (io_u->ddir == DDIR_READ)
                ret = aio_read(aiocb);
        else if (io_u->ddir == DDIR_WRITE)
index cc50d6b937e747009b39d1651ab279800ee8a446..790019e1d57fa48e7a635cecdc47dd5b6835cba3 100644 (file)
@@ -242,6 +242,8 @@ static int fio_sgio_queue(struct thread_data *td, struct io_u *io_u)
        struct sg_io_hdr *hdr = &io_u->hdr;
        int ret;
 
        struct sg_io_hdr *hdr = &io_u->hdr;
        int ret;
 
+       fio_ro_check(td, io_u);
+
        ret = fio_sgio_doio(td, io_u, io_u->ddir == DDIR_SYNC);
 
        if (ret < 0)
        ret = fio_sgio_doio(td, io_u, io_u->ddir == DDIR_SYNC);
 
        if (ret < 0)
index 9000accf5e2d639f28f533993fed775519d3d2da..26dbedf6b9b4ad9ef506aad138c185cf49f8ef81 100644 (file)
@@ -64,6 +64,11 @@ static int fio_skeleton_cancel(struct thread_data *td, struct io_u *io_u)
  */
 static int fio_skeleton_queue(struct thread_data *td, struct io_u *io_u)
 {
  */
 static int fio_skeleton_queue(struct thread_data *td, struct io_u *io_u)
 {
+       /*
+        * Double sanity check to catch errant write on a readonly setup
+        */
+       fio_ro_check(td, io_u);
+
        /*
         * Could return FIO_Q_QUEUED for a queued request,
         * FIO_Q_COMPLETED for a completed request, and FIO_Q_BUSY
        /*
         * Could return FIO_Q_QUEUED for a queued request,
         * FIO_Q_COMPLETED for a completed request, and FIO_Q_BUSY
index 440196b8a16e485e530e06b9f8694c8c7d702d4b..2344fddd3be30b2192f4ea1e4d1b921a8baebd70 100644 (file)
@@ -185,6 +185,8 @@ static int fio_spliceio_queue(struct thread_data *td, struct io_u *io_u)
        struct spliceio_data *sd = td->io_ops->data;
        int ret;
 
        struct spliceio_data *sd = td->io_ops->data;
        int ret;
 
+       fio_ro_check(td, io_u);
+
        if (io_u->ddir == DDIR_READ) {
                if (sd->vmsplice_to_user) {
                        ret = fio_splice_read(td, io_u);
        if (io_u->ddir == DDIR_READ) {
                if (sd->vmsplice_to_user) {
                        ret = fio_splice_read(td, io_u);
index ee8e3c367360166b7f95b312988ff89c07b5e09e..597ee0127a39d1a5d30f0609d366b3fb5d9230e7 100644 (file)
@@ -35,6 +35,8 @@ static int fio_syncio_queue(struct thread_data *td, struct io_u *io_u)
        struct fio_file *f = io_u->file;
        int ret;
 
        struct fio_file *f = io_u->file;
        int ret;
 
+       fio_ro_check(td, io_u);
+
        if (io_u->ddir == DDIR_READ)
                ret = read(f->fd, io_u->xfer_buf, io_u->xfer_buflen);
        else if (io_u->ddir == DDIR_WRITE)
        if (io_u->ddir == DDIR_READ)
                ret = read(f->fd, io_u->xfer_buf, io_u->xfer_buflen);
        else if (io_u->ddir == DDIR_WRITE)
index 7e407d785bfbcbb73125214d48e88d1bbd679c9f..e0dddd8761268487c8ce15f2c000a4cd8603e18a 100644 (file)
@@ -253,6 +253,8 @@ static int fio_syslet_queue(struct thread_data *td, struct io_u *io_u)
 {
        struct syslet_data *sd = td->io_ops->data;
 
 {
        struct syslet_data *sd = td->io_ops->data;
 
+       fio_ro_check(td, io_u);
+
        if (sd->tail) {
                sd->tail->next = &io_u->req.atom;
                sd->tail = &io_u->req.atom;
        if (sd->tail) {
                sd->tail->next = &io_u->req.atom;
                sd->tail = &io_u->req.atom;
diff --git a/fio.h b/fio.h
index 20d14082d3281b03e44f04823de5f714a81f65da..1b392a0372b0ddbe60984eefc1cc09b60180ffc4 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -13,6 +13,7 @@
 #include <string.h>
 #include <getopt.h>
 #include <inttypes.h>
 #include <string.h>
 #include <getopt.h>
 #include <inttypes.h>
+#include <assert.h>
 
 #include "compiler/compiler.h"
 #include "list.h"
 
 #include "compiler/compiler.h"
 #include "list.h"
@@ -670,6 +671,11 @@ extern struct thread_data *threads;
 #define td_rw(td)              (((td)->o.td_ddir & TD_DDIR_RW) == TD_DDIR_RW)
 #define td_random(td)          ((td)->o.td_ddir & TD_DDIR_RAND)
 
 #define td_rw(td)              (((td)->o.td_ddir & TD_DDIR_RW) == TD_DDIR_RW)
 #define td_random(td)          ((td)->o.td_ddir & TD_DDIR_RAND)
 
+static inline void fio_ro_check(struct thread_data *td, struct io_u *io_u)
+{
+       assert(!(io_u->ddir == DDIR_WRITE && !td_write(td)));
+}
+
 #define BLOCKS_PER_MAP         (8 * sizeof(long))
 #define TO_MAP_BLOCK(td, f, b) ((b) - ((f)->file_offset / (td)->o.rw_min_bs))
 #define RAND_MAP_IDX(td, f, b) (TO_MAP_BLOCK(td, f, b) / BLOCKS_PER_MAP)
 #define BLOCKS_PER_MAP         (8 * sizeof(long))
 #define TO_MAP_BLOCK(td, f, b) ((b) - ((f)->file_offset / (td)->o.rw_min_bs))
 #define RAND_MAP_IDX(td, f, b) (TO_MAP_BLOCK(td, f, b) / BLOCKS_PER_MAP)
index 8e6fae2267bdc2340fa82453ef65bab3335615ab..cf8c2f148ca8df611c2817e854cf43ace609f56a 100644 (file)
@@ -157,6 +157,8 @@ void close_ioengine(struct thread_data *td)
 
 int td_io_prep(struct thread_data *td, struct io_u *io_u)
 {
 
 int td_io_prep(struct thread_data *td, struct io_u *io_u)
 {
+       fio_ro_check(td, io_u);
+
        if (td->io_ops->prep)
                return td->io_ops->prep(td, io_u);
 
        if (td->io_ops->prep)
                return td->io_ops->prep(td, io_u);
 
@@ -182,13 +184,13 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u)
 {
        int ret;
 
 {
        int ret;
 
+       fio_ro_check(td, io_u);
+
        assert((io_u->flags & IO_U_F_FLIGHT) == 0);
        io_u->flags |= IO_U_F_FLIGHT;
 
        assert(io_u->file->flags & FIO_FILE_OPEN);
 
        assert((io_u->flags & IO_U_F_FLIGHT) == 0);
        io_u->flags |= IO_U_F_FLIGHT;
 
        assert(io_u->file->flags & FIO_FILE_OPEN);
 
-       assert(!(io_u->ddir == DDIR_WRITE && !td_write(td)));
-
        io_u->error = 0;
        io_u->resid = 0;
 
        io_u->error = 0;
        io_u->resid = 0;