Thanks for the explanation Robert. I guess I need to work with other man pages for other changes as well. Below is the (hopefully final) patch for the fua bit support, which also includes an update to the root fio.1 man page file Thanks again everyone. Kris Davis diff --git a/HOWTO b/HOWTO index acb9e97..9309811 100644 --- a/HOWTO +++ b/HOWTO @@ -1747,6 +1747,7 @@ :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 @@ 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 + the force unit access (fua) flag. Defaults is 0. + +.. option:: writefua=bool : [sg] + + With writefua option set to 1, write operations include the + 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,8 +12,42 @@ #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 @@ -267,6 +301,7 @@ 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 @@ 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 @@ 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 @@ .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..06cac67 100644 --- a/fio.1 +++ b/fio.1 @@ -1523,7 +1523,7 @@ 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 @@ 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 the force +unit access (fua) flag. Default: 0. +.TP +.BI (sg)writefua \fR=\fPbool +With writefua option set to 1, write operations include the 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 @@ __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 @@ 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), }; ��.n��������+%������w��{.n�������^n�r������&��z�ޗ�zf���h���~����������_��+v���)ߣ�