summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@suse.de>2005-12-08 11:17:52 +0100
committerJens Axboe <axboe@suse.de>2005-12-08 11:17:52 +0100
commit842c5db8789dfb50e40c3c4ce6d4ad86cbaa0bb5 (patch)
tree0e51f13f4c6bbd1827bfe5f197f7f11cc4a7e700
parent410de646b75dc74cb480aae3d151bd4503e67780 (diff)
[PATCH] fio: support sync operation with sgio ioengine
-rw-r--r--fio-io.c57
-rw-r--r--fio.c2
-rw-r--r--fio.h1
3 files changed, 44 insertions, 16 deletions
diff --git a/fio-io.c b/fio-io.c
index 3c86639..b8b05f0 100644
--- 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 30b84ac..2d850b7 100644
--- 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 4021b74..db97140 100644
--- 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;
};