From b07dea49d4dc4eae22f16d8f911d172d4225b0f1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 16 May 2020 15:55:46 +0000 Subject: [PATCH 1/6] scripts/run-regression-tests: Do not create a -.o file git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8922 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scripts/run-regression-tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/run-regression-tests b/scripts/run-regression-tests index 97fb9f6a0..1de609dc2 100755 --- a/scripts/run-regression-tests +++ b/scripts/run-regression-tests @@ -713,7 +713,7 @@ do # v4.13) and commit 6f303d60534c ("gcc-9: silence 'address-of-packed-member' # warning"; v5.1). for w in -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -Wno-address-of-packed-member; do - if gcc -c -xc - "$w" &/dev/null; then + if gcc -c -xc -E - "$w" &/dev/null; then KCFLAGS+=" $w" fi done From c84dbccf5ce93087e1a1eb2879dd3924030f9dd5 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 16 May 2020 15:57:21 +0000 Subject: [PATCH 2/6] scst: Complain loudly if scst_adjust_sg_get_tail() fails Apparently certain libiscsi COMPARE AND WRITE tests cause scst_adjust_sg_get_tail() to fail. Complain if that happens even if "EXTRACHECKS" are disabled. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8923 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/scst_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index d9378c4a4..bda3d712a 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -6846,7 +6846,7 @@ static void scst_cwr_read_cmd_finished(struct scst_cmd *cmd) * It must not happen, because get_cdb_info_compare_and_write() * supposed to ensure that. */ - EXTRACHECKS_BUG_ON(rc != 0); + WARN_ONCE(rc != 0, "scst_adjust_sg_get_tail() failed: %d\n", rc); wcmd->tgt_i_data_buf_alloced = 1; From d9a684a9c364676a35cf0af3eb354fa687504386 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 16 May 2020 15:57:45 +0000 Subject: [PATCH 3/6] scst.h: Add a comment above sg_next_inline() git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8924 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/include/scst.h | 1 + 1 file changed, 1 insertion(+) diff --git a/scst/include/scst.h b/scst/include/scst.h index a3453f0e9..d735ee97c 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -4846,6 +4846,7 @@ static inline struct scatterlist *__sg_next_inline(struct scatterlist *sg) return sg; } +/* Inline version of sg_next() from lib/scatterlist.c in the Linux kernel. */ static inline struct scatterlist *sg_next_inline(struct scatterlist *sg) { if (sg_is_last(sg)) From 981501a9fa236ab81094981aa76c2570bc71c8ac Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 16 May 2020 15:59:30 +0000 Subject: [PATCH 4/6] scst.h: Remove an obsolete comment This is a follow-up for commit 57d9df07178a ("scst: Remove an empty function") / r8908. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8925 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/include/scst.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/scst/include/scst.h b/scst/include/scst.h index d735ee97c..5da726d7d 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -5020,9 +5020,6 @@ static inline void scst_put_sg_buf(struct scst_cmd *cmd, void *buf, * negative error code otherwise. * * "Page" argument returns the starting page, "offset" - offset in it. - * - * The "put" function "puts" the buffer. It should be always be used, because - * in future may need to do some additional operations. */ static inline int __scst_get_sg_page(struct scst_cmd *cmd, int sg_cnt, struct page **page, int *offset) From d5e13d64531eaae52edf478b042f7277edf27bc3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 16 May 2020 16:01:00 +0000 Subject: [PATCH 5/6] scst: Introduce a new local variable in scst_cmp_wr_local() This patch does not change any functionality. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8926 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/scst_lib.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index bda3d712a..da890b9c3 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -6876,7 +6876,8 @@ enum scst_exec_res scst_cmp_wr_local(struct scst_cmd *cmd) struct scst_cwr_priv *cwrp; uint8_t read16_cdb[16]; struct scst_cmd *rcmd; - int data_len; + const int data_len = cmd->data_len; + const uint32_t num_lbas = data_len >> cmd->dev->block_shift; TRACE_ENTRY(); @@ -6912,8 +6913,6 @@ enum scst_exec_res scst_cmp_wr_local(struct scst_cmd *cmd) cwrp->cwr_orig_cmd = cmd; cwrp->cwr_finish_fn = scst_cwr_read_cmd_finished; - data_len = cmd->data_len; - /* * As required by SBC, DIF PI, if any, is not checked for the read part */ @@ -6922,7 +6921,7 @@ enum scst_exec_res scst_cmp_wr_local(struct scst_cmd *cmd) read16_cdb[0] = READ_16; read16_cdb[1] = cmd->cdb[1] & ~0xE0; /* as required, see above */ put_unaligned_be64(cmd->lba, &read16_cdb[2]); - put_unaligned_be32(data_len >> cmd->dev->block_shift, &read16_cdb[10]); + put_unaligned_be32(num_lbas, &read16_cdb[10]); rcmd = scst_create_prepare_internal_cmd(cmd, read16_cdb, sizeof(read16_cdb), SCST_CMD_QUEUE_HEAD_OF_QUEUE); From 4525b04b23f310d3defbcca2f637f78d9b901a7b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 16 May 2020 16:02:32 +0000 Subject: [PATCH 6/6] scst: Reject inconsistent COMPARE AND WRITE commands Reject COMPARE AND WRITE commands if the size of the data buffer does not match the number of logical blocks specified in the CDB. This patch makes two more libiscsi conformance tests pass. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8927 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/scst_lib.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index da890b9c3..7c4e858bd 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -6870,6 +6870,19 @@ out_finish: goto out; } +/* + * The Data-Out Buffer contains two instances of logical block data: + * 1) the compare instance, in which: + * A) the user data is used for the compare operation; and + * B) the protection information, if any, is not used; + * and + * 2) the write instance, in which: + * A) the user data is used for the write operations; and + * B) the protection information, if any, is used for the write operations. + * + * Note: cmd->data_len is half of the DataOut buffer size while cmd->bufflen + * and cmd->expected_transfer_len refer to the entire DataOut buffer. + */ enum scst_exec_res scst_cmp_wr_local(struct scst_cmd *cmd) { enum scst_exec_res res = SCST_EXEC_COMPLETED; @@ -6913,6 +6926,14 @@ enum scst_exec_res scst_cmp_wr_local(struct scst_cmd *cmd) cwrp->cwr_orig_cmd = cmd; cwrp->cwr_finish_fn = scst_cwr_read_cmd_finished; + if (cmd->bufflen != scst_cmd_get_expected_transfer_len_data(cmd)) { + PRINT_ERROR("COMPARE AND WRITE: data buffer length mismatch (CDB %u <> ini %u)", + cmd->bufflen, + scst_cmd_get_expected_transfer_len_data(cmd)); + scst_set_invalid_field_in_cdb(cmd, 13/*NLB*/, 0); + goto out_done; + } + /* * As required by SBC, DIF PI, if any, is not checked for the read part */