sg: add support for WRITE SAME(16) commands with NDOB flag set
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)
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@samsung.com>
Link: https://lore.kernel.org/r/20211115200807.117138-3-vincent.fu@samsung.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
HOWTO
engines/sg.c
examples/sg_write_same_ndob.fio [new file with mode: 0644]
fio.1

diff --git a/HOWTO b/HOWTO
index 111d2342de7b6e819acacff0365ff1acdaec79dc..370e04aa3f88f4b4b2a3a7d167d22bd2a03d183b 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -2511,6 +2511,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.
index 0c525fae8fd800877888a341e14df0c4d64bab72..3c4e986de734f443598467708f7c91b1c03f6bcb 100644 (file)
@@ -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 (file)
index 0000000..fb04731
--- /dev/null
@@ -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 4206360afab725341424c314ec26e58576135162..5a66e32680e65be68281efe5fd17bdbbe6740214 100644 (file)
--- a/fio.1
+++ b/fio.1
@@ -2309,6 +2309,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.