Merge git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending

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
This commit is contained in:
Linus Torvalds 2013-02-02 13:37:56 +11:00
commit 8b31849a11
5 changed files with 32 additions and 47 deletions

View file

@ -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",

View file

@ -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);

View file

@ -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;
memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
transport_kunmap_data_sg(cmd);
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;
memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
transport_kunmap_data_sg(cmd);
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;

View file

@ -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;
memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
transport_kunmap_data_sg(cmd);
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;
}

View file

@ -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);