X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=engines%2Fsg.c;h=06cd19463b309124e4f75b95eb5ade8d50adb53b;hp=56e5d18ab60ba90edb05b69c079fae70a2fdc104;hb=cbdc9353da4ca4522cbed59e98d796a9ca99f0e9;hpb=d3b07186b1d4c7c1d9adc1306407458ce41ad048 diff --git a/engines/sg.c b/engines/sg.c index 56e5d18a..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, }, @@ -236,9 +266,9 @@ re_read: return r; } -static enum fio_q_status -fio_sgio_ioctl_doio(struct thread_data *td, struct fio_file *f, - struct io_u *io_u) +static enum fio_q_status fio_sgio_ioctl_doio(struct thread_data *td, + struct fio_file *f, + struct io_u *io_u) { struct sgio_data *sd = td->io_ops_data; struct sg_io_hdr *hdr = &io_u->hdr; @@ -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; @@ -378,8 +424,8 @@ static int fio_sgio_prep(struct thread_data *td, struct io_u *io_u) return 0; } -static enum fio_q_status -fio_sgio_queue(struct thread_data *td, struct io_u *io_u) +static enum fio_q_status fio_sgio_queue(struct thread_data *td, + struct io_u *io_u) { struct sg_io_hdr *hdr = &io_u->hdr; int ret, do_sync = 0;