[PATCH] fio: support sync operation with sgio ioengine
authorJens Axboe <axboe@suse.de>
Thu, 8 Dec 2005 10:17:52 +0000 (11:17 +0100)
committerJens Axboe <axboe@suse.de>
Thu, 8 Dec 2005 10:17:52 +0000 (11:17 +0100)
fio-io.c
fio.c
fio.h

index 3c8663916389df0e8d0ed76fc213f479da584c22..b8b05f059183fdc3aa2bf1b86a9835417ab0b741 100644 (file)
--- a/fio-io.c
+++ b/fio-io.c
@@ -467,33 +467,47 @@ struct sgio_data {
        unsigned int bs;
 };
 
+static inline void sgio_hdr_init(struct sgio_data *sd, struct sg_io_hdr *hdr,
+                                struct io_u *io_u)
+{
+       memset(hdr, 0, sizeof(*hdr));
+       memset(sd->cdb, 0, sizeof(sd->cdb));
+
+       hdr->interface_id = 'S';
+       hdr->cmdp = sd->cdb;
+       hdr->cmd_len = sizeof(sd->cdb);
+
+       if (io_u) {
+               hdr->dxferp = io_u->buf;
+               hdr->dxfer_len = io_u->buflen;
+       }
+}
+
 static int fio_sgio_sync(struct thread_data *td)
 {
-       /*
-        * need to issue flush cache
-        */
-       return 0;
+       struct sgio_data *sd = td->io_data;
+       struct sg_io_hdr hdr;
+
+       sgio_hdr_init(sd, &hdr, NULL);
+       hdr.dxfer_direction = SG_DXFER_NONE;
+
+       hdr.cmdp[0] = 0x35;
+
+       return ioctl(td->fd, SG_IO, &hdr);
 }
 
-static int fio_sgio_queue(struct thread_data *td, struct io_u *io_u)
+static int fio_sgio_prep(struct thread_data *td, struct io_u *io_u)
 {
        struct sg_io_hdr *hdr = &io_u->hdr;
        struct sgio_data *sd = td->io_data;
-       int nr_blocks, lba, ret;
+       int nr_blocks, lba;
 
        if (io_u->buflen & (sd->bs - 1)) {
                fprintf(stderr, "read/write not sector aligned\n");
                return EINVAL;
        }
 
-       memset(hdr, 0, sizeof(*hdr));
-       memset(sd->cdb, 0, sizeof(sd->cdb));
-
-       hdr->interface_id = 'S';
-       hdr->cmdp = sd->cdb;
-       hdr->cmd_len = sizeof(sd->cdb);
-       hdr->dxferp = io_u->buf;
-       hdr->dxfer_len = io_u->buflen;
+       sgio_hdr_init(sd, hdr, io_u);
 
        if (io_u->ddir == DDIR_READ) {
                hdr->dxfer_direction = SG_DXFER_FROM_DEV;
@@ -511,6 +525,14 @@ static int fio_sgio_queue(struct thread_data *td, struct io_u *io_u)
        hdr->cmdp[5] = lba & 0xff;
        hdr->cmdp[7] = (nr_blocks >> 8) & 0xff;
        hdr->cmdp[8] = nr_blocks & 0xff;
+       return 0;
+}
+
+static int fio_sgio_queue(struct thread_data *td, struct io_u *io_u)
+{
+       struct sg_io_hdr *hdr = &io_u->hdr;
+       struct sgio_data *sd = td->io_data;
+       int ret;
 
        ret = ioctl(td->fd, SG_IO, hdr);
        if (ret < 0)
@@ -554,7 +576,7 @@ int fio_sgio_init(struct thread_data *td)
        sd = malloc(sizeof(*sd));
        sd->bs = bs;
 
-       td->io_prep = NULL;
+       td->io_prep = fio_sgio_prep;
        td->io_queue = fio_sgio_queue;
        td->io_getevents = fio_syncio_getevents;
        td->io_event = fio_sgio_event;
@@ -562,6 +584,11 @@ int fio_sgio_init(struct thread_data *td)
        td->io_cleanup = fio_syncio_cleanup;
        td->io_sync = fio_sgio_sync;
 
+       /*
+        * we want to do it, regardless of whether odirect is set or not
+        */
+       td->override_sync = 1;
+
        sd->last_io_u = NULL;
        td->io_data = sd;
        return 0;
diff --git a/fio.c b/fio.c
index 30b84ac3dac94de48a49004c4d58045aa9fa16ef..2d850b7f7ee41a602ae3d5eb89e9475215242047 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -68,7 +68,7 @@ enum {
        TD_REAPED,
 };
 
-#define should_fsync(td)       (td_write(td) && !(td)->odirect)
+#define should_fsync(td)       (td_write(td) && (!(td)->odirect || (td)->override_sync))
 
 static sem_t startup_sem;
 
diff --git a/fio.h b/fio.h
index 4021b748268a183fcfcae83a6bd52c2269d4add6..db9714070b935a243d549783a1fe074e90c433e5 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -208,6 +208,7 @@ struct thread_data {
        unsigned long ctx;
 
        unsigned int do_disk_util;
+       unsigned int override_sync;
 
        struct list_head io_hist_list;
 };