From 7101d9c24abec4be58a086d85d6d92ec6e6492e9 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 12 Sep 2007 13:12:39 +0200 Subject: [PATCH] Full readonly check Both in core and in engines. To the extent possible, this should catch even fio errors. Signed-off-by: Jens Axboe --- engines/guasi.c | 2 ++ engines/libaio.c | 2 ++ engines/mmap.c | 2 ++ engines/net.c | 2 ++ engines/null.c | 2 ++ engines/posixaio.c | 2 ++ engines/sg.c | 2 ++ engines/skeleton_external.c | 5 +++++ engines/splice.c | 2 ++ engines/sync.c | 2 ++ engines/syslet-rw.c | 2 ++ fio.h | 6 ++++++ ioengines.c | 6 ++++-- 13 files changed, 35 insertions(+), 2 deletions(-) diff --git a/engines/guasi.c b/engines/guasi.c index 7db09c30..69b2cd2a 100644 --- a/engines/guasi.c +++ b/engines/guasi.c @@ -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; + 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; diff --git a/engines/libaio.c b/engines/libaio.c index f8990c16..8f677115 100644 --- a/engines/libaio.c +++ b/engines/libaio.c @@ -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; + fio_ro_check(td, io_u); + if (ld->iocbs_nr == (int) td->o.iodepth) return FIO_Q_BUSY; diff --git a/engines/mmap.c b/engines/mmap.c index f3d55c16..604f8b09 100644 --- a/engines/mmap.c +++ b/engines/mmap.c @@ -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; + 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) diff --git a/engines/net.c b/engines/net.c index 0adc0064..552ad0bd 100644 --- a/engines/net.c +++ b/engines/net.c @@ -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; + fio_ro_check(td, io_u); + if (io_u->ddir == DDIR_WRITE) { if (nd->use_splice) ret = fio_netio_splice_out(td, io_u); diff --git a/engines/null.c b/engines/null.c index 823d40de..bbb4e8ab 100644 --- a/engines/null.c +++ b/engines/null.c @@ -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; + fio_ro_check(td, io_u); + if (td->io_ops->flags & FIO_SYNCIO) return FIO_Q_COMPLETED; if (nd->events) diff --git a/engines/posixaio.c b/engines/posixaio.c index 88ed4026..9ff05c49 100644 --- a/engines/posixaio.c +++ b/engines/posixaio.c @@ -148,6 +148,8 @@ static int fio_posixaio_queue(struct thread_data fio_unused *td, 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) diff --git a/engines/sg.c b/engines/sg.c index cc50d6b9..790019e1 100644 --- a/engines/sg.c +++ b/engines/sg.c @@ -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; + fio_ro_check(td, io_u); + ret = fio_sgio_doio(td, io_u, io_u->ddir == DDIR_SYNC); if (ret < 0) diff --git a/engines/skeleton_external.c b/engines/skeleton_external.c index 9000accf..26dbedf6 100644 --- a/engines/skeleton_external.c +++ b/engines/skeleton_external.c @@ -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) { + /* + * 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 diff --git a/engines/splice.c b/engines/splice.c index 440196b8..2344fddd 100644 --- a/engines/splice.c +++ b/engines/splice.c @@ -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; + fio_ro_check(td, io_u); + if (io_u->ddir == DDIR_READ) { if (sd->vmsplice_to_user) { ret = fio_splice_read(td, io_u); diff --git a/engines/sync.c b/engines/sync.c index ee8e3c36..597ee012 100644 --- a/engines/sync.c +++ b/engines/sync.c @@ -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; + 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) diff --git a/engines/syslet-rw.c b/engines/syslet-rw.c index 7e407d78..e0dddd87 100644 --- a/engines/syslet-rw.c +++ b/engines/syslet-rw.c @@ -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; + fio_ro_check(td, io_u); + 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 20d14082..1b392a03 100644 --- a/fio.h +++ b/fio.h @@ -13,6 +13,7 @@ #include #include #include +#include #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) +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) diff --git a/ioengines.c b/ioengines.c index 8e6fae22..cf8c2f14 100644 --- a/ioengines.c +++ b/ioengines.c @@ -157,6 +157,8 @@ void close_ioengine(struct thread_data *td) 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); @@ -182,13 +184,13 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u) { 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->ddir == DDIR_WRITE && !td_write(td))); - io_u->error = 0; io_u->resid = 0; -- 2.25.1