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 */