summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKris Davis <Kris.Davis@wdc.com>2018-03-19 10:19:44 -0600
committerJens Axboe <axboe@kernel.dk>2018-03-19 10:19:44 -0600
commit52b81b7c3b1c9900bf124b6cd0a2cef4a9a1df76 (patch)
tree36439929f24c8b76ca9d185868231616e61558f4
parent8d7632aa5a5a5c866ff2872319056df4ac2541ed (diff)
sg: add read/write FUA options
Enable the user to ask for the FUA bits to be set on read and write operations. Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--HOWTO12
-rw-r--r--engines/sg.c45
-rw-r--r--fio.110
-rw-r--r--optgroup.h8
4 files changed, 71 insertions, 4 deletions
diff --git a/HOWTO b/HOWTO
index acb9e97..dbbbfaa 100644
--- a/HOWTO
+++ b/HOWTO
@@ -1747,6 +1747,7 @@ I/O engine
:manpage:`read(2)` and :manpage:`write(2)` for asynchronous
I/O. Requires :option:`filename` option to specify either block or
character devices.
+ The sg engine includes engine specific options.
**null**
Doesn't transfer any data, just pretends to. This is mainly used to
@@ -2068,6 +2069,17 @@ with the caveat that when used on the command line, they must come after the
multiple paths exist between the client and the server or in certain loopback
configurations.
+.. option:: readfua=bool : [sg]
+
+ With readfua option set to 1, read operations include
+ the force unit access (fua) flag. Default is 0.
+
+.. option:: writefua=bool : [sg]
+
+ With writefua option set to 1, write operations include
+ the force unit access (fua) flag. Default is 0.
+
+
I/O depth
~~~~~~~~~
diff --git a/engines/sg.c b/engines/sg.c
index 4540b57..f240755 100644
--- a/engines/sg.c
+++ b/engines/sg.c
@@ -12,9 +12,43 @@
#include <sys/poll.h>
#include "../fio.h"
+#include "../optgroup.h"
#ifdef FIO_HAVE_SGIO
+
+struct sg_options {
+ void *pad;
+ unsigned int readfua;
+ unsigned int writefua;
+};
+
+static struct fio_option options[] = {
+ {
+ .name = "readfua",
+ .lname = "sg engine read fua flag support",
+ .type = FIO_OPT_BOOL,
+ .off1 = offsetof(struct sg_options, readfua),
+ .help = "Set FUA flag (force unit access) for all Read operations",
+ .def = "0",
+ .category = FIO_OPT_C_ENGINE,
+ .group = FIO_OPT_G_SG,
+ },
+ {
+ .name = "writefua",
+ .lname = "sg engine write fua flag support",
+ .type = FIO_OPT_BOOL,
+ .off1 = offsetof(struct sg_options, writefua),
+ .help = "Set FUA flag (force unit access) for all Write operations",
+ .def = "0",
+ .category = FIO_OPT_C_ENGINE,
+ .group = FIO_OPT_G_SG,
+ },
+ {
+ .name = NULL,
+ },
+};
+
#define MAX_10B_LBA 0xFFFFFFFFULL
#define SCSI_TIMEOUT_MS 30000 // 30 second timeout; currently no method to override
#define MAX_SB 64 // sense block maximum return size
@@ -267,6 +301,7 @@ static int fio_sgio_doio(struct thread_data *td, struct io_u *io_u, int do_sync)
static int fio_sgio_prep(struct thread_data *td, struct io_u *io_u)
{
struct sg_io_hdr *hdr = &io_u->hdr;
+ struct sg_options *o = td->eo;
struct sgio_data *sd = td->io_ops_data;
long long nr_blocks, lba;
@@ -286,6 +321,10 @@ static int fio_sgio_prep(struct thread_data *td, struct io_u *io_u)
hdr->cmdp[0] = 0x28; // read(10)
else
hdr->cmdp[0] = 0x88; // read(16)
+
+ if (o->readfua)
+ hdr->cmdp[1] |= 0x08;
+
} else if (io_u->ddir == DDIR_WRITE) {
sgio_hdr_init(sd, hdr, io_u, 1);
@@ -294,6 +333,10 @@ static int fio_sgio_prep(struct thread_data *td, struct io_u *io_u)
hdr->cmdp[0] = 0x2a; // write(10)
else
hdr->cmdp[0] = 0x8a; // write(16)
+
+ if (o->writefua)
+ hdr->cmdp[1] |= 0x08;
+
} else {
sgio_hdr_init(sd, hdr, io_u, 0);
hdr->dxfer_direction = SG_DXFER_NONE;
@@ -822,6 +865,8 @@ static struct ioengine_ops ioengine = {
.close_file = generic_close_file,
.get_file_size = fio_sgio_get_file_size,
.flags = FIO_SYNCIO | FIO_RAWIO,
+ .options = options,
+ .option_struct_size = sizeof(struct sg_options)
};
#else /* FIO_HAVE_SGIO */
diff --git a/fio.1 b/fio.1
index f955167..5ca57ce 100644
--- a/fio.1
+++ b/fio.1
@@ -1523,7 +1523,7 @@ SCSI generic sg v3 I/O. May either be synchronous using the SG_IO
ioctl, or if the target is an sg character device we use
\fBread\fR\|(2) and \fBwrite\fR\|(2) for asynchronous
I/O. Requires \fBfilename\fR option to specify either block or
-character devices.
+character devices. The sg engine includes engine specific options.
.TP
.B null
Doesn't transfer any data, just pretends to. This is mainly used to
@@ -1820,6 +1820,14 @@ server side this will be passed into the rdma_bind_addr() function and
on the client site it will be used in the rdma_resolve_add()
function. This can be useful when multiple paths exist between the
client and the server or in certain loopback configurations.
+.TP
+.BI (sg)readfua \fR=\fPbool
+With readfua option set to 1, read operations include the force
+unit access (fua) flag. Default: 0.
+.TP
+.BI (sg)writefua \fR=\fPbool
+With writefua option set to 1, write operations include the force
+unit access (fua) flag. Default: 0.
.SS "I/O depth"
.TP
.BI iodepth \fR=\fPint
diff --git a/optgroup.h b/optgroup.h
index 815ac16..d5e968d 100644
--- a/optgroup.h
+++ b/optgroup.h
@@ -55,10 +55,11 @@ enum opt_category_group {
__FIO_OPT_G_LIBAIO,
__FIO_OPT_G_ACT,
__FIO_OPT_G_LATPROF,
- __FIO_OPT_G_RBD,
- __FIO_OPT_G_GFAPI,
- __FIO_OPT_G_MTD,
+ __FIO_OPT_G_RBD,
+ __FIO_OPT_G_GFAPI,
+ __FIO_OPT_G_MTD,
__FIO_OPT_G_HDFS,
+ __FIO_OPT_G_SG,
__FIO_OPT_G_NR,
FIO_OPT_G_RATE = (1ULL << __FIO_OPT_G_RATE),
@@ -93,6 +94,7 @@ enum opt_category_group {
FIO_OPT_G_GFAPI = (1ULL << __FIO_OPT_G_GFAPI),
FIO_OPT_G_MTD = (1ULL << __FIO_OPT_G_MTD),
FIO_OPT_G_HDFS = (1ULL << __FIO_OPT_G_HDFS),
+ FIO_OPT_G_SG = (1ULL << __FIO_OPT_G_SG),
FIO_OPT_G_INVALID = (1ULL << __FIO_OPT_G_NR),
};