From e8ab121c88d61624c0925b54013cd57c2dc171f2 Mon Sep 17 00:00:00 2001 From: Vincent Fu Date: Mon, 15 Nov 2021 20:07:17 +0000 Subject: [PATCH] sg: add support for VERIFY command using write modes fio does not have an explicit verify data direction and creating a new data direction just for SCSI VERIFY commands probably is not worthwhile. The format of SCSI VERIFY commands matches that of write operations since VERIFY commands can include data transfer to the device. So it seems reasonable to have VERIFY commands be accounted for as write operations by fio. Use the sg_write_mode option to support SCSI VERIFY commands with different BYTCHK values. BYTCHK Description 00 No data is transferred to the device; device data is checked 01 Device data is compared with data transferred to device 11 Same as 01 except that only one sector of data is transferred to the device and each sector specified in the verification extent is compared against this transferred data. Also update documentation and add a couple example jobs files. Signed-off-by: Vincent Fu Link: https://lore.kernel.org/r/20211115200807.117138-2-vincent.fu@samsung.com Signed-off-by: Jens Axboe --- HOWTO | 14 +++++++++ engines/sg.c | 41 ++++++++++++++++++++++++-- examples/sg_verify-fail.fio | 48 +++++++++++++++++++++++++++++++ examples/sg_verify.fio | 57 +++++++++++++++++++++++++++++++++++++ fio.1 | 24 +++++++++++++--- 5 files changed, 178 insertions(+), 6 deletions(-) create mode 100644 examples/sg_verify-fail.fio create mode 100644 examples/sg_verify.fio diff --git a/HOWTO b/HOWTO index 2956e50d..111d2342 100644 --- a/HOWTO +++ b/HOWTO @@ -2511,6 +2511,20 @@ 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. + **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. + **verify_bytchk_01** + Issue VERIFY commands with BYTCHK set to 01. This directs the device to + compare the data on the device with the data transferred to the device. + **verify_bytchk_11** + Issue VERIFY commands with BYTCHK set to 11. This transfers a + single block to the device and compares the contents of this block with the + data on the device beginning at the specified offset. fio's block size + parameter specifies the total amount of data compared with this command. + However, only one block (sector) worth of data is transferred to the device. + This is similar to the WRITE SAME command except that data is compared instead + of written. .. option:: hipri : [sg] diff --git a/engines/sg.c b/engines/sg.c index 1c019384..0c525fae 100644 --- a/engines/sg.c +++ b/engines/sg.c @@ -66,8 +66,11 @@ enum { FIO_SG_WRITE = 1, - FIO_SG_WRITE_VERIFY = 2, - FIO_SG_WRITE_SAME = 3 + FIO_SG_WRITE_VERIFY, + FIO_SG_WRITE_SAME, + FIO_SG_VERIFY_BYTCHK_00, + FIO_SG_VERIFY_BYTCHK_01, + FIO_SG_VERIFY_BYTCHK_11, }; struct sg_options { @@ -128,6 +131,18 @@ static struct fio_option options[] = { .oval = FIO_SG_WRITE_SAME, .help = "Issue SCSI WRITE SAME commands", }, + { .ival = "verify_bytchk_00", + .oval = FIO_SG_VERIFY_BYTCHK_00, + .help = "Issue SCSI VERIFY commands with BYTCHK set to 00", + }, + { .ival = "verify_bytchk_01", + .oval = FIO_SG_VERIFY_BYTCHK_01, + .help = "Issue SCSI VERIFY commands with BYTCHK set to 01", + }, + { .ival = "verify_bytchk_11", + .oval = FIO_SG_VERIFY_BYTCHK_11, + .help = "Issue SCSI VERIFY commands with BYTCHK set to 11", + }, }, .category = FIO_OPT_C_ENGINE, .group = FIO_OPT_G_SG, @@ -576,6 +591,28 @@ 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_VERIFY_BYTCHK_00: + if (lba < MAX_10B_LBA) + hdr->cmdp[0] = 0x2f; // VERIFY(10) + else + hdr->cmdp[0] = 0x8f; // VERIFY(16) + hdr->dxfer_len = 0; + break; + case FIO_SG_VERIFY_BYTCHK_01: + if (lba < MAX_10B_LBA) + hdr->cmdp[0] = 0x2f; // VERIFY(10) + else + hdr->cmdp[0] = 0x8f; // VERIFY(16) + hdr->cmdp[1] |= 0x02; // BYTCHK = 01b + break; + case FIO_SG_VERIFY_BYTCHK_11: + if (lba < MAX_10B_LBA) + hdr->cmdp[0] = 0x2f; // VERIFY(10) + else + hdr->cmdp[0] = 0x8f; // VERIFY(16) + hdr->cmdp[1] |= 0x06; // BYTCHK = 11b + hdr->dxfer_len = sd->bs; + break; }; fio_sgio_rw_lba(hdr, lba, nr_blocks); diff --git a/examples/sg_verify-fail.fio b/examples/sg_verify-fail.fio new file mode 100644 index 00000000..64feece3 --- /dev/null +++ b/examples/sg_verify-fail.fio @@ -0,0 +1,48 @@ +# +# ********************************** +# * !!THIS IS A DESTRUCTIVE TEST!! * +# * IF NOT CHANGED THIS TEST WILL * +# * DESTROY DATA ON /dev/sdb * +# ********************************** +# +# Test SCSI VERIFY commands issued via the sg ioengine +# The jobs with fail in the name should produce errors +# +# job description +# precon precondition the device by writing with a known +# pattern +# verify01 verify each block one at a time by comparing to known +# pattern +# verify01-fail verifying one too many blocks should produce a failure +# verify11-one_ios verify all 20 blocks by sending only 512 bytes +# verify11-fail verifying beyond the preconditioned region should +# produce a failure + +[global] +filename=/dev/sdb +buffer_pattern=0x01 +ioengine=sg +rw=write +bs=512 +number_ios=20 +stonewall + +[precon] + +[verify01] +sg_write_mode=verify_bytchk_01 +number_ios=20 + +[verify01-fail] +sg_write_mode=verify_bytchk_01 +number_ios=21 + +[verify11-one_ios] +sg_write_mode=verify_bytchk_11 +number_ios=1 +bs=10240 + +[verify11-fail] +sg_write_mode=verify_bytchk_11 +number_ios=1 +bs=10752 diff --git a/examples/sg_verify.fio b/examples/sg_verify.fio new file mode 100644 index 00000000..6db0dd0a --- /dev/null +++ b/examples/sg_verify.fio @@ -0,0 +1,57 @@ +# +# ********************************** +# * !!THIS IS A DESTRUCTIVE TEST!! * +# * IF NOT CHANGED THIS TEST WILL * +# * DESTROY DATA ON /dev/sdb * +# ********************************** +# +# Test SCSI VERIFY commands issued via the sg ioengine +# All of the jobs below should complete without error +# +# job description +# precon precondition the device by writing with a known +# pattern +# verify00 verify written data on medium only +# verify01 verify each block one at a time by comparing to known +# pattern +# verify01-two_ios verify same data but with only two VERIFY operations +# verify11 verify each block one at a time +# verify11-five_ios verify data with five IOs, four blocks at a time, +# sending 512 bytes for each IO +# verify11-one_ios verify all 20 blocks by sending only 512 bytes +# + +[global] +filename=/dev/sdb +buffer_pattern=0x01 +ioengine=sg +rw=write +bs=512 +number_ios=20 +stonewall + +[precon] + +[verify00] +sg_write_mode=verify_bytchk_00 + +[verify01] +sg_write_mode=verify_bytchk_01 + +[verify01-two_ios] +sg_write_mode=verify_bytchk_01 +bs=5120 +number_ios=2 + +[verify11] +sg_write_mode=verify_bytchk_11 + +[verify11-five_ios] +sg_write_mode=verify_bytchk_11 +bs=2048 +number_ios=5 + +[verify11-one_ios] +sg_write_mode=verify_bytchk_11 +bs=10240 +number_ios=1 diff --git a/fio.1 b/fio.1 index e0458c22..4206360a 100644 --- a/fio.1 +++ b/fio.1 @@ -2284,7 +2284,7 @@ With writefua option set to 1, write operations include the force unit access (fua) flag. Default: 0. .TP .BI (sg)sg_write_mode \fR=\fPstr -Specify the type of write commands to issue. This option can take three +Specify the type of write commands to issue. This option can take multiple values: .RS .RS @@ -2293,9 +2293,9 @@ values: Write opcodes are issued as usual .TP .B verify -Issue WRITE AND VERIFY commands. The BYTCHK bit is set to 0. This -directs the device to carry out a medium verification with no data -comparison. The writefua option is ignored with this selection. +Issue WRITE AND VERIFY commands. The BYTCHK bit is set to 00b. This directs the +device to carry out a medium verification with no data comparison for the data +that was written. The writefua option is ignored with this selection. .TP .B same Issue WRITE SAME commands. This transfers a single block to the device @@ -2308,6 +2308,22 @@ blocksize=8k will write 16 sectors with each command. fio will still 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 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. +.TP +.B verify_bytchk_01 +Issue VERIFY commands with BYTCHK set to 01. This directs the device to +compare the data on the device with the data transferred to the device. +.TP +.B verify_bytchk_11 +Issue VERIFY commands with BYTCHK set to 11. This transfers a single block to +the device and compares the contents of this block with the data on the device +beginning at the specified offset. fio's block size parameter specifies the +total amount of data compared with this command. However, only one block +(sector) worth of data is transferred to the device. This is similar to the +WRITE SAME command except that data is compared instead of written. .RE .RE .TP -- 2.25.1