From a31041eaf5a306b5f6ad3dd14b60da6212775037 Mon Sep 17 00:00:00 2001 From: gurudas pai Date: Tue, 23 Oct 2007 15:12:30 +0200 Subject: [PATCH] Add pread/pwrite support to sync engine Signed-off-by: Jens Axboe --- HOWTO | 2 ++ README | 15 ++++++++------- engines/sync.c | 46 ++++++++++++++++++++++++++++++++++++---------- fio.1 | 3 +++ options.c | 3 +++ 5 files changed, 52 insertions(+), 17 deletions(-) diff --git a/HOWTO b/HOWTO index 5d757b2d..24171e9b 100644 --- a/HOWTO +++ b/HOWTO @@ -314,6 +314,8 @@ ioengine=str Defines how the job issues io to the file. The following sync Basic read(2) or write(2) io. lseek(2) is used to position the io location. + psync Basic pread(2) or pwrite(2) io. + libaio Linux native asynchronous io. posixaio glibc posix asynchronous io. diff --git a/README b/README index f713f737..3ef13eaa 100644 --- a/README +++ b/README @@ -120,13 +120,14 @@ The job file parameters are: size=x Set file size to x bytes (x string can include k/m/g) ioengine=x 'x' may be: aio/libaio/linuxaio for Linux aio, posixaio for POSIX aio, sync for regular read/write io, - mmap for mmap'ed io, syslet-rw for syslet driven - read/write, splice for using splice/vmsplice, - sgio for direct SG_IO io, net for network io, or cpuio - for a cycler burner load. sgio only works on Linux on - SCSI (or SCSI-like devices, such as usb-storage or - sata/libata driven) devices. Fio also has a null io - engine, which is mainly used for testing fio itself. + psync for regular pread/pwrite io, mmap for mmap'ed io, + syslet-rw for syslet driven read/write, splice for using + splice/vmsplice, sgio for direct SG_IO io, net for + network io, or cpuio for a cycler burner load. sgio only + works on Linux on SCSI (or SCSI-like devices, such as + usb-storage or sata/libata driven) devices. Fio also has + a null io engine, which is mainly used for testing fio + itself. iodepth=x For async io, allow 'x' ios in flight overwrite=x If 'x', layout a write file first. nrfiles=x Spread io load over 'x' number of files per job, diff --git a/engines/sync.c b/engines/sync.c index 597ee012..3cd4e90a 100644 --- a/engines/sync.c +++ b/engines/sync.c @@ -1,8 +1,8 @@ /* - * sync engine + * sync/psync engine * * IO engine that does regular read(2)/write(2) with lseek(2) to transfer - * data. + * data and IO engine that does regular pread(2)/pwrite(2) to transfer data. * */ #include @@ -13,6 +13,8 @@ #include "../fio.h" +#define is_psync(td) ((td)->io_ops->data == (void *) 1) + static int fio_syncio_prep(struct thread_data *td, struct io_u *io_u) { struct fio_file *f = io_u->file; @@ -37,11 +39,17 @@ static int fio_syncio_queue(struct thread_data *td, struct io_u *io_u) 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) - ret = write(f->fd, io_u->xfer_buf, io_u->xfer_buflen); - else + if (io_u->ddir == DDIR_READ) { + if (is_psync(td)) + ret = pread(f->fd, io_u->xfer_buf, io_u->xfer_buflen,io_u->offset); + else + ret = read(f->fd, io_u->xfer_buf, io_u->xfer_buflen); + } else if (io_u->ddir == DDIR_WRITE) { + if (is_psync(td)) + ret = pwrite(f->fd, io_u->xfer_buf, io_u->xfer_buflen,io_u->offset); + else + ret = write(f->fd, io_u->xfer_buf, io_u->xfer_buflen); + } else ret = fsync(f->fd); if (ret != (int) io_u->xfer_buflen) { @@ -59,7 +67,13 @@ static int fio_syncio_queue(struct thread_data *td, struct io_u *io_u) return FIO_Q_COMPLETED; } -static struct ioengine_ops ioengine = { +static int fio_psyncio_init(struct thread_data *td) +{ + td->io_ops->data = (void *) 1; + return 0; +} + +static struct ioengine_ops ioengine_rw = { .name = "sync", .version = FIO_IOOPS_VERSION, .prep = fio_syncio_prep, @@ -69,12 +83,24 @@ static struct ioengine_ops ioengine = { .flags = FIO_SYNCIO, }; +static struct ioengine_ops ioengine_prw = { + .name = "psync", + .version = FIO_IOOPS_VERSION, + .queue = fio_syncio_queue, + .init = fio_psyncio_init, + .open_file = generic_open_file, + .close_file = generic_close_file, + .flags = FIO_SYNCIO, +}; + static void fio_init fio_syncio_register(void) { - register_ioengine(&ioengine); + register_ioengine(&ioengine_rw); + register_ioengine(&ioengine_prw); } static void fio_exit fio_syncio_unregister(void) { - unregister_ioengine(&ioengine); + unregister_ioengine(&ioengine_rw); + unregister_ioengine(&ioengine_prw); } diff --git a/fio.1 b/fio.1 index aacee101..35056a8d 100644 --- a/fio.1 +++ b/fio.1 @@ -209,6 +209,9 @@ Defines how the job issues I/O. The following types are defined: Basic \fIread\fR\|(2) or \fIwrite\fR\|(2) I/O. \fIfseek\fR\|(2) is used to position the I/O location. .TP +.B psync +Basic \fIpread\fR\|(2) or \fIpwrite\fR\|(2) I/O. +.TP .B libaio Linux native asynchronous I/O. .TP diff --git a/options.c b/options.c index 82d5ff51..e1516344 100644 --- a/options.c +++ b/options.c @@ -336,6 +336,9 @@ static struct fio_option options[] = { { .ival = "sync", .help = "Use read/write", }, + { .ival = "psync", + .help = "Use pread/pwrite", + }, #ifdef FIO_HAVE_LIBAIO { .ival = "libaio", .help = "Linux native asynchronous IO", -- 2.25.1