Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cab9609b authored by Nicholas Bellinger's avatar Nicholas Bellinger
Browse files

target: Fix zero-length MODE_SENSE regression



This patch fixes a regression introduced in v3.8-rc1 code where
a zero-length MODE_SENSE was no longer returning GOOD status, but
instead returning TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE to generate
a CHECK_CONDITION status.

This regression was introduced with the following commit:

  commit de103c93
  Author: Christoph Hellwig <hch@lst.de>
  Date:   Tue Nov 6 12:24:09 2012 -0800

      target: pass sense_reason as a return value

and this patch has been tested with the following zero-length CDB:

  sg_raw /dev/sdd 5a 00 0a 00 00 00 00 00 00 00
  SCSI Status: Good

  Sense Information:
  sense buffer empty

Cc: Christoph Hellwig <hch@lst.de>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Roland Dreier <roland@purestorage.com>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent 49df9fc9
Loading
Loading
Loading
Loading
+7 −28
Original line number Original line Diff line number Diff line
@@ -850,7 +850,7 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd)
{
{
	struct se_device *dev = cmd->se_dev;
	struct se_device *dev = cmd->se_dev;
	char *cdb = cmd->t_task_cdb;
	char *cdb = cmd->t_task_cdb;
	unsigned char *buf, *map_buf;
	unsigned char buf[SE_MODE_PAGE_BUF], *rbuf;
	int type = dev->transport->get_device_type(dev);
	int type = dev->transport->get_device_type(dev);
	int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10);
	int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10);
	bool dbd = !!(cdb[1] & 0x08);
	bool dbd = !!(cdb[1] & 0x08);
@@ -862,26 +862,8 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd)
	int ret;
	int ret;
	int i;
	int i;


	map_buf = transport_kmap_data_sg(cmd);
	memset(buf, 0, SE_MODE_PAGE_BUF);
	if (!map_buf)

		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
	/*
	 * If SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC is not set, then we
	 * know we actually allocated a full page.  Otherwise, if the
	 * data buffer is too small, allocate a temporary buffer so we
	 * don't have to worry about overruns in all our INQUIRY
	 * emulation handling.
	 */
	if (cmd->data_length < SE_MODE_PAGE_BUF &&
	    (cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC)) {
		buf = kzalloc(SE_MODE_PAGE_BUF, GFP_KERNEL);
		if (!buf) {
			transport_kunmap_data_sg(cmd);
			return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
		}
	} else {
		buf = map_buf;
	}
	/*
	/*
	 * Skip over MODE DATA LENGTH + MEDIUM TYPE fields to byte 3 for
	 * Skip over MODE DATA LENGTH + MEDIUM TYPE fields to byte 3 for
	 * MODE_SENSE_10 and byte 2 for MODE_SENSE (6).
	 * MODE_SENSE_10 and byte 2 for MODE_SENSE (6).
@@ -933,8 +915,6 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd)
	if (page == 0x3f) {
	if (page == 0x3f) {
		if (subpage != 0x00 && subpage != 0xff) {
		if (subpage != 0x00 && subpage != 0xff) {
			pr_warn("MODE_SENSE: Invalid subpage code: 0x%02x\n", subpage);
			pr_warn("MODE_SENSE: Invalid subpage code: 0x%02x\n", subpage);
			kfree(buf);
			transport_kunmap_data_sg(cmd);
			return TCM_INVALID_CDB_FIELD;
			return TCM_INVALID_CDB_FIELD;
		}
		}


@@ -971,7 +951,6 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd)
		pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n",
		pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n",
		       page, subpage);
		       page, subpage);


	transport_kunmap_data_sg(cmd);
	return TCM_UNKNOWN_MODE_PAGE;
	return TCM_UNKNOWN_MODE_PAGE;


set_length:
set_length:
@@ -980,12 +959,12 @@ set_length:
	else
	else
		buf[0] = length - 1;
		buf[0] = length - 1;


	if (buf != map_buf) {
	rbuf = transport_kmap_data_sg(cmd);
		memcpy(map_buf, buf, cmd->data_length);
	if (rbuf) {
		kfree(buf);
		memcpy(rbuf, buf, min_t(u32, SE_MODE_PAGE_BUF, cmd->data_length));
		transport_kunmap_data_sg(cmd);
	}
	}


	transport_kunmap_data_sg(cmd);
	target_complete_cmd(cmd, GOOD);
	target_complete_cmd(cmd, GOOD);
	return 0;
	return 0;
}
}