@@ -283,7 +283,12 @@ fd_execute_rw_aio(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
for_each_sg(sgl, sg, sgl_nents, i) {
bvec_set_page(&aio_cmd->bvecs[i], sg_page(sg), sg->length,
sg->offset);
- len += sg->length;
+ if (len + sg->length >= cmd->data_length) {
+ len = cmd->data_length;
+ break;
+ } else {
+ len += sg->length;
+ }
}
iov_iter_bvec(&iter, is_write, aio_cmd->bvecs, sgl_nents, len);
@@ -328,7 +333,12 @@ static int fd_do_rw(struct se_cmd *cmd, struct file *fd,
for_each_sg(sgl, sg, sgl_nents, i) {
bvec_set_page(&bvec[i], sg_page(sg), sg->length, sg->offset);
- len += sg->length;
+ if (len + sg->length >= data_length) {
+ len = data_length;
+ break;
+ } else {
+ len += sg->length;
+ }
}
iov_iter_bvec(&iter, is_write, bvec, sgl_nents, len);
--
2) Fix Sense Data Length
------------------------
The transport_get_sense_buffer() and transport_copy_sense_to_cmd() take
sense data length to be the allocated sense buffer length
TRANSPORT_SENSE_BUFFER. However, the sense data length is depending on
the sense data description. Check the sense data to set the proper
cmd->scsi_sense_length.
See SPC4-r37 section 4.5.2.1.
---
drivers/target/target_core_transport.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
@@ -804,8 +804,6 @@ static unsigned char *transport_get_sense_buffer(struct se_cmd *cmd)
if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION)
return NULL;
- cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER;
-
pr_debug("HBA_[%u]_PLUG[%s]: Requesting sense for SAM STATUS: 0x%02x\n",
dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status);
return cmd->sense_buffer;
@@ -824,7 +822,13 @@ void transport_copy_sense_to_cmd(struct se_cmd *cmd, unsigned char *sense)
}
cmd->se_cmd_flags |= SCF_TRANSPORT_TASK_SENSE;
+
+ /* Sense data length = min sense data + additional sense data length */
+ cmd->scsi_sense_length = min_t(u16, cmd_sense_buf[7] + 8,
+ TRANSPORT_SENSE_BUFFER);
+
memcpy(cmd_sense_buf, sense, cmd->scsi_sense_length);
+
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
}
EXPORT_SYMBOL(transport_copy_sense_to_cmd);
@@ -3521,12 +3525,19 @@ static void translate_sense_reason(struct se_cmd *cmd, sense_reason_t reason)
cmd->se_cmd_flags |= SCF_EMULATED_TASK_SENSE;
cmd->scsi_status = SAM_STAT_CHECK_CONDITION;
- cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER;
+
scsi_build_sense_buffer(desc_format, buffer, key, asc, ascq);
if (sd->add_sense_info)
WARN_ON_ONCE(scsi_set_sense_information(buffer,
- cmd->scsi_sense_length,
+ TRANSPORT_SENSE_BUFFER,
cmd->sense_info) < 0);
+ /*
+ * CHECK CONDITION returns sense data, and sense data is minimum 8
+ * bytes long plus additional Sense Data Length.
+ * See SPC4-r37 section 4.5.2.1.
+ */
+ cmd->scsi_sense_length = min_t(u16, buffer[7] + 8,
+ TRANSPORT_SENSE_BUFFER);
}
int