From: Vincent Fu Date: Wed, 16 May 2018 23:17:47 +0000 (-0400) Subject: engines/sg: add support for WRITE AND VERIFY, WRITE SAME X-Git-Tag: fio-3.7~4^2~1 X-Git-Url: https://git.kernel.dk/?p=fio.git;a=commitdiff_plain;h=cbdc9353da4ca4522cbed59e98d796a9ca99f0e9;ds=sidebyside engines/sg: add support for WRITE AND VERIFY, WRITE SAME Add an sg ioengine option to treat write IO as either WRITE AND VERIFY or WRITE SAME commands The new ioengine option sg_write_mode can take 3 values: write (default) WRITE opcodes are issued as usual verify WRITE AND VERIFY opcodes are issued same WRITE SAME opcodes are issued WRITE AND VERIFY opcodes are issued with the BYTCHK bit set to 0. This directs the device to carry out a medium verification with no data comparison. WRITE SAME transfers a single block of data to the device and writes this same block of data to a contiguous sequence of LBAs beginning at the specified offset. fio's block size parameter specifies the amount of data written with each command. However, the amount of data actually transferred to the device is equal to the device's block (sector) size. For a device with 512 byte sectors, blocksize=8k will write 16 sectors with each command. fio will still generate 8k of data for each command but only the first 512 bytes will be used and transferred to the device. --- diff --git a/engines/sg.c b/engines/sg.c index d4848bc5..06cd1946 100644 --- a/engines/sg.c +++ b/engines/sg.c @@ -15,11 +15,17 @@ #ifdef FIO_HAVE_SGIO +enum { + FIO_SG_WRITE = 1, + FIO_SG_WRITE_VERIFY = 2, + FIO_SG_WRITE_SAME = 3 +}; struct sg_options { void *pad; unsigned int readfua; unsigned int writefua; + unsigned int write_mode; }; static struct fio_option options[] = { @@ -43,6 +49,30 @@ static struct fio_option options[] = { .category = FIO_OPT_C_ENGINE, .group = FIO_OPT_G_SG, }, + { + .name = "sg_write_mode", + .lname = "specify sg write mode", + .type = FIO_OPT_STR, + .off1 = offsetof(struct sg_options, write_mode), + .help = "Specify SCSI WRITE mode", + .def = "write", + .posval = { + { .ival = "write", + .oval = FIO_SG_WRITE, + .help = "Issue standard SCSI WRITE commands", + }, + { .ival = "verify", + .oval = FIO_SG_WRITE_VERIFY, + .help = "Issue SCSI WRITE AND VERIFY commands", + }, + { .ival = "same", + .oval = FIO_SG_WRITE_SAME, + .help = "Issue SCSI WRITE SAME commands", + }, + }, + .category = FIO_OPT_C_ENGINE, + .group = FIO_OPT_G_SG, + }, { .name = NULL, }, @@ -329,14 +359,30 @@ static int fio_sgio_prep(struct thread_data *td, struct io_u *io_u) sgio_hdr_init(sd, hdr, io_u, 1); hdr->dxfer_direction = SG_DXFER_TO_DEV; - if (lba < MAX_10B_LBA) - hdr->cmdp[0] = 0x2a; // write(10) - else - hdr->cmdp[0] = 0x8a; // write(16) - - if (o->writefua) - hdr->cmdp[1] |= 0x08; - + switch(o->write_mode) { + case FIO_SG_WRITE: + if (lba < MAX_10B_LBA) + hdr->cmdp[0] = 0x2a; // write(10) + else + hdr->cmdp[0] = 0x8a; // write(16) + if (o->writefua) + hdr->cmdp[1] |= 0x08; + break; + case FIO_SG_WRITE_VERIFY: + if (lba < MAX_10B_LBA) + hdr->cmdp[0] = 0x2e; // write and verify(10) + else + hdr->cmdp[0] = 0x8e; // write and verify(16) + break; + // BYTCHK is disabled by virtue of the memset in sgio_hdr_init + case FIO_SG_WRITE_SAME: + hdr->dxfer_len = sd->bs; + if (lba < MAX_10B_LBA) + hdr->cmdp[0] = 0x41; // write same(10) + else + hdr->cmdp[0] = 0x93; // write same(16) + break; + }; } else { sgio_hdr_init(sd, hdr, io_u, 0); hdr->dxfer_direction = SG_DXFER_NONE;