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:
@@ -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,
|
se_cmd->se_tmr_req = core_tmr_alloc_req(se_cmd, (void *)tl_tmr,
|
||||||
TMR_LUN_RESET);
|
TMR_LUN_RESET);
|
||||||
if (!se_cmd->se_tmr_req)
|
if (IS_ERR(se_cmd->se_tmr_req))
|
||||||
goto release;
|
goto release;
|
||||||
/*
|
/*
|
||||||
* Locate the underlying TCM struct se_lun from sc->device->lun
|
* 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 se_portal_group *se_tpg;
|
||||||
struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
|
struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
|
||||||
struct tcm_loop_nexus *tl_nexus;
|
struct tcm_loop_nexus *tl_nexus;
|
||||||
|
int ret = -ENOMEM;
|
||||||
|
|
||||||
if (tl_tpg->tl_hba->tl_nexus) {
|
if (tl_tpg->tl_hba->tl_nexus) {
|
||||||
printk(KERN_INFO "tl_tpg->tl_hba->tl_nexus already exists\n");
|
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
|
* Initialize the struct se_session pointer
|
||||||
*/
|
*/
|
||||||
tl_nexus->se_sess = transport_init_session();
|
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;
|
goto out;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Since we are running in 'demo mode' this call with generate a
|
* 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
|
* 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:
|
out:
|
||||||
kfree(tl_nexus);
|
kfree(tl_nexus);
|
||||||
return -ENOMEM;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tcm_loop_drop_nexus(
|
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
|
* the fabric protocol_id set in tcm_loop_make_scsi_hba(), and call
|
||||||
* tcm_loop_make_nexus()
|
* 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"
|
printk(KERN_ERR "Emulated NAA Sas Address: %s, exceeds"
|
||||||
" max: %d\n", page, TL_WWN_ADDR_LEN);
|
" max: %d\n", page, TL_WWN_ADDR_LEN);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -1321,7 +1324,7 @@ struct se_wwn *tcm_loop_make_scsi_hba(
|
|||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
check_len:
|
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"
|
printk(KERN_ERR "Emulated NAA %s Address: %s, exceeds"
|
||||||
" max: %d\n", name, tcm_loop_dump_proto_id(tl_hba),
|
" max: %d\n", name, tcm_loop_dump_proto_id(tl_hba),
|
||||||
TL_WWN_ADDR_LEN);
|
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");
|
printk(KERN_ERR "Unable to locate passed fabric name\n");
|
||||||
return NULL;
|
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"
|
printk(KERN_ERR "Passed name: %s exceeds TARGET_FABRIC"
|
||||||
"_NAME_SIZE\n", name);
|
"_NAME_SIZE\n", name);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -312,7 +312,7 @@ struct target_fabric_configfs *target_fabric_configfs_init(
|
|||||||
|
|
||||||
tf = kzalloc(sizeof(struct target_fabric_configfs), GFP_KERNEL);
|
tf = kzalloc(sizeof(struct target_fabric_configfs), GFP_KERNEL);
|
||||||
if (!(tf))
|
if (!(tf))
|
||||||
return ERR_PTR(-ENOMEM);
|
return NULL;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&tf->tf_list);
|
INIT_LIST_HEAD(&tf->tf_list);
|
||||||
atomic_set(&tf->tf_access_cnt, 0);
|
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;
|
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"
|
printk(KERN_ERR "Emulated VPD Unit Serial exceeds"
|
||||||
" INQUIRY_VPD_SERIAL_LEN: %d\n", INQUIRY_VPD_SERIAL_LEN);
|
" INQUIRY_VPD_SERIAL_LEN: %d\n", INQUIRY_VPD_SERIAL_LEN);
|
||||||
return -EOVERFLOW;
|
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);
|
transport_dump_vpd_proto_id(vpd, buf, VPD_TMP_BUF_SIZE);
|
||||||
|
|
||||||
if ((len + strlen(buf) > PAGE_SIZE))
|
if ((len + strlen(buf) >= PAGE_SIZE))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
len += sprintf(page+len, "%s", buf);
|
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); \
|
memset(buf, 0, VPD_TMP_BUF_SIZE); \
|
||||||
transport_dump_vpd_assoc(vpd, buf, 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; \
|
break; \
|
||||||
len += sprintf(page+len, "%s", buf); \
|
len += sprintf(page+len, "%s", buf); \
|
||||||
\
|
\
|
||||||
memset(buf, 0, VPD_TMP_BUF_SIZE); \
|
memset(buf, 0, VPD_TMP_BUF_SIZE); \
|
||||||
transport_dump_vpd_ident_type(vpd, buf, 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; \
|
break; \
|
||||||
len += sprintf(page+len, "%s", buf); \
|
len += sprintf(page+len, "%s", buf); \
|
||||||
\
|
\
|
||||||
memset(buf, 0, VPD_TMP_BUF_SIZE); \
|
memset(buf, 0, VPD_TMP_BUF_SIZE); \
|
||||||
transport_dump_vpd_ident(vpd, buf, 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; \
|
break; \
|
||||||
len += sprintf(page+len, "%s", buf); \
|
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,
|
&i_buf[0] : "", pr_reg->pr_res_key,
|
||||||
pr_reg->pr_res_generation);
|
pr_reg->pr_res_generation);
|
||||||
|
|
||||||
if ((len + strlen(buf) > PAGE_SIZE))
|
if ((len + strlen(buf) >= PAGE_SIZE))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
len += sprintf(page+len, "%s", buf);
|
len += sprintf(page+len, "%s", buf);
|
||||||
@@ -1496,7 +1496,7 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
|
|||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out;
|
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="
|
printk(KERN_ERR "APTPL metadata initiator_node="
|
||||||
" exceeds PR_APTPL_MAX_IPORT_LEN: %d\n",
|
" exceeds PR_APTPL_MAX_IPORT_LEN: %d\n",
|
||||||
PR_APTPL_MAX_IPORT_LEN);
|
PR_APTPL_MAX_IPORT_LEN);
|
||||||
@@ -1510,7 +1510,7 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
|
|||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (strlen(isid) > PR_REG_ISID_LEN) {
|
if (strlen(isid) >= PR_REG_ISID_LEN) {
|
||||||
printk(KERN_ERR "APTPL metadata initiator_isid"
|
printk(KERN_ERR "APTPL metadata initiator_isid"
|
||||||
"= exceeds PR_REG_ISID_LEN: %d\n",
|
"= exceeds PR_REG_ISID_LEN: %d\n",
|
||||||
PR_REG_ISID_LEN);
|
PR_REG_ISID_LEN);
|
||||||
@@ -1571,7 +1571,7 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
|
|||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out;
|
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="
|
printk(KERN_ERR "APTPL metadata target_node="
|
||||||
" exceeds PR_APTPL_MAX_TPORT_LEN: %d\n",
|
" exceeds PR_APTPL_MAX_TPORT_LEN: %d\n",
|
||||||
PR_APTPL_MAX_TPORT_LEN);
|
PR_APTPL_MAX_TPORT_LEN);
|
||||||
@@ -3052,7 +3052,7 @@ static struct config_group *target_core_call_addhbatotarget(
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
memset(buf, 0, TARGET_CORE_NAME_MAX_LEN);
|
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"
|
printk(KERN_ERR "Passed *name strlen(): %d exceeds"
|
||||||
" TARGET_CORE_NAME_MAX_LEN: %d\n", (int)strlen(name),
|
" TARGET_CORE_NAME_MAX_LEN: %d\n", (int)strlen(name),
|
||||||
TARGET_CORE_NAME_MAX_LEN);
|
TARGET_CORE_NAME_MAX_LEN);
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ int transport_get_lun_for_tmr(
|
|||||||
&SE_NODE_ACL(se_sess)->device_list[unpacked_lun];
|
&SE_NODE_ACL(se_sess)->device_list[unpacked_lun];
|
||||||
if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) {
|
if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) {
|
||||||
se_lun = se_cmd->se_lun = se_tmr->tmr_lun = deve->se_lun;
|
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->pr_res_key = deve->pr_res_key;
|
||||||
se_cmd->orig_fe_lun = unpacked_lun;
|
se_cmd->orig_fe_lun = unpacked_lun;
|
||||||
se_cmd->se_orig_obj_ptr = SE_LUN(se_cmd)->lun_se_dev;
|
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;
|
se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
se_tmr->tmr_dev = dev;
|
||||||
|
|
||||||
spin_lock(&dev->se_tmr_lock);
|
spin_lock(&dev->se_tmr_lock);
|
||||||
list_add_tail(&se_tmr->tmr_list, &dev->dev_tmr_list);
|
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_lun_acl *lacl;
|
||||||
struct se_node_acl *nacl;
|
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",
|
printk(KERN_ERR "%s InitiatorName exceeds maximum size.\n",
|
||||||
TPG_TFO(tpg)->get_fabric_name());
|
TPG_TFO(tpg)->get_fabric_name());
|
||||||
*ret = -EOVERFLOW;
|
*ret = -EOVERFLOW;
|
||||||
|
|||||||
@@ -1916,7 +1916,7 @@ static int __core_scsi3_update_aptpl_buf(
|
|||||||
pr_reg->pr_res_mapped_lun);
|
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"
|
printk(KERN_ERR "Unable to update renaming"
|
||||||
" APTPL metadata\n");
|
" APTPL metadata\n");
|
||||||
spin_unlock(&T10_RES(su_dev)->registration_lock);
|
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),
|
TPG_TFO(tpg)->tpg_get_tag(tpg),
|
||||||
lun->lun_sep->sep_rtpi, lun->unpacked_lun, reg_count);
|
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"
|
printk(KERN_ERR "Unable to update renaming"
|
||||||
" APTPL metadata\n");
|
" APTPL metadata\n");
|
||||||
spin_unlock(&T10_RES(su_dev)->registration_lock);
|
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(iov, 0, sizeof(struct iovec));
|
||||||
memset(path, 0, 512);
|
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"
|
printk(KERN_ERR "WWN value for struct se_device does not fit"
|
||||||
" into path buffer\n");
|
" into path buffer\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -75,10 +75,16 @@ void core_tmr_release_req(
|
|||||||
{
|
{
|
||||||
struct se_device *dev = tmr->tmr_dev;
|
struct se_device *dev = tmr->tmr_dev;
|
||||||
|
|
||||||
|
if (!dev) {
|
||||||
|
kmem_cache_free(se_tmr_req_cache, tmr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock(&dev->se_tmr_lock);
|
spin_lock(&dev->se_tmr_lock);
|
||||||
list_del(&tmr->tmr_list);
|
list_del(&tmr->tmr_list);
|
||||||
kmem_cache_free(se_tmr_req_cache, tmr);
|
|
||||||
spin_unlock(&dev->se_tmr_lock);
|
spin_unlock(&dev->se_tmr_lock);
|
||||||
|
|
||||||
|
kmem_cache_free(se_tmr_req_cache, tmr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void core_tmr_handle_tas_abort(
|
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)
|
void transport_deregister_session_configfs(struct se_session *se_sess)
|
||||||
{
|
{
|
||||||
struct se_node_acl *se_nacl;
|
struct se_node_acl *se_nacl;
|
||||||
|
unsigned long flags;
|
||||||
/*
|
/*
|
||||||
* Used by struct se_node_acl's under ConfigFS to locate active struct se_session
|
* Used by struct se_node_acl's under ConfigFS to locate active struct se_session
|
||||||
*/
|
*/
|
||||||
se_nacl = se_sess->se_node_acl;
|
se_nacl = se_sess->se_node_acl;
|
||||||
if ((se_nacl)) {
|
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);
|
list_del(&se_sess->sess_acl_list);
|
||||||
/*
|
/*
|
||||||
* If the session list is empty, then clear the pointer.
|
* 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,
|
se_nacl->acl_sess_list.prev,
|
||||||
struct se_session, sess_acl_list);
|
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);
|
EXPORT_SYMBOL(transport_deregister_session_configfs);
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ enum ft_cmd_state {
|
|||||||
*/
|
*/
|
||||||
struct ft_cmd {
|
struct ft_cmd {
|
||||||
enum ft_cmd_state state;
|
enum ft_cmd_state state;
|
||||||
u16 lun; /* LUN from request */
|
u32 lun; /* LUN from request */
|
||||||
struct ft_sess *sess; /* session held for cmd */
|
struct ft_sess *sess; /* session held for cmd */
|
||||||
struct fc_seq *seq; /* sequence in exchange mgr */
|
struct fc_seq *seq; /* sequence in exchange mgr */
|
||||||
struct se_cmd se_cmd; /* Local TCM I/O descriptor */
|
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);
|
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)
|
static void ft_queue_cmd(struct ft_sess *sess, struct ft_cmd *cmd)
|
||||||
{
|
{
|
||||||
struct se_queue_obj *qobj;
|
struct se_queue_obj *qobj;
|
||||||
@@ -418,6 +395,7 @@ static void ft_send_tm(struct ft_cmd *cmd)
|
|||||||
{
|
{
|
||||||
struct se_tmr_req *tmr;
|
struct se_tmr_req *tmr;
|
||||||
struct fcp_cmnd *fcp;
|
struct fcp_cmnd *fcp;
|
||||||
|
struct ft_sess *sess;
|
||||||
u8 tm_func;
|
u8 tm_func;
|
||||||
|
|
||||||
fcp = fc_frame_payload_get(cmd->req_frame, sizeof(*fcp));
|
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) {
|
switch (fcp->fc_tm_flags) {
|
||||||
case FCP_TMF_LUN_RESET:
|
case FCP_TMF_LUN_RESET:
|
||||||
tm_func = TMR_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;
|
break;
|
||||||
case FCP_TMF_TGT_RESET:
|
case FCP_TMF_TGT_RESET:
|
||||||
tm_func = TMR_TARGET_WARM_RESET;
|
tm_func = TMR_TARGET_WARM_RESET;
|
||||||
@@ -463,6 +434,36 @@ static void ft_send_tm(struct ft_cmd *cmd)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cmd->se_cmd.se_tmr_req = tmr;
|
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);
|
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);
|
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) {
|
if (ret < 0) {
|
||||||
ft_dump_cmd(cmd, __func__);
|
ft_dump_cmd(cmd, __func__);
|
||||||
transport_send_check_condition_and_sense(&cmd->se_cmd,
|
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 */
|
/* XXX For now, initiator will retry */
|
||||||
if (printk_ratelimit())
|
if (printk_ratelimit())
|
||||||
printk(KERN_ERR "%s: Failed to send frame %p, "
|
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",
|
"lso_max <0x%x>\n",
|
||||||
__func__, fp, ep->xid,
|
__func__, fp, ep->xid,
|
||||||
remaining, lport->lso_max);
|
remaining, lport->lso_max);
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id,
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
sess->se_sess = transport_init_session();
|
sess->se_sess = transport_init_session();
|
||||||
if (!sess->se_sess) {
|
if (IS_ERR(sess->se_sess)) {
|
||||||
kfree(sess);
|
kfree(sess);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -332,7 +332,7 @@ void ft_sess_close(struct se_session *se_sess)
|
|||||||
lport = sess->tport->lport;
|
lport = sess->tport->lport;
|
||||||
port_id = sess->port_id;
|
port_id = sess->port_id;
|
||||||
if (port_id == -1) {
|
if (port_id == -1) {
|
||||||
mutex_lock(&ft_lport_lock);
|
mutex_unlock(&ft_lport_lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
FT_SESS_DBG("port_id %x\n", port_id);
|
FT_SESS_DBG("port_id %x\n", port_id);
|
||||||
|
|||||||
Reference in New Issue
Block a user