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

Commit 8b31849a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull scsi target fixes from Nicholas Bellinger:
 "Here's the current set of v3.8-rc fixes in the target-pending.git
  queue.  Apologies in advance for these missing the -rc6 release, and
  having to be destined for -rc7 code.

  The majority of these patches are regression bugfixes specific to
  v3.8-rc code changes, namely the zero-length CDB handling breakage
  after the sense_reason_t conversion, and preventing configfs port
  linking for unconfigured devices after the recent struct
  se_subsystem_dev removal.  These is also one (the divide by zero bug
  for unconfigured devices) that is CC'ed to stable."

* git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending:
  target: Fix divide by zero bug in fabric_max_sectors for unconfigured devices
  target: Fix regression allowing unconfigured devices to fabric port link
  tcm_vhost: fix pr_err on early kick
  target: Fix zero-length READ_CAPACITY_16 regression
  target: Fix zero-length MODE_SENSE regression
  target: Fix zero-length INQUIRY additional sense code regression
parents 7810cc1e 7a3cf6ca
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -941,6 +941,8 @@ int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth)

int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors)
{
	int block_size = dev->dev_attrib.block_size;

	if (dev->export_count) {
		pr_err("dev[%p]: Unable to change SE Device"
			" fabric_max_sectors while export_count is %d\n",
@@ -978,8 +980,12 @@ int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors)
	/*
	 * Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks()
	 */
	if (!block_size) {
		block_size = 512;
		pr_warn("Defaulting to 512 for zero block_size\n");
	}
	fabric_max_sectors = se_dev_align_max_sectors(fabric_max_sectors,
						      dev->dev_attrib.block_size);
						      block_size);

	dev->dev_attrib.fabric_max_sectors = fabric_max_sectors;
	pr_debug("dev[%p]: SE Device max_sectors changed to %u\n",
+5 −0
Original line number Diff line number Diff line
@@ -754,6 +754,11 @@ static int target_fabric_port_link(
		return -EFAULT;
	}

	if (!(dev->dev_flags & DF_CONFIGURED)) {
		pr_err("se_device not configured yet, cannot port link\n");
		return -ENODEV;
	}

	tpg_ci = &lun_ci->ci_parent->ci_group->cg_item;
	se_tpg = container_of(to_config_group(tpg_ci),
				struct se_portal_group, tpg_group);
+8 −10
Original line number Diff line number Diff line
@@ -58,11 +58,10 @@ sbc_emulate_readcapacity(struct se_cmd *cmd)
	buf[7] = dev->dev_attrib.block_size & 0xff;

	rbuf = transport_kmap_data_sg(cmd);
	if (!rbuf)
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

	if (rbuf) {
		memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
		transport_kunmap_data_sg(cmd);
	}

	target_complete_cmd(cmd, GOOD);
	return 0;
@@ -97,11 +96,10 @@ sbc_emulate_readcapacity_16(struct se_cmd *cmd)
		buf[14] = 0x80;

	rbuf = transport_kmap_data_sg(cmd);
	if (!rbuf)
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

	if (rbuf) {
		memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
		transport_kunmap_data_sg(cmd);
	}

	target_complete_cmd(cmd, GOOD);
	return 0;
+11 −33
Original line number Diff line number Diff line
@@ -641,11 +641,10 @@ spc_emulate_inquiry(struct se_cmd *cmd)

out:
	rbuf = transport_kmap_data_sg(cmd);
	if (!rbuf)
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

	if (rbuf) {
		memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
		transport_kunmap_data_sg(cmd);
	}

	if (!ret)
		target_complete_cmd(cmd, GOOD);
@@ -851,7 +850,7 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd)
{
	struct se_device *dev = cmd->se_dev;
	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 ten = (cmd->t_task_cdb[0] == MODE_SENSE_10);
	bool dbd = !!(cdb[1] & 0x08);
@@ -863,26 +862,8 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd)
	int ret;
	int i;

	map_buf = transport_kmap_data_sg(cmd);
	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;
	}
	memset(buf, 0, SE_MODE_PAGE_BUF);

	/*
	 * Skip over MODE DATA LENGTH + MEDIUM TYPE fields to byte 3 for
	 * MODE_SENSE_10 and byte 2 for MODE_SENSE (6).
@@ -934,8 +915,6 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd)
	if (page == 0x3f) {
		if (subpage != 0x00 && subpage != 0xff) {
			pr_warn("MODE_SENSE: Invalid subpage code: 0x%02x\n", subpage);
			kfree(buf);
			transport_kunmap_data_sg(cmd);
			return TCM_INVALID_CDB_FIELD;
		}

@@ -972,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",
		       page, subpage);

	transport_kunmap_data_sg(cmd);
	return TCM_UNKNOWN_MODE_PAGE;

set_length:
@@ -981,12 +959,12 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd)
	else
		buf[0] = length - 1;

	if (buf != map_buf) {
		memcpy(map_buf, buf, cmd->data_length);
		kfree(buf);
	rbuf = transport_kmap_data_sg(cmd);
	if (rbuf) {
		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);
	return 0;
}
+1 −3
Original line number Diff line number Diff line
@@ -575,10 +575,8 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs)

	/* Must use ioctl VHOST_SCSI_SET_ENDPOINT */
	tv_tpg = vs->vs_tpg;
	if (unlikely(!tv_tpg)) {
		pr_err("%s endpoint not set\n", __func__);
	if (unlikely(!tv_tpg))
		return;
	}

	mutex_lock(&vq->mutex);
	vhost_disable_notify(&vs->dev, vq);