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

Pull SCSI target fixes from Nicholas Bellinger:
 "Mostly minor fixes this time to v3.14-rc1 related changes.  Also
  included is one fix for a free after use regression in persistent
  reservations UNREGISTER logic that is CC'ed to >= v3.11.y stable"

* git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending:
  Target/sbc: Fix protection copy routine
  IB/srpt: replace strict_strtoul() with kstrtoul()
  target: Simplify command completion by removing CMD_T_FAILED flag
  iser-target: Fix leak on failure in isert_conn_create_fastreg_pool
  iscsi-target: Fix SNACK Type 1 + BegRun=0 handling
  target: Fix missing length check in spc_emulate_evpd_83()
  qla2xxx: Remove last vestiges of qla_tgt_cmd.cmd_list
  target: Fix 32-bit + CONFIG_LBDAF=n link error w/ sector_div
  target: Fix free-after-use regression in PR unregister
This commit is contained in:
Linus Torvalds 2014-02-15 16:18:47 -08:00
Родитель 2d0ef4fb34 d6a65fdc89
Коммит 946dd683af
11 изменённых файлов: 30 добавлений и 23 удалений

Просмотреть файл

@ -453,6 +453,7 @@ isert_conn_create_fastreg_pool(struct isert_conn *isert_conn)
if (ret) { if (ret) {
pr_err("Failed to create fastreg descriptor err=%d\n", pr_err("Failed to create fastreg descriptor err=%d\n",
ret); ret);
kfree(fr_desc);
goto err; goto err;
} }

Просмотреть файл

@ -3666,9 +3666,9 @@ static ssize_t srpt_tpg_attrib_store_srp_max_rdma_size(
unsigned long val; unsigned long val;
int ret; int ret;
ret = strict_strtoul(page, 0, &val); ret = kstrtoul(page, 0, &val);
if (ret < 0) { if (ret < 0) {
pr_err("strict_strtoul() failed with ret: %d\n", ret); pr_err("kstrtoul() failed with ret: %d\n", ret);
return -EINVAL; return -EINVAL;
} }
if (val > MAX_SRPT_RDMA_SIZE) { if (val > MAX_SRPT_RDMA_SIZE) {
@ -3706,9 +3706,9 @@ static ssize_t srpt_tpg_attrib_store_srp_max_rsp_size(
unsigned long val; unsigned long val;
int ret; int ret;
ret = strict_strtoul(page, 0, &val); ret = kstrtoul(page, 0, &val);
if (ret < 0) { if (ret < 0) {
pr_err("strict_strtoul() failed with ret: %d\n", ret); pr_err("kstrtoul() failed with ret: %d\n", ret);
return -EINVAL; return -EINVAL;
} }
if (val > MAX_SRPT_RSP_SIZE) { if (val > MAX_SRPT_RSP_SIZE) {
@ -3746,9 +3746,9 @@ static ssize_t srpt_tpg_attrib_store_srp_sq_size(
unsigned long val; unsigned long val;
int ret; int ret;
ret = strict_strtoul(page, 0, &val); ret = kstrtoul(page, 0, &val);
if (ret < 0) { if (ret < 0) {
pr_err("strict_strtoul() failed with ret: %d\n", ret); pr_err("kstrtoul() failed with ret: %d\n", ret);
return -EINVAL; return -EINVAL;
} }
if (val > MAX_SRPT_SRQ_SIZE) { if (val > MAX_SRPT_SRQ_SIZE) {
@ -3793,7 +3793,7 @@ static ssize_t srpt_tpg_store_enable(
unsigned long tmp; unsigned long tmp;
int ret; int ret;
ret = strict_strtoul(page, 0, &tmp); ret = kstrtoul(page, 0, &tmp);
if (ret < 0) { if (ret < 0) {
printk(KERN_ERR "Unable to extract srpt_tpg_store_enable\n"); printk(KERN_ERR "Unable to extract srpt_tpg_store_enable\n");
return -EINVAL; return -EINVAL;

Просмотреть файл

@ -2595,8 +2595,6 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
return -ENOMEM; return -ENOMEM;
} }
INIT_LIST_HEAD(&cmd->cmd_list);
memcpy(&cmd->atio, atio, sizeof(*atio)); memcpy(&cmd->atio, atio, sizeof(*atio));
cmd->state = QLA_TGT_STATE_NEW; cmd->state = QLA_TGT_STATE_NEW;
cmd->tgt = vha->vha_tgt.qla_tgt; cmd->tgt = vha->vha_tgt.qla_tgt;

Просмотреть файл

@ -855,7 +855,6 @@ struct qla_tgt_cmd {
uint16_t loop_id; /* to save extra sess dereferences */ uint16_t loop_id; /* to save extra sess dereferences */
struct qla_tgt *tgt; /* to save extra sess dereferences */ struct qla_tgt *tgt; /* to save extra sess dereferences */
struct scsi_qla_host *vha; struct scsi_qla_host *vha;
struct list_head cmd_list;
struct atio_from_isp atio; struct atio_from_isp atio;
}; };

Просмотреть файл

@ -507,7 +507,9 @@ int iscsit_handle_status_snack(
u32 last_statsn; u32 last_statsn;
int found_cmd; int found_cmd;
if (conn->exp_statsn > begrun) { if (!begrun) {
begrun = conn->exp_statsn;
} else if (conn->exp_statsn > begrun) {
pr_err("Got Status SNACK Begrun: 0x%08x, RunLength:" pr_err("Got Status SNACK Begrun: 0x%08x, RunLength:"
" 0x%08x but already got ExpStatSN: 0x%08x on CID:" " 0x%08x but already got ExpStatSN: 0x%08x on CID:"
" %hu.\n", begrun, runlength, conn->exp_statsn, " %hu.\n", begrun, runlength, conn->exp_statsn,

Просмотреть файл

@ -500,7 +500,7 @@ static inline int core_alua_state_lba_dependent(
if (segment_mult) { if (segment_mult) {
u64 tmp = lba; u64 tmp = lba;
start_lba = sector_div(tmp, segment_size * segment_mult); start_lba = do_div(tmp, segment_size * segment_mult);
last_lba = first_lba + segment_size - 1; last_lba = first_lba + segment_size - 1;
if (start_lba >= first_lba && if (start_lba >= first_lba &&

Просмотреть файл

@ -2009,7 +2009,7 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key,
struct t10_reservation *pr_tmpl = &dev->t10_pr; struct t10_reservation *pr_tmpl = &dev->t10_pr;
unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL; unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL;
sense_reason_t ret = TCM_NO_SENSE; sense_reason_t ret = TCM_NO_SENSE;
int pr_holder = 0; int pr_holder = 0, type;
if (!se_sess || !se_lun) { if (!se_sess || !se_lun) {
pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
@ -2131,6 +2131,7 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key,
ret = TCM_RESERVATION_CONFLICT; ret = TCM_RESERVATION_CONFLICT;
goto out; goto out;
} }
type = pr_reg->pr_res_type;
spin_lock(&pr_tmpl->registration_lock); spin_lock(&pr_tmpl->registration_lock);
/* /*
@ -2161,6 +2162,7 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key,
* Release the calling I_T Nexus registration now.. * Release the calling I_T Nexus registration now..
*/ */
__core_scsi3_free_registration(cmd->se_dev, pr_reg, NULL, 1); __core_scsi3_free_registration(cmd->se_dev, pr_reg, NULL, 1);
pr_reg = NULL;
/* /*
* From spc4r17, section 5.7.11.3 Unregistering * From spc4r17, section 5.7.11.3 Unregistering
@ -2174,8 +2176,8 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key,
* RESERVATIONS RELEASED. * RESERVATIONS RELEASED.
*/ */
if (pr_holder && if (pr_holder &&
(pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY || (type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY ||
pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY)) { type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY)) {
list_for_each_entry(pr_reg_p, list_for_each_entry(pr_reg_p,
&pr_tmpl->registration_list, &pr_tmpl->registration_list,
pr_reg_list) { pr_reg_list) {
@ -2194,7 +2196,8 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key,
ret = core_scsi3_update_and_write_aptpl(dev, aptpl); ret = core_scsi3_update_and_write_aptpl(dev, aptpl);
out: out:
core_scsi3_put_pr_reg(pr_reg); if (pr_reg)
core_scsi3_put_pr_reg(pr_reg);
return ret; return ret;
} }

Просмотреть файл

@ -1074,12 +1074,19 @@ sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read,
struct scatterlist *psg; struct scatterlist *psg;
void *paddr, *addr; void *paddr, *addr;
unsigned int i, len, left; unsigned int i, len, left;
unsigned int offset = 0;
left = sectors * dev->prot_length; left = sectors * dev->prot_length;
for_each_sg(cmd->t_prot_sg, psg, cmd->t_prot_nents, i) { for_each_sg(cmd->t_prot_sg, psg, cmd->t_prot_nents, i) {
len = min(psg->length, left); len = min(psg->length, left);
if (offset >= sg->length) {
sg = sg_next(sg);
offset = 0;
sg_off = sg->offset;
}
paddr = kmap_atomic(sg_page(psg)) + psg->offset; paddr = kmap_atomic(sg_page(psg)) + psg->offset;
addr = kmap_atomic(sg_page(sg)) + sg_off; addr = kmap_atomic(sg_page(sg)) + sg_off;
@ -1089,6 +1096,7 @@ sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read,
memcpy(addr, paddr, len); memcpy(addr, paddr, len);
left -= len; left -= len;
offset += len;
kunmap_atomic(paddr); kunmap_atomic(paddr);
kunmap_atomic(addr); kunmap_atomic(addr);
} }

Просмотреть файл

@ -440,8 +440,8 @@ check_scsi_name:
padding = ((-scsi_target_len) & 3); padding = ((-scsi_target_len) & 3);
if (padding) if (padding)
scsi_target_len += padding; scsi_target_len += padding;
if (scsi_name_len > 256) if (scsi_target_len > 256)
scsi_name_len = 256; scsi_target_len = 256;
buf[off-1] = scsi_target_len; buf[off-1] = scsi_target_len;
off += scsi_target_len; off += scsi_target_len;

Просмотреть файл

@ -669,9 +669,6 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
return; return;
} }
if (!success)
cmd->transport_state |= CMD_T_FAILED;
/* /*
* Check for case where an explicit ABORT_TASK has been received * Check for case where an explicit ABORT_TASK has been received
* and transport_wait_for_tasks() will be waiting for completion.. * and transport_wait_for_tasks() will be waiting for completion..
@ -681,7 +678,7 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
spin_unlock_irqrestore(&cmd->t_state_lock, flags); spin_unlock_irqrestore(&cmd->t_state_lock, flags);
complete(&cmd->t_transport_stop_comp); complete(&cmd->t_transport_stop_comp);
return; return;
} else if (cmd->transport_state & CMD_T_FAILED) { } else if (!success) {
INIT_WORK(&cmd->work, target_complete_failure_work); INIT_WORK(&cmd->work, target_complete_failure_work);
} else { } else {
INIT_WORK(&cmd->work, target_complete_ok_work); INIT_WORK(&cmd->work, target_complete_ok_work);

Просмотреть файл

@ -525,7 +525,6 @@ struct se_cmd {
#define CMD_T_COMPLETE (1 << 2) #define CMD_T_COMPLETE (1 << 2)
#define CMD_T_SENT (1 << 4) #define CMD_T_SENT (1 << 4)
#define CMD_T_STOP (1 << 5) #define CMD_T_STOP (1 << 5)
#define CMD_T_FAILED (1 << 6)
#define CMD_T_DEV_ACTIVE (1 << 7) #define CMD_T_DEV_ACTIVE (1 << 7)
#define CMD_T_REQUEST_STOP (1 << 8) #define CMD_T_REQUEST_STOP (1 << 8)
#define CMD_T_BUSY (1 << 9) #define CMD_T_BUSY (1 << 9)