From 7d680f3b74dd6f0f57569eeeee8c257790ceaa96 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 21 Dec 2011 14:13:47 -0500 Subject: target: replace various cmd flags with a transport state Replace various atomic_ts used as flags in struct se_cmd with a single transport_state bitmap that requires t_state_lock to be held for modifications. In the target core that assumption generally is true, but some recently added code in the SRP target had to grow new lock calls. I can't say I like the way how it messes with the command state directly, but let's leave that for later. (Re-add missing ib_srpt.c changes that nab dropped..) Signed-off-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/infiniband/ulp/srpt/ib_srpt.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 2b73d43cd69..e1e6b5b03c9 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -1378,7 +1378,9 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx) break; case SRPT_STATE_NEED_DATA: /* DMA_TO_DEVICE (write) - RDMA read error. */ - atomic_set(&ioctx->cmd.transport_lun_stop, 1); + spin_lock_irqsave(&ioctx->cmd.t_state_lock, flags); + ioctx->cmd.transport_state |= CMD_T_LUN_STOP; + spin_unlock_irqrestore(&ioctx->cmd.t_state_lock, flags); transport_generic_handle_data(&ioctx->cmd); break; case SRPT_STATE_CMD_RSP_SENT: @@ -1387,7 +1389,9 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx) * not been received in time. */ srpt_unmap_sg_to_ib_sge(ioctx->ch, ioctx); - atomic_set(&ioctx->cmd.transport_lun_stop, 1); + spin_lock_irqsave(&ioctx->cmd.t_state_lock, flags); + ioctx->cmd.transport_state |= CMD_T_LUN_STOP; + spin_unlock_irqrestore(&ioctx->cmd.t_state_lock, flags); kref_put(&ioctx->kref, srpt_put_send_ioctx_kref); break; case SRPT_STATE_MGMT_RSP_SENT: @@ -1494,6 +1498,7 @@ static void srpt_handle_rdma_err_comp(struct srpt_rdma_ch *ch, { struct se_cmd *cmd; enum srpt_command_state state; + unsigned long flags; cmd = &ioctx->cmd; state = srpt_get_cmd_state(ioctx); @@ -1513,7 +1518,9 @@ static void srpt_handle_rdma_err_comp(struct srpt_rdma_ch *ch, __func__, __LINE__, state); break; case SRPT_RDMA_WRITE_LAST: - atomic_set(&ioctx->cmd.transport_lun_stop, 1); + spin_lock_irqsave(&ioctx->cmd.t_state_lock, flags); + ioctx->cmd.transport_state |= CMD_T_LUN_STOP; + spin_unlock_irqrestore(&ioctx->cmd.t_state_lock, flags); break; default: printk(KERN_ERR "%s[%d]: opcode = %u\n", __func__, -- cgit v1.2.3-70-g09d2 From c8e31f26feeb03dc6f51bff68135cc58431e099b Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Thu, 19 Jan 2012 13:39:17 -0800 Subject: target: Add SCF_SCSI_TMR_CDB usage and drop se_tmr_req_cache Change the test for if a cmd is a tmr request to checking if SCF_SCSI_TMR_CDB (a new flag) is set in cmd->se_cmd_flags. Also remove se_tmr_req_cache usage in favor of kzalloc usage, and make core_tmr_alloc_req() return int + setup se_cmd->se_tmr_req directly and fix up various fabric module usages Cc: Andy Grover Signed-off-by: Nicholas Bellinger --- drivers/infiniband/ulp/srpt/ib_srpt.c | 4 ++-- drivers/target/iscsi/iscsi_target_util.c | 7 +++--- drivers/target/loopback/tcm_loop.c | 13 ++++------- drivers/target/target_core_tmr.c | 15 +++++++----- drivers/target/target_core_transport.c | 26 +++++++-------------- drivers/target/tcm_fc/tfc_cmd.c | 6 ++--- include/target/target_core_base.h | 39 ++++++++++++++++---------------- include/target/target_core_fabric.h | 2 +- 8 files changed, 51 insertions(+), 61 deletions(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index e1e6b5b03c9..3290a57b248 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -1878,8 +1878,8 @@ static void srpt_handle_tsk_mgmt(struct srpt_rdma_ch *ch, TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED; goto process_tmr; } - cmd->se_tmr_req = core_tmr_alloc_req(cmd, NULL, tcm_tmr, GFP_KERNEL); - if (!cmd->se_tmr_req) { + res = core_tmr_alloc_req(cmd, NULL, tcm_tmr, GFP_KERNEL); + if (res < 0) { send_ioctx->cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; send_ioctx->cmd.se_tmr_req->response = TMR_FUNCTION_REJECTED; goto process_tmr; diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 11287e1ece1..4eba86d2bd8 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -229,6 +229,7 @@ struct iscsi_cmd *iscsit_allocate_se_cmd_for_tmr( { struct iscsi_cmd *cmd; struct se_cmd *se_cmd; + int rc; u8 tcm_function; cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); @@ -286,10 +287,8 @@ struct iscsi_cmd *iscsit_allocate_se_cmd_for_tmr( goto out; } - se_cmd->se_tmr_req = core_tmr_alloc_req(se_cmd, - cmd->tmr_req, tcm_function, - GFP_KERNEL); - if (!se_cmd->se_tmr_req) + rc = core_tmr_alloc_req(se_cmd, cmd->tmr_req, tcm_function, GFP_KERNEL); + if (rc < 0) goto out; cmd->tmr_req->se_tmr_req = se_cmd->se_tmr_req; diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index c47ff7f59e5..7cfbcb00b3c 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -187,7 +187,7 @@ static int tcm_loop_check_stop_free(struct se_cmd *se_cmd) * pointer. These will be released directly in tcm_loop_device_reset() * with transport_generic_free_cmd(). */ - if (se_cmd->se_tmr_req) + if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) return 0; /* * Release the struct se_cmd, which will make a callback to release @@ -324,7 +324,7 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc) struct tcm_loop_nexus *tl_nexus; struct tcm_loop_tmr *tl_tmr = NULL; struct tcm_loop_tpg *tl_tpg; - int ret = FAILED; + int ret = FAILED, rc; /* * Locate the tcm_loop_hba_t pointer */ @@ -365,12 +365,9 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc) transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, 0, DMA_NONE, MSG_SIMPLE_TAG, &tl_cmd->tl_sense_buf[0]); - /* - * Allocate the LUN_RESET TMR - */ - se_cmd->se_tmr_req = core_tmr_alloc_req(se_cmd, tl_tmr, - TMR_LUN_RESET, GFP_KERNEL); - if (IS_ERR(se_cmd->se_tmr_req)) + + rc = core_tmr_alloc_req(se_cmd, tl_tmr, TMR_LUN_RESET, GFP_KERNEL); + if (rc < 0) goto release; /* * Locate the underlying TCM struct se_lun from sc->device->lun diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index a5c2e41debf..5d3eb9e6c2e 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c @@ -40,7 +40,7 @@ #include "target_core_alua.h" #include "target_core_pr.h" -struct se_tmr_req *core_tmr_alloc_req( +int core_tmr_alloc_req( struct se_cmd *se_cmd, void *fabric_tmr_ptr, u8 function, @@ -48,17 +48,20 @@ struct se_tmr_req *core_tmr_alloc_req( { struct se_tmr_req *tmr; - tmr = kmem_cache_zalloc(se_tmr_req_cache, gfp_flags); + tmr = kzalloc(sizeof(struct se_tmr_req), gfp_flags); if (!tmr) { pr_err("Unable to allocate struct se_tmr_req\n"); - return ERR_PTR(-ENOMEM); + return -ENOMEM; } + + se_cmd->se_cmd_flags |= SCF_SCSI_TMR_CDB; + se_cmd->se_tmr_req = tmr; tmr->task_cmd = se_cmd; tmr->fabric_tmr_ptr = fabric_tmr_ptr; tmr->function = function; INIT_LIST_HEAD(&tmr->tmr_list); - return tmr; + return 0; } EXPORT_SYMBOL(core_tmr_alloc_req); @@ -69,7 +72,7 @@ void core_tmr_release_req( unsigned long flags; if (!dev) { - kmem_cache_free(se_tmr_req_cache, tmr); + kfree(tmr); return; } @@ -77,7 +80,7 @@ void core_tmr_release_req( list_del(&tmr->tmr_list); spin_unlock_irqrestore(&dev->se_tmr_lock, flags); - kmem_cache_free(se_tmr_req_cache, tmr); + kfree(tmr); } static void core_tmr_handle_tas_abort( diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index affbd4d1446..c10c3653eab 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -58,7 +58,6 @@ static int sub_api_initialized; static struct workqueue_struct *target_completion_wq; static struct kmem_cache *se_sess_cache; -struct kmem_cache *se_tmr_req_cache; struct kmem_cache *se_ua_cache; struct kmem_cache *t10_pr_reg_cache; struct kmem_cache *t10_alua_lu_gp_cache; @@ -82,21 +81,13 @@ static void target_complete_ok_work(struct work_struct *work); int init_se_kmem_caches(void) { - se_tmr_req_cache = kmem_cache_create("se_tmr_cache", - sizeof(struct se_tmr_req), __alignof__(struct se_tmr_req), - 0, NULL); - if (!se_tmr_req_cache) { - pr_err("kmem_cache_create() for struct se_tmr_req" - " failed\n"); - goto out; - } se_sess_cache = kmem_cache_create("se_sess_cache", sizeof(struct se_session), __alignof__(struct se_session), 0, NULL); if (!se_sess_cache) { pr_err("kmem_cache_create() for struct se_session" " failed\n"); - goto out_free_tmr_req_cache; + goto out; } se_ua_cache = kmem_cache_create("se_ua_cache", sizeof(struct se_ua), __alignof__(struct se_ua), @@ -169,8 +160,6 @@ out_free_ua_cache: kmem_cache_destroy(se_ua_cache); out_free_sess_cache: kmem_cache_destroy(se_sess_cache); -out_free_tmr_req_cache: - kmem_cache_destroy(se_tmr_req_cache); out: return -ENOMEM; } @@ -178,7 +167,6 @@ out: void release_se_kmem_caches(void) { destroy_workqueue(target_completion_wq); - kmem_cache_destroy(se_tmr_req_cache); kmem_cache_destroy(se_sess_cache); kmem_cache_destroy(se_ua_cache); kmem_cache_destroy(t10_pr_reg_cache); @@ -553,7 +541,7 @@ static void transport_lun_remove_cmd(struct se_cmd *cmd) void transport_cmd_finish_abort(struct se_cmd *cmd, int remove) { - if (!cmd->se_tmr_req) + if (!(cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) transport_lun_remove_cmd(cmd); if (transport_cmd_check_stop_to_fabric(cmd)) @@ -3367,7 +3355,7 @@ static void transport_release_cmd(struct se_cmd *cmd) { BUG_ON(!cmd->se_tfo); - if (cmd->se_tmr_req) + if (cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) core_tmr_release_req(cmd->se_tmr_req); if (cmd->t_task_cdb != cmd->__t_task_cdb) kfree(cmd->t_task_cdb); @@ -3956,7 +3944,7 @@ queue_full: void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) { if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD)) { - if (wait_for_tasks && cmd->se_tmr_req) + if (wait_for_tasks && (cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) transport_wait_for_tasks(cmd); transport_release_cmd(cmd); @@ -4282,7 +4270,8 @@ bool transport_wait_for_tasks(struct se_cmd *cmd) unsigned long flags; spin_lock_irqsave(&cmd->t_state_lock, flags); - if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD) && !(cmd->se_tmr_req)) { + if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD) && + !(cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) { spin_unlock_irqrestore(&cmd->t_state_lock, flags); return false; } @@ -4290,7 +4279,8 @@ bool transport_wait_for_tasks(struct se_cmd *cmd) * Only perform a possible wait_for_tasks if SCF_SUPPORTED_SAM_OPCODE * has been set in transport_set_supported_SAM_opcode(). */ - if (!(cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) && !cmd->se_tmr_req) { + if (!(cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) && + !(cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) { spin_unlock_irqrestore(&cmd->t_state_lock, flags); return false; } diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index a76661178d6..bdf25593b81 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c @@ -356,6 +356,7 @@ static void ft_send_tm(struct ft_cmd *cmd) struct se_tmr_req *tmr; struct fcp_cmnd *fcp; struct ft_sess *sess; + int rc; u8 tm_func; transport_init_se_cmd(&cmd->se_cmd, &ft_configfs->tf_ops, @@ -392,13 +393,12 @@ static void ft_send_tm(struct ft_cmd *cmd) } pr_debug("alloc tm cmd fn %d\n", tm_func); - tmr = core_tmr_alloc_req(&cmd->se_cmd, cmd, tm_func, GFP_KERNEL); - if (!tmr) { + rc = core_tmr_alloc_req(&cmd->se_cmd, cmd, tm_func, GFP_KERNEL); + if (rc < 0) { pr_debug("alloc failed\n"); ft_send_resp_code_and_free(cmd, FCP_TMF_FAILED); return; } - cmd->se_cmd.se_tmr_req = tmr; switch (fcp->fc_tm_flags) { case FCP_TMF_LUN_RESET: diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 41dd91b9890..9d514e06625 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -169,7 +169,8 @@ enum se_cmd_flags_table { SCF_EMULATED_TASK_SENSE = 0x00000004, SCF_SCSI_DATA_SG_IO_CDB = 0x00000008, SCF_SCSI_CONTROL_SG_IO_CDB = 0x00000010, - SCF_SCSI_NON_DATA_CDB = 0x00000040, + SCF_SCSI_NON_DATA_CDB = 0x00000020, + SCF_SCSI_TMR_CDB = 0x00000040, SCF_SCSI_CDB_EXCEPTION = 0x00000080, SCF_SCSI_RESERVATION_CONFLICT = 0x00000100, SCF_FUA = 0x00000200, @@ -498,6 +499,24 @@ struct se_task { struct completion task_stop_comp; }; +struct se_tmr_req { + /* Task Management function to be performed */ + u8 function; + /* Task Management response to send */ + u8 response; + int call_transport; + /* Reference to ITT that Task Mgmt should be performed */ + u32 ref_task_tag; + /* 64-bit encoded SAM LUN from $FABRIC_MOD TMR header */ + u64 ref_task_lun; + void *fabric_tmr_ptr; + struct se_cmd *task_cmd; + struct se_cmd *ref_cmd; + struct se_device *tmr_dev; + struct se_lun *tmr_lun; + struct list_head tmr_list; +}; + struct se_cmd { /* SAM response code being sent to initiator */ u8 scsi_status; @@ -586,24 +605,6 @@ struct se_cmd { }; -struct se_tmr_req { - /* Task Management function to be performed */ - u8 function; - /* Task Management response to send */ - u8 response; - int call_transport; - /* Reference to ITT that Task Mgmt should be performed */ - u32 ref_task_tag; - /* 64-bit encoded SAM LUN from $FABRIC_MOD TMR header */ - u64 ref_task_lun; - void *fabric_tmr_ptr; - struct se_cmd *task_cmd; - struct se_cmd *ref_cmd; - struct se_device *tmr_dev; - struct se_lun *tmr_lun; - struct list_head tmr_list; -}; - struct se_ua { u8 ua_asc; u8 ua_ascq; diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index d36fad317e7..c5c16efe396 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -139,7 +139,7 @@ void target_wait_for_sess_cmds(struct se_session *, int); int core_alua_check_nonop_delay(struct se_cmd *); -struct se_tmr_req *core_tmr_alloc_req(struct se_cmd *, void *, u8, gfp_t); +int core_tmr_alloc_req(struct se_cmd *, void *, u8, gfp_t); void core_tmr_release_req(struct se_tmr_req *); int transport_generic_handle_tmr(struct se_cmd *); int transport_lookup_tmr_lun(struct se_cmd *, u32); -- cgit v1.2.3-70-g09d2 From c7ec05c82bfd6acf1fd800d628591500805f3179 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Tue, 28 Feb 2012 00:22:12 -0800 Subject: target: Drop unused legacy target_core_fabric_ops API callers This patch drops the following unused legacy API callers from target_core_fabric.h: *) TFO->fall_back_to_erl0() *) TFO->stop_session() *) TFO->sess_logged_in() *) TFO->is_state_remove() This patch also removes the stub usage in loopback, tcm_fc, iscsi_target, and ib_srpt fabric modules. Signed-off-by: Nicholas Bellinger --- drivers/infiniband/ulp/srpt/ib_srpt.c | 28 ------------------ drivers/target/iscsi/iscsi_target_configfs.c | 43 ---------------------------- drivers/target/loopback/tcm_loop.c | 33 --------------------- drivers/target/target_core_configfs.c | 16 ----------- drivers/target/tcm_fc/tcm_fc.h | 4 --- drivers/target/tcm_fc/tfc_cmd.c | 5 ---- drivers/target/tcm_fc/tfc_conf.c | 4 --- drivers/target/tcm_fc/tfc_sess.c | 19 ------------ include/target/target_core_fabric.h | 4 --- 9 files changed, 156 deletions(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 3290a57b248..6735b63d96f 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -3520,25 +3520,6 @@ static void srpt_close_session(struct se_session *se_sess) WARN_ON(res <= 0); } -/** - * To do: Find out whether stop_session() has a meaning for transports - * other than iSCSI. - */ -static void srpt_stop_session(struct se_session *se_sess, int sess_sleep, - int conn_sleep) -{ -} - -static void srpt_reset_nexus(struct se_session *sess) -{ - printk(KERN_ERR "This is the SRP protocol, not iSCSI\n"); -} - -static int srpt_sess_logged_in(struct se_session *se_sess) -{ - return true; -} - /** * srpt_sess_get_index() - Return the value of scsiAttIntrPortIndex (SCSI-MIB). * @@ -3583,11 +3564,6 @@ static u16 srpt_get_fabric_sense_len(void) return 0; } -static int srpt_is_state_remove(struct se_cmd *se_cmd) -{ - return 0; -} - /** * srpt_parse_i_port_id() - Parse an initiator port ID. * @name: ASCII representation of a 128-bit initiator port ID. @@ -3957,9 +3933,6 @@ static struct target_core_fabric_ops srpt_template = { .check_stop_free = srpt_check_stop_free, .shutdown_session = srpt_shutdown_session, .close_session = srpt_close_session, - .stop_session = srpt_stop_session, - .fall_back_to_erl0 = srpt_reset_nexus, - .sess_logged_in = srpt_sess_logged_in, .sess_get_index = srpt_sess_get_index, .sess_get_initiator_sid = NULL, .write_pending = srpt_write_pending, @@ -3972,7 +3945,6 @@ static struct target_core_fabric_ops srpt_template = { .queue_tm_rsp = srpt_queue_response, .get_fabric_sense_len = srpt_get_fabric_sense_len, .set_fabric_sense_len = srpt_set_fabric_sense_len, - .is_state_remove = srpt_is_state_remove, /* * Setup function pointers for generic logic in * target_core_fabric_configfs.c diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index 1174f74f4fb..00c58cc82c8 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -1503,28 +1503,6 @@ static int iscsi_get_cmd_state(struct se_cmd *se_cmd) return cmd->i_state; } -static int iscsi_is_state_remove(struct se_cmd *se_cmd) -{ - struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); - - return (cmd->i_state == ISTATE_REMOVE); -} - -static int lio_sess_logged_in(struct se_session *se_sess) -{ - struct iscsi_session *sess = se_sess->fabric_sess_ptr; - int ret; - /* - * Called with spin_lock_bh(&tpg_lock); and - * spin_lock(&se_tpg->session_lock); held. - */ - spin_lock(&sess->conn_lock); - ret = (sess->session_state != TARG_SESS_STATE_LOGGED_IN); - spin_unlock(&sess->conn_lock); - - return ret; -} - static u32 lio_sess_get_index(struct se_session *se_sess) { struct iscsi_session *sess = se_sess->fabric_sess_ptr; @@ -1718,23 +1696,6 @@ static void lio_tpg_close_session(struct se_session *se_sess) iscsit_close_session(sess); } -static void lio_tpg_stop_session( - struct se_session *se_sess, - int sess_sleep, - int conn_sleep) -{ - struct iscsi_session *sess = se_sess->fabric_sess_ptr; - - iscsit_stop_session(sess, sess_sleep, conn_sleep); -} - -static void lio_tpg_fall_back_to_erl0(struct se_session *se_sess) -{ - struct iscsi_session *sess = se_sess->fabric_sess_ptr; - - iscsit_fall_back_to_erl0(sess); -} - static u32 lio_tpg_get_inst_index(struct se_portal_group *se_tpg) { struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr; @@ -1798,9 +1759,6 @@ int iscsi_target_register_configfs(void) fabric->tf_ops.release_cmd = &lio_release_cmd; fabric->tf_ops.shutdown_session = &lio_tpg_shutdown_session; fabric->tf_ops.close_session = &lio_tpg_close_session; - fabric->tf_ops.stop_session = &lio_tpg_stop_session; - fabric->tf_ops.fall_back_to_erl0 = &lio_tpg_fall_back_to_erl0; - fabric->tf_ops.sess_logged_in = &lio_sess_logged_in; fabric->tf_ops.sess_get_index = &lio_sess_get_index; fabric->tf_ops.sess_get_initiator_sid = &lio_sess_get_initiator_sid; fabric->tf_ops.write_pending = &lio_write_pending; @@ -1814,7 +1772,6 @@ int iscsi_target_register_configfs(void) fabric->tf_ops.queue_tm_rsp = &lio_queue_tm_rsp; fabric->tf_ops.set_fabric_sense_len = &lio_set_fabric_sense_len; fabric->tf_ops.get_fabric_sense_len = &lio_get_fabric_sense_len; - fabric->tf_ops.is_state_remove = &iscsi_is_state_remove; /* * Setup function pointers for generic logic in target_core_fabric_configfs.c */ diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 041673e9d2d..026dffa0ed5 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -736,22 +736,6 @@ static u32 tcm_loop_get_inst_index(struct se_portal_group *se_tpg) return 1; } -static int tcm_loop_is_state_remove(struct se_cmd *se_cmd) -{ - /* - * Assume struct scsi_cmnd is not in remove state.. - */ - return 0; -} - -static int tcm_loop_sess_logged_in(struct se_session *se_sess) -{ - /* - * Assume that TL Nexus is always active - */ - return 1; -} - static u32 tcm_loop_sess_get_index(struct se_session *se_sess) { return 1; @@ -785,19 +769,6 @@ static void tcm_loop_close_session(struct se_session *se_sess) return; }; -static void tcm_loop_stop_session( - struct se_session *se_sess, - int sess_sleep, - int conn_sleep) -{ - return; -} - -static void tcm_loop_fall_back_to_erl0(struct se_session *se_sess) -{ - return; -} - static int tcm_loop_write_pending(struct se_cmd *se_cmd) { /* @@ -1391,9 +1362,6 @@ static int tcm_loop_register_configfs(void) fabric->tf_ops.release_cmd = &tcm_loop_release_cmd; fabric->tf_ops.shutdown_session = &tcm_loop_shutdown_session; fabric->tf_ops.close_session = &tcm_loop_close_session; - fabric->tf_ops.stop_session = &tcm_loop_stop_session; - fabric->tf_ops.fall_back_to_erl0 = &tcm_loop_fall_back_to_erl0; - fabric->tf_ops.sess_logged_in = &tcm_loop_sess_logged_in; fabric->tf_ops.sess_get_index = &tcm_loop_sess_get_index; fabric->tf_ops.sess_get_initiator_sid = NULL; fabric->tf_ops.write_pending = &tcm_loop_write_pending; @@ -1410,7 +1378,6 @@ static int tcm_loop_register_configfs(void) fabric->tf_ops.queue_tm_rsp = &tcm_loop_queue_tm_rsp; fabric->tf_ops.set_fabric_sense_len = &tcm_loop_set_fabric_sense_len; fabric->tf_ops.get_fabric_sense_len = &tcm_loop_get_fabric_sense_len; - fabric->tf_ops.is_state_remove = &tcm_loop_is_state_remove; tf_cg = &fabric->tf_group; /* diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 2ecde0d4d4e..72bd7f5d679 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -421,18 +421,6 @@ static int target_fabric_tf_ops_check( pr_err("Missing tfo->close_session()\n"); return -EINVAL; } - if (!tfo->stop_session) { - pr_err("Missing tfo->stop_session()\n"); - return -EINVAL; - } - if (!tfo->fall_back_to_erl0) { - pr_err("Missing tfo->fall_back_to_erl0()\n"); - return -EINVAL; - } - if (!tfo->sess_logged_in) { - pr_err("Missing tfo->sess_logged_in()\n"); - return -EINVAL; - } if (!tfo->sess_get_index) { pr_err("Missing tfo->sess_get_index()\n"); return -EINVAL; @@ -477,10 +465,6 @@ static int target_fabric_tf_ops_check( pr_err("Missing tfo->get_fabric_sense_len()\n"); return -EINVAL; } - if (!tfo->is_state_remove) { - pr_err("Missing tfo->is_state_remove()\n"); - return -EINVAL; - } /* * We at least require tfo->fabric_make_wwn(), tfo->fabric_drop_wwn() * tfo->fabric_make_tpg() and tfo->fabric_drop_tpg() in diff --git a/drivers/target/tcm_fc/tcm_fc.h b/drivers/target/tcm_fc/tcm_fc.h index 7906b9f8eba..524b9768398 100644 --- a/drivers/target/tcm_fc/tcm_fc.h +++ b/drivers/target/tcm_fc/tcm_fc.h @@ -141,11 +141,8 @@ extern struct target_fabric_configfs *ft_configfs; void ft_sess_put(struct ft_sess *); int ft_sess_shutdown(struct se_session *); void ft_sess_close(struct se_session *); -void ft_sess_stop(struct se_session *, int, int); -int ft_sess_logged_in(struct se_session *); u32 ft_sess_get_index(struct se_session *); u32 ft_sess_get_port_name(struct se_session *, unsigned char *, u32); -void ft_sess_set_erl0(struct se_session *); void ft_lport_add(struct fc_lport *, void *); void ft_lport_del(struct fc_lport *, void *); @@ -163,7 +160,6 @@ int ft_write_pending_status(struct se_cmd *); u32 ft_get_task_tag(struct se_cmd *); int ft_get_cmd_state(struct se_cmd *); int ft_queue_tm_resp(struct se_cmd *); -int ft_is_state_remove(struct se_cmd *); /* * other internal functions. diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index 17ffc82274a..b831461156b 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c @@ -244,11 +244,6 @@ int ft_get_cmd_state(struct se_cmd *se_cmd) return 0; } -int ft_is_state_remove(struct se_cmd *se_cmd) -{ - return 0; /* XXX TBD */ -} - /* * FC sequence response handler for follow-on sequences (data) and aborts. */ diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c index 73852fbc857..f357039349b 100644 --- a/drivers/target/tcm_fc/tfc_conf.c +++ b/drivers/target/tcm_fc/tfc_conf.c @@ -529,9 +529,6 @@ static struct target_core_fabric_ops ft_fabric_ops = { .release_cmd = ft_release_cmd, .shutdown_session = ft_sess_shutdown, .close_session = ft_sess_close, - .stop_session = ft_sess_stop, - .fall_back_to_erl0 = ft_sess_set_erl0, - .sess_logged_in = ft_sess_logged_in, .sess_get_index = ft_sess_get_index, .sess_get_initiator_sid = NULL, .write_pending = ft_write_pending, @@ -544,7 +541,6 @@ static struct target_core_fabric_ops ft_fabric_ops = { .queue_tm_rsp = ft_queue_tm_resp, .get_fabric_sense_len = ft_get_fabric_sense_len, .set_fabric_sense_len = ft_set_fabric_sense_len, - .is_state_remove = ft_is_state_remove, /* * Setup function pointers for generic logic in * target_core_fabric_configfs.c diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c index 4c0507cf808..a1d1f3c8644 100644 --- a/drivers/target/tcm_fc/tfc_sess.c +++ b/drivers/target/tcm_fc/tfc_sess.c @@ -338,20 +338,6 @@ void ft_sess_close(struct se_session *se_sess) synchronize_rcu(); /* let transport deregister happen */ } -void ft_sess_stop(struct se_session *se_sess, int sess_sleep, int conn_sleep) -{ - struct ft_sess *sess = se_sess->fabric_sess_ptr; - - pr_debug("port_id %x\n", sess->port_id); -} - -int ft_sess_logged_in(struct se_session *se_sess) -{ - struct ft_sess *sess = se_sess->fabric_sess_ptr; - - return sess->port_id != -1; -} - u32 ft_sess_get_index(struct se_session *se_sess) { struct ft_sess *sess = se_sess->fabric_sess_ptr; @@ -367,11 +353,6 @@ u32 ft_sess_get_port_name(struct se_session *se_sess, return ft_format_wwn(buf, len, sess->port_name); } -void ft_sess_set_erl0(struct se_session *se_sess) -{ - /* XXX TBD called when out of memory */ -} - /* * libfc ops involving sessions. */ diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 032c48753cf..10c69080960 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -58,9 +58,6 @@ struct target_core_fabric_ops { */ int (*shutdown_session)(struct se_session *); void (*close_session)(struct se_session *); - void (*stop_session)(struct se_session *, int, int); - void (*fall_back_to_erl0)(struct se_session *); - int (*sess_logged_in)(struct se_session *); u32 (*sess_get_index)(struct se_session *); /* * Used only for SCSI fabrics that contain multi-value TransportIDs @@ -78,7 +75,6 @@ struct target_core_fabric_ops { int (*queue_tm_rsp)(struct se_cmd *); u16 (*set_fabric_sense_len)(struct se_cmd *, u32); u16 (*get_fabric_sense_len)(void); - int (*is_state_remove)(struct se_cmd *); /* * fabric module calls for target_core_fabric_configfs.c */ -- cgit v1.2.3-70-g09d2 From 187e70a554e0f0717a65998bc9199945cbbd4692 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Sat, 17 Mar 2012 20:12:36 -0700 Subject: ib_srpt: Fix srpt_handle_cmd send_ioctx->ioctx_kref leak on exception This patch addresses a bug in srpt_handle_cmd() failure handling where send_ioctx->kref is being leaked with the local extra reference after init, causing the expected kref_put() in srpt_handle_send_comp() to not be the final call to invoke srpt_put_send_ioctx_kref() -> transport_generic_free_cmd() and perform se_cmd descriptor memory release. It also fixes a SCF_SCSI_RESERVATION_CONFLICT handling bug where this code is incorrectly falling through to transport_handle_cdb_direct() after invoking srpt_queue_status() to send SAM_STAT_RESERVATION_CONFLICT status. Note this patch is for >= v3.3 mainline code, and current lio-core.git code has already been converted to target_submit_cmd() + se_cmd->cmd_kref usage, and internal ioctx->kref usage has been removed. I'm including this patch now into target-pending/for-next with a CC' for v3.3 stable. Cc: Bart Van Assche Cc: Roland Dreier Cc: stable@vger.kernel.org Signed-off-by: Nicholas Bellinger --- drivers/infiniband/ulp/srpt/ib_srpt.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 6735b63d96f..c3cb907d810 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -1757,6 +1757,7 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch, srp_cmd->tag); cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; + kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref); goto send_sense; } @@ -1764,15 +1765,19 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch, cmd->data_direction = dir; unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_cmd->lun, sizeof(srp_cmd->lun)); - if (transport_lookup_cmd_lun(cmd, unpacked_lun) < 0) + if (transport_lookup_cmd_lun(cmd, unpacked_lun) < 0) { + kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref); goto send_sense; + } ret = transport_generic_allocate_tasks(cmd, srp_cmd->cdb); - if (cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) - srpt_queue_status(cmd); - else if (cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) - goto send_sense; - else - WARN_ON_ONCE(ret); + if (ret < 0) { + kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref); + if (cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) { + srpt_queue_status(cmd); + return 0; + } else + goto send_sense; + } transport_handle_cdb_direct(cmd); return 0; -- cgit v1.2.3-70-g09d2