Add the sg_write_mode option write_same_ndob to issue WRITE SAME(16) commands with the no data output buffer flag set. This flag is not supported for WRITE SAME(10). So all commands with this option will be WRITE SAME(16). Also include an example job file. Signed-off-by: Vincent Fu <vincent.fu@xxxxxxxxxxx> --- HOWTO | 5 ++++ engines/sg.c | 19 +++++++++++--- examples/sg_write_same_ndob.fio | 44 +++++++++++++++++++++++++++++++++ fio.1 | 6 +++++ 4 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 examples/sg_write_same_ndob.fio diff --git a/HOWTO b/HOWTO index c641a2a5..3c507d50 100644 --- a/HOWTO +++ b/HOWTO @@ -2501,6 +2501,11 @@ with the caveat that when used on the command line, they must come after the for each command but only the first 512 bytes will be used and transferred to the device. The writefua option is ignored with this selection. + **write_same_ndob** + Issue WRITE SAME(16) commands as above but with the No Data Output + Buffer (NDOB) bit set. No data will be transferred to the device with + this bit set. Data written will be a pre-determined pattern such as + all zeroes. **verify_bytchk_00** Issue VERIFY commands with BYTCHK set to 00. This directs the device to carry out a medium verification with no data comparison. diff --git a/engines/sg.c b/engines/sg.c index 0c525fae..3c4e986d 100644 --- a/engines/sg.c +++ b/engines/sg.c @@ -68,6 +68,7 @@ enum { FIO_SG_WRITE = 1, FIO_SG_WRITE_VERIFY, FIO_SG_WRITE_SAME, + FIO_SG_WRITE_SAME_NDOB, FIO_SG_VERIFY_BYTCHK_00, FIO_SG_VERIFY_BYTCHK_01, FIO_SG_VERIFY_BYTCHK_11, @@ -131,6 +132,10 @@ static struct fio_option options[] = { .oval = FIO_SG_WRITE_SAME, .help = "Issue SCSI WRITE SAME commands", }, + { .ival = "write_same_ndob", + .oval = FIO_SG_WRITE_SAME_NDOB, + .help = "Issue SCSI WRITE SAME(16) commands with NDOB flag set", + }, { .ival = "verify_bytchk_00", .oval = FIO_SG_VERIFY_BYTCHK_00, .help = "Issue SCSI VERIFY commands with BYTCHK set to 00", @@ -517,9 +522,9 @@ static enum fio_q_status fio_sgio_doio(struct thread_data *td, } static void fio_sgio_rw_lba(struct sg_io_hdr *hdr, unsigned long long lba, - unsigned long long nr_blocks) + unsigned long long nr_blocks, bool override16) { - if (lba < MAX_10B_LBA) { + if (lba < MAX_10B_LBA && !override16) { sgio_set_be32((uint32_t) lba, &hdr->cmdp[2]); sgio_set_be16((uint16_t) nr_blocks, &hdr->cmdp[7]); } else { @@ -560,7 +565,7 @@ static int fio_sgio_prep(struct thread_data *td, struct io_u *io_u) if (o->readfua) hdr->cmdp[1] |= 0x08; - fio_sgio_rw_lba(hdr, lba, nr_blocks); + fio_sgio_rw_lba(hdr, lba, nr_blocks, false); } else if (io_u->ddir == DDIR_WRITE) { sgio_hdr_init(sd, hdr, io_u, 1); @@ -591,6 +596,11 @@ static int fio_sgio_prep(struct thread_data *td, struct io_u *io_u) else hdr->cmdp[0] = 0x93; // write same(16) break; + case FIO_SG_WRITE_SAME_NDOB: + hdr->cmdp[0] = 0x93; // write same(16) + hdr->cmdp[1] |= 0x1; // no data output buffer + hdr->dxfer_len = 0; + break; case FIO_SG_VERIFY_BYTCHK_00: if (lba < MAX_10B_LBA) hdr->cmdp[0] = 0x2f; // VERIFY(10) @@ -615,7 +625,8 @@ static int fio_sgio_prep(struct thread_data *td, struct io_u *io_u) break; }; - fio_sgio_rw_lba(hdr, lba, nr_blocks); + fio_sgio_rw_lba(hdr, lba, nr_blocks, + o->write_mode == FIO_SG_WRITE_SAME_NDOB); } else if (io_u->ddir == DDIR_TRIM) { struct sgio_trim *st; diff --git a/examples/sg_write_same_ndob.fio b/examples/sg_write_same_ndob.fio new file mode 100644 index 00000000..fb047319 --- /dev/null +++ b/examples/sg_write_same_ndob.fio @@ -0,0 +1,44 @@ +# +# ********************************** +# * !!THIS IS A DESTRUCTIVE TEST!! * +# * IF NOT CHANGED THIS TEST WILL * +# * DESTROY DATA ON /dev/sdb * +# ********************************** +# +# Test WRITE SAME commands with the NDOB flag set +# issued via the sg ioengine +# All of the jobs below should complete without error +# except the last one +# +# job description +# precon Precondition the device by writing 20 blocks with a +# known pattern +# write_same_ndob Write 19 sectors of all zeroes with the NDOB flag set +# verify-pass Verify 19 blocks of all zeroes +# verify-fail Verify 20 blocks of all zeroes. This should fail. +# + +[global] +filename=/dev/sdb +buffer_pattern=0x01 +ioengine=sg +rw=write +bs=512 +stonewall + +[precon] +number_ios=20 + +[write_same_ndob] +sg_write_mode=write_same_ndob +number_ios=19 + +[verify-pass] +sg_write_mode=verify_bytchk_01 +buffer_pattern=0x00 +number_ios=19 + +[verify-fail] +sg_write_mode=verify_bytchk_01 +buffer_pattern=0x00 +number_ios=20 diff --git a/fio.1 b/fio.1 index 2d69615b..b1af6e8f 100644 --- a/fio.1 +++ b/fio.1 @@ -2306,6 +2306,12 @@ generate 8k of data for each command butonly the first 512 bytes will be used and transferred to the device. The writefua option is ignored with this selection. .TP +.B write_same_ndob +Issue WRITE SAME(16) commands as above but with the No Data Output +Buffer (NDOB) bit set. No data will be transferred to the device with +this bit set. Data written will be a pre-determined pattern such as +all zeroes. +.TP .B verify_bytchk_00 Issue VERIFY commands with BYTCHK set to 00. This directs the device to carry out a medium verification with no data comparison. -- 2.25.1