Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/scsi-post-merge-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/scsi-post-merge-2.6: tcm_fc: Fix conversion spec warning tcm_fc: Fix possible lock to unlock type deadlock tcm_fc: Fix ft_send_tm LUN lookup OOPs target: Fix incorrect strlen() NULL terminator checks target: Drop bogus ERR_PTR usage in target_fabric_configfs_init target: Fix ERR_PTR dereferencing bugs target: Convert transport_deregister_session_configfs nacl_sess_lock to save irq state target: Fix transport_get_lun_for_tmr failure cases [SCSI] target: Convert TASK_ATTR to scsi_tcq.h definitions [SCSI] target: Convert REPORT_LUNs to use int_to_scsilun [SCSI] target: Fix task->task_execute_queue=1 clear bug + LUN_RESET OOPs [SCSI] target: Fix bug with task_sg chained transport_free_dev_tasks release [SCSI] target: Fix interrupt context bug with stats_lock and core_tmr_alloc_req [SCSI] target: Fix multi task->task_sg[] chaining logic bug
This commit is contained in:
commit
7a1f7b3d68
10 changed files with 73 additions and 61 deletions
|
@ -386,7 +386,7 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
|
|||
*/
|
||||
se_cmd->se_tmr_req = core_tmr_alloc_req(se_cmd, (void *)tl_tmr,
|
||||
TMR_LUN_RESET);
|
||||
if (!se_cmd->se_tmr_req)
|
||||
if (IS_ERR(se_cmd->se_tmr_req))
|
||||
goto release;
|
||||
/*
|
||||
* Locate the underlying TCM struct se_lun from sc->device->lun
|
||||
|
@ -1017,6 +1017,7 @@ static int tcm_loop_make_nexus(
|
|||
struct se_portal_group *se_tpg;
|
||||
struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
|
||||
struct tcm_loop_nexus *tl_nexus;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
if (tl_tpg->tl_hba->tl_nexus) {
|
||||
printk(KERN_INFO "tl_tpg->tl_hba->tl_nexus already exists\n");
|
||||
|
@ -1033,8 +1034,10 @@ static int tcm_loop_make_nexus(
|
|||
* Initialize the struct se_session pointer
|
||||
*/
|
||||
tl_nexus->se_sess = transport_init_session();
|
||||
if (!tl_nexus->se_sess)
|
||||
if (IS_ERR(tl_nexus->se_sess)) {
|
||||
ret = PTR_ERR(tl_nexus->se_sess);
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* Since we are running in 'demo mode' this call with generate a
|
||||
* struct se_node_acl for the tcm_loop struct se_portal_group with the SCSI
|
||||
|
@ -1060,7 +1063,7 @@ static int tcm_loop_make_nexus(
|
|||
|
||||
out:
|
||||
kfree(tl_nexus);
|
||||
return -ENOMEM;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tcm_loop_drop_nexus(
|
||||
|
@ -1140,7 +1143,7 @@ static ssize_t tcm_loop_tpg_store_nexus(
|
|||
* the fabric protocol_id set in tcm_loop_make_scsi_hba(), and call
|
||||
* tcm_loop_make_nexus()
|
||||
*/
|
||||
if (strlen(page) > TL_WWN_ADDR_LEN) {
|
||||
if (strlen(page) >= TL_WWN_ADDR_LEN) {
|
||||
printk(KERN_ERR "Emulated NAA Sas Address: %s, exceeds"
|
||||
" max: %d\n", page, TL_WWN_ADDR_LEN);
|
||||
return -EINVAL;
|
||||
|
@ -1321,7 +1324,7 @@ struct se_wwn *tcm_loop_make_scsi_hba(
|
|||
return ERR_PTR(-EINVAL);
|
||||
|
||||
check_len:
|
||||
if (strlen(name) > TL_WWN_ADDR_LEN) {
|
||||
if (strlen(name) >= TL_WWN_ADDR_LEN) {
|
||||
printk(KERN_ERR "Emulated NAA %s Address: %s, exceeds"
|
||||
" max: %d\n", name, tcm_loop_dump_proto_id(tl_hba),
|
||||
TL_WWN_ADDR_LEN);
|
||||
|
|
|
@ -304,7 +304,7 @@ struct target_fabric_configfs *target_fabric_configfs_init(
|
|||
printk(KERN_ERR "Unable to locate passed fabric name\n");
|
||||
return NULL;
|
||||
}
|
||||
if (strlen(name) > TARGET_FABRIC_NAME_SIZE) {
|
||||
if (strlen(name) >= TARGET_FABRIC_NAME_SIZE) {
|
||||
printk(KERN_ERR "Passed name: %s exceeds TARGET_FABRIC"
|
||||
"_NAME_SIZE\n", name);
|
||||
return NULL;
|
||||
|
@ -312,7 +312,7 @@ struct target_fabric_configfs *target_fabric_configfs_init(
|
|||
|
||||
tf = kzalloc(sizeof(struct target_fabric_configfs), GFP_KERNEL);
|
||||
if (!(tf))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
return NULL;
|
||||
|
||||
INIT_LIST_HEAD(&tf->tf_list);
|
||||
atomic_set(&tf->tf_access_cnt, 0);
|
||||
|
@ -851,7 +851,7 @@ static ssize_t target_core_dev_wwn_store_attr_vpd_unit_serial(
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if ((strlen(page) + 1) > INQUIRY_VPD_SERIAL_LEN) {
|
||||
if (strlen(page) >= INQUIRY_VPD_SERIAL_LEN) {
|
||||
printk(KERN_ERR "Emulated VPD Unit Serial exceeds"
|
||||
" INQUIRY_VPD_SERIAL_LEN: %d\n", INQUIRY_VPD_SERIAL_LEN);
|
||||
return -EOVERFLOW;
|
||||
|
@ -917,7 +917,7 @@ static ssize_t target_core_dev_wwn_show_attr_vpd_protocol_identifier(
|
|||
|
||||
transport_dump_vpd_proto_id(vpd, buf, VPD_TMP_BUF_SIZE);
|
||||
|
||||
if ((len + strlen(buf) > PAGE_SIZE))
|
||||
if ((len + strlen(buf) >= PAGE_SIZE))
|
||||
break;
|
||||
|
||||
len += sprintf(page+len, "%s", buf);
|
||||
|
@ -962,19 +962,19 @@ static ssize_t target_core_dev_wwn_show_attr_##_name( \
|
|||
\
|
||||
memset(buf, 0, VPD_TMP_BUF_SIZE); \
|
||||
transport_dump_vpd_assoc(vpd, buf, VPD_TMP_BUF_SIZE); \
|
||||
if ((len + strlen(buf) > PAGE_SIZE)) \
|
||||
if ((len + strlen(buf) >= PAGE_SIZE)) \
|
||||
break; \
|
||||
len += sprintf(page+len, "%s", buf); \
|
||||
\
|
||||
memset(buf, 0, VPD_TMP_BUF_SIZE); \
|
||||
transport_dump_vpd_ident_type(vpd, buf, VPD_TMP_BUF_SIZE); \
|
||||
if ((len + strlen(buf) > PAGE_SIZE)) \
|
||||
if ((len + strlen(buf) >= PAGE_SIZE)) \
|
||||
break; \
|
||||
len += sprintf(page+len, "%s", buf); \
|
||||
\
|
||||
memset(buf, 0, VPD_TMP_BUF_SIZE); \
|
||||
transport_dump_vpd_ident(vpd, buf, VPD_TMP_BUF_SIZE); \
|
||||
if ((len + strlen(buf) > PAGE_SIZE)) \
|
||||
if ((len + strlen(buf) >= PAGE_SIZE)) \
|
||||
break; \
|
||||
len += sprintf(page+len, "%s", buf); \
|
||||
} \
|
||||
|
@ -1299,7 +1299,7 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts(
|
|||
&i_buf[0] : "", pr_reg->pr_res_key,
|
||||
pr_reg->pr_res_generation);
|
||||
|
||||
if ((len + strlen(buf) > PAGE_SIZE))
|
||||
if ((len + strlen(buf) >= PAGE_SIZE))
|
||||
break;
|
||||
|
||||
len += sprintf(page+len, "%s", buf);
|
||||
|
@ -1496,7 +1496,7 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
|
|||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
if (strlen(i_port) > PR_APTPL_MAX_IPORT_LEN) {
|
||||
if (strlen(i_port) >= PR_APTPL_MAX_IPORT_LEN) {
|
||||
printk(KERN_ERR "APTPL metadata initiator_node="
|
||||
" exceeds PR_APTPL_MAX_IPORT_LEN: %d\n",
|
||||
PR_APTPL_MAX_IPORT_LEN);
|
||||
|
@ -1510,7 +1510,7 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
|
|||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
if (strlen(isid) > PR_REG_ISID_LEN) {
|
||||
if (strlen(isid) >= PR_REG_ISID_LEN) {
|
||||
printk(KERN_ERR "APTPL metadata initiator_isid"
|
||||
"= exceeds PR_REG_ISID_LEN: %d\n",
|
||||
PR_REG_ISID_LEN);
|
||||
|
@ -1571,7 +1571,7 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
|
|||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
if (strlen(t_port) > PR_APTPL_MAX_TPORT_LEN) {
|
||||
if (strlen(t_port) >= PR_APTPL_MAX_TPORT_LEN) {
|
||||
printk(KERN_ERR "APTPL metadata target_node="
|
||||
" exceeds PR_APTPL_MAX_TPORT_LEN: %d\n",
|
||||
PR_APTPL_MAX_TPORT_LEN);
|
||||
|
@ -3052,7 +3052,7 @@ static struct config_group *target_core_call_addhbatotarget(
|
|||
int ret;
|
||||
|
||||
memset(buf, 0, TARGET_CORE_NAME_MAX_LEN);
|
||||
if (strlen(name) > TARGET_CORE_NAME_MAX_LEN) {
|
||||
if (strlen(name) >= TARGET_CORE_NAME_MAX_LEN) {
|
||||
printk(KERN_ERR "Passed *name strlen(): %d exceeds"
|
||||
" TARGET_CORE_NAME_MAX_LEN: %d\n", (int)strlen(name),
|
||||
TARGET_CORE_NAME_MAX_LEN);
|
||||
|
|
|
@ -192,7 +192,7 @@ int transport_get_lun_for_tmr(
|
|||
&SE_NODE_ACL(se_sess)->device_list[unpacked_lun];
|
||||
if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) {
|
||||
se_lun = se_cmd->se_lun = se_tmr->tmr_lun = deve->se_lun;
|
||||
dev = se_tmr->tmr_dev = se_lun->lun_se_dev;
|
||||
dev = se_lun->lun_se_dev;
|
||||
se_cmd->pr_res_key = deve->pr_res_key;
|
||||
se_cmd->orig_fe_lun = unpacked_lun;
|
||||
se_cmd->se_orig_obj_ptr = SE_LUN(se_cmd)->lun_se_dev;
|
||||
|
@ -216,6 +216,7 @@ int transport_get_lun_for_tmr(
|
|||
se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
|
||||
return -1;
|
||||
}
|
||||
se_tmr->tmr_dev = dev;
|
||||
|
||||
spin_lock(&dev->se_tmr_lock);
|
||||
list_add_tail(&se_tmr->tmr_list, &dev->dev_tmr_list);
|
||||
|
@ -1430,7 +1431,7 @@ struct se_lun_acl *core_dev_init_initiator_node_lun_acl(
|
|||
struct se_lun_acl *lacl;
|
||||
struct se_node_acl *nacl;
|
||||
|
||||
if (strlen(initiatorname) > TRANSPORT_IQN_LEN) {
|
||||
if (strlen(initiatorname) >= TRANSPORT_IQN_LEN) {
|
||||
printk(KERN_ERR "%s InitiatorName exceeds maximum size.\n",
|
||||
TPG_TFO(tpg)->get_fabric_name());
|
||||
*ret = -EOVERFLOW;
|
||||
|
|
|
@ -1916,7 +1916,7 @@ static int __core_scsi3_update_aptpl_buf(
|
|||
pr_reg->pr_res_mapped_lun);
|
||||
}
|
||||
|
||||
if ((len + strlen(tmp) > pr_aptpl_buf_len)) {
|
||||
if ((len + strlen(tmp) >= pr_aptpl_buf_len)) {
|
||||
printk(KERN_ERR "Unable to update renaming"
|
||||
" APTPL metadata\n");
|
||||
spin_unlock(&T10_RES(su_dev)->registration_lock);
|
||||
|
@ -1934,7 +1934,7 @@ static int __core_scsi3_update_aptpl_buf(
|
|||
TPG_TFO(tpg)->tpg_get_tag(tpg),
|
||||
lun->lun_sep->sep_rtpi, lun->unpacked_lun, reg_count);
|
||||
|
||||
if ((len + strlen(tmp) > pr_aptpl_buf_len)) {
|
||||
if ((len + strlen(tmp) >= pr_aptpl_buf_len)) {
|
||||
printk(KERN_ERR "Unable to update renaming"
|
||||
" APTPL metadata\n");
|
||||
spin_unlock(&T10_RES(su_dev)->registration_lock);
|
||||
|
@ -1986,7 +1986,7 @@ static int __core_scsi3_write_aptpl_to_file(
|
|||
memset(iov, 0, sizeof(struct iovec));
|
||||
memset(path, 0, 512);
|
||||
|
||||
if (strlen(&wwn->unit_serial[0]) > 512) {
|
||||
if (strlen(&wwn->unit_serial[0]) >= 512) {
|
||||
printk(KERN_ERR "WWN value for struct se_device does not fit"
|
||||
" into path buffer\n");
|
||||
return -1;
|
||||
|
|
|
@ -75,10 +75,16 @@ void core_tmr_release_req(
|
|||
{
|
||||
struct se_device *dev = tmr->tmr_dev;
|
||||
|
||||
if (!dev) {
|
||||
kmem_cache_free(se_tmr_req_cache, tmr);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock(&dev->se_tmr_lock);
|
||||
list_del(&tmr->tmr_list);
|
||||
kmem_cache_free(se_tmr_req_cache, tmr);
|
||||
spin_unlock(&dev->se_tmr_lock);
|
||||
|
||||
kmem_cache_free(se_tmr_req_cache, tmr);
|
||||
}
|
||||
|
||||
static void core_tmr_handle_tas_abort(
|
||||
|
|
|
@ -536,13 +536,13 @@ EXPORT_SYMBOL(transport_register_session);
|
|||
void transport_deregister_session_configfs(struct se_session *se_sess)
|
||||
{
|
||||
struct se_node_acl *se_nacl;
|
||||
|
||||
unsigned long flags;
|
||||
/*
|
||||
* Used by struct se_node_acl's under ConfigFS to locate active struct se_session
|
||||
*/
|
||||
se_nacl = se_sess->se_node_acl;
|
||||
if ((se_nacl)) {
|
||||
spin_lock_irq(&se_nacl->nacl_sess_lock);
|
||||
spin_lock_irqsave(&se_nacl->nacl_sess_lock, flags);
|
||||
list_del(&se_sess->sess_acl_list);
|
||||
/*
|
||||
* If the session list is empty, then clear the pointer.
|
||||
|
@ -556,7 +556,7 @@ void transport_deregister_session_configfs(struct se_session *se_sess)
|
|||
se_nacl->acl_sess_list.prev,
|
||||
struct se_session, sess_acl_list);
|
||||
}
|
||||
spin_unlock_irq(&se_nacl->nacl_sess_lock);
|
||||
spin_unlock_irqrestore(&se_nacl->nacl_sess_lock, flags);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(transport_deregister_session_configfs);
|
||||
|
|
|
@ -144,7 +144,7 @@ enum ft_cmd_state {
|
|||
*/
|
||||
struct ft_cmd {
|
||||
enum ft_cmd_state state;
|
||||
u16 lun; /* LUN from request */
|
||||
u32 lun; /* LUN from request */
|
||||
struct ft_sess *sess; /* session held for cmd */
|
||||
struct fc_seq *seq; /* sequence in exchange mgr */
|
||||
struct se_cmd se_cmd; /* Local TCM I/O descriptor */
|
||||
|
|
|
@ -94,29 +94,6 @@ void ft_dump_cmd(struct ft_cmd *cmd, const char *caller)
|
|||
16, 4, cmd->cdb, MAX_COMMAND_SIZE, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get LUN from CDB.
|
||||
*/
|
||||
static int ft_get_lun_for_cmd(struct ft_cmd *cmd, u8 *lunp)
|
||||
{
|
||||
u64 lun;
|
||||
|
||||
lun = lunp[1];
|
||||
switch (lunp[0] >> 6) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
lun |= (lunp[0] & 0x3f) << 8;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
if (lun >= TRANSPORT_MAX_LUNS_PER_TPG)
|
||||
return -1;
|
||||
cmd->lun = lun;
|
||||
return transport_get_lun_for_cmd(&cmd->se_cmd, NULL, lun);
|
||||
}
|
||||
|
||||
static void ft_queue_cmd(struct ft_sess *sess, struct ft_cmd *cmd)
|
||||
{
|
||||
struct se_queue_obj *qobj;
|
||||
|
@ -418,6 +395,7 @@ static void ft_send_tm(struct ft_cmd *cmd)
|
|||
{
|
||||
struct se_tmr_req *tmr;
|
||||
struct fcp_cmnd *fcp;
|
||||
struct ft_sess *sess;
|
||||
u8 tm_func;
|
||||
|
||||
fcp = fc_frame_payload_get(cmd->req_frame, sizeof(*fcp));
|
||||
|
@ -425,13 +403,6 @@ static void ft_send_tm(struct ft_cmd *cmd)
|
|||
switch (fcp->fc_tm_flags) {
|
||||
case FCP_TMF_LUN_RESET:
|
||||
tm_func = TMR_LUN_RESET;
|
||||
if (ft_get_lun_for_cmd(cmd, fcp->fc_lun) < 0) {
|
||||
ft_dump_cmd(cmd, __func__);
|
||||
transport_send_check_condition_and_sense(&cmd->se_cmd,
|
||||
cmd->se_cmd.scsi_sense_reason, 0);
|
||||
ft_sess_put(cmd->sess);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case FCP_TMF_TGT_RESET:
|
||||
tm_func = TMR_TARGET_WARM_RESET;
|
||||
|
@ -463,6 +434,36 @@ static void ft_send_tm(struct ft_cmd *cmd)
|
|||
return;
|
||||
}
|
||||
cmd->se_cmd.se_tmr_req = tmr;
|
||||
|
||||
switch (fcp->fc_tm_flags) {
|
||||
case FCP_TMF_LUN_RESET:
|
||||
cmd->lun = scsilun_to_int((struct scsi_lun *)fcp->fc_lun);
|
||||
if (transport_get_lun_for_tmr(&cmd->se_cmd, cmd->lun) < 0) {
|
||||
/*
|
||||
* Make sure to clean up newly allocated TMR request
|
||||
* since "unable to handle TMR request because failed
|
||||
* to get to LUN"
|
||||
*/
|
||||
FT_TM_DBG("Failed to get LUN for TMR func %d, "
|
||||
"se_cmd %p, unpacked_lun %d\n",
|
||||
tm_func, &cmd->se_cmd, cmd->lun);
|
||||
ft_dump_cmd(cmd, __func__);
|
||||
sess = cmd->sess;
|
||||
transport_send_check_condition_and_sense(&cmd->se_cmd,
|
||||
cmd->se_cmd.scsi_sense_reason, 0);
|
||||
transport_generic_free_cmd(&cmd->se_cmd, 0, 1, 0);
|
||||
ft_sess_put(sess);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case FCP_TMF_TGT_RESET:
|
||||
case FCP_TMF_CLR_TASK_SET:
|
||||
case FCP_TMF_ABT_TASK_SET:
|
||||
case FCP_TMF_CLR_ACA:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
transport_generic_handle_tmr(&cmd->se_cmd);
|
||||
}
|
||||
|
||||
|
@ -635,7 +636,8 @@ static void ft_send_cmd(struct ft_cmd *cmd)
|
|||
|
||||
fc_seq_exch(cmd->seq)->lp->tt.seq_set_resp(cmd->seq, ft_recv_seq, cmd);
|
||||
|
||||
ret = ft_get_lun_for_cmd(cmd, fcp->fc_lun);
|
||||
cmd->lun = scsilun_to_int((struct scsi_lun *)fcp->fc_lun);
|
||||
ret = transport_get_lun_for_cmd(&cmd->se_cmd, NULL, cmd->lun);
|
||||
if (ret < 0) {
|
||||
ft_dump_cmd(cmd, __func__);
|
||||
transport_send_check_condition_and_sense(&cmd->se_cmd,
|
||||
|
|
|
@ -203,7 +203,7 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
|
|||
/* XXX For now, initiator will retry */
|
||||
if (printk_ratelimit())
|
||||
printk(KERN_ERR "%s: Failed to send frame %p, "
|
||||
"xid <0x%x>, remaining <0x%x>, "
|
||||
"xid <0x%x>, remaining %zu, "
|
||||
"lso_max <0x%x>\n",
|
||||
__func__, fp, ep->xid,
|
||||
remaining, lport->lso_max);
|
||||
|
|
|
@ -229,7 +229,7 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id,
|
|||
return NULL;
|
||||
|
||||
sess->se_sess = transport_init_session();
|
||||
if (!sess->se_sess) {
|
||||
if (IS_ERR(sess->se_sess)) {
|
||||
kfree(sess);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -332,7 +332,7 @@ void ft_sess_close(struct se_session *se_sess)
|
|||
lport = sess->tport->lport;
|
||||
port_id = sess->port_id;
|
||||
if (port_id == -1) {
|
||||
mutex_lock(&ft_lport_lock);
|
||||
mutex_unlock(&ft_lport_lock);
|
||||
return;
|
||||
}
|
||||
FT_SESS_DBG("port_id %x\n", port_id);
|
||||
|
|
Loading…
Reference in a new issue