sg: add support for VERIFY command using write modes
authorVincent Fu <vincent.fu@samsung.com>
Mon, 15 Nov 2021 20:07:17 +0000 (20:07 +0000)
committerJens Axboe <axboe@kernel.dk>
Tue, 18 Jan 2022 13:37:39 +0000 (06:37 -0700)
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 <vincent.fu@samsung.com>
Link: https://lore.kernel.org/r/20211115200807.117138-2-vincent.fu@samsung.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
HOWTO
engines/sg.c
examples/sg_verify-fail.fio [new file with mode: 0644]
examples/sg_verify.fio [new file with mode: 0644]
fio.1

diff --git a/HOWTO b/HOWTO
index 2956e50d7d3891af9fd216d1a2a4fc04ec1109d7..111d2342de7b6e819acacff0365ff1acdaec79dc 100644 (file)
--- 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]
 
index 1c0193840df3cacbf276be48542f5cd5af7b80ad..0c525fae8fd800877888a341e14df0c4d64bab72 100644 (file)
 
 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 (file)
index 0000000..64feece
--- /dev/null
@@ -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 (file)
index 0000000..6db0dd0
--- /dev/null
@@ -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 e0458c22e25fc819bb0ed9754549b23e609b0b26..4206360afab725341424c314ec26e58576135162 100644 (file)
--- 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