Add pread/pwrite support to sync engine
authorgurudas pai <gurudas.pai@oracle.com>
Tue, 23 Oct 2007 13:12:30 +0000 (15:12 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Tue, 23 Oct 2007 13:12:30 +0000 (15:12 +0200)
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
HOWTO
README
engines/sync.c
fio.1
options.c

diff --git a/HOWTO b/HOWTO
index 5d757b2d17f716d3b143171cf716d1c8fba6e2a0..24171e9b2f3ef7feeae341aa870155871726673c 100644 (file)
--- 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.
 
                        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.
                        libaio  Linux native asynchronous io.
 
                        posixaio glibc posix asynchronous io.
diff --git a/README b/README
index f713f73793d1ac321e098576a38dcc34e610b479..3ef13eaa1a36d1453561ebd1dc330948637eb8b1 100644 (file)
--- 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,
        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,
        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,
index 597ee0127a39d1a5d30f0609d366b3fb5d9230e7..3cd4e90ae4debe89bab56fe1e3be191e510832dc 100644 (file)
@@ -1,8 +1,8 @@
 /*
 /*
- * sync engine
+ * sync/psync engine
  *
  * IO engine that does regular read(2)/write(2) with lseek(2) to transfer
  *
  * 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 <stdio.h>
  *
  */
 #include <stdio.h>
@@ -13,6 +13,8 @@
 
 #include "../fio.h"
 
 
 #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;
 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);
 
 
        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) {
                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;
 }
 
        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,
        .name           = "sync",
        .version        = FIO_IOOPS_VERSION,
        .prep           = fio_syncio_prep,
@@ -69,12 +83,24 @@ static struct ioengine_ops ioengine = {
        .flags          = FIO_SYNCIO,
 };
 
        .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)
 {
 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)
 {
 }
 
 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 aacee101d0efa247eea771a19902496ab7284ff8..35056a8de58a35c15bbfc299d28f7d7b302ceb9c 100644 (file)
--- 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
 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
 .B libaio
 Linux native asynchronous I/O.
 .TP
index 82d5ff51b47f684be065d848f1493aac63f6dbad..e151634415bb5c2e64c8c318da18c560ce3692b8 100644 (file)
--- a/options.c
+++ b/options.c
@@ -336,6 +336,9 @@ static struct fio_option options[] = {
                          { .ival = "sync",
                            .help = "Use read/write",
                          },
                          { .ival = "sync",
                            .help = "Use read/write",
                          },
+                         { .ival = "psync",
+                           .help = "Use pread/pwrite",
+                         },
 #ifdef FIO_HAVE_LIBAIO
                          { .ival = "libaio",
                            .help = "Linux native asynchronous IO",
 #ifdef FIO_HAVE_LIBAIO
                          { .ival = "libaio",
                            .help = "Linux native asynchronous IO",