summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2011-11-23 06:41:54 +0100
committerNicholas Bellinger <nab@linux-iscsi.org>2011-12-14 12:42:08 +0100
commit4355a9110eeb2eaf1dd44fcab16ccbd1c8c5fad4 (patch)
tree6cfb4d1fc3cb5c71f67ab158ab41430cfe7a6e0c
parenttarget: Add target_submit_cmd() for process context fabric submission (diff)
downloadlinux-4355a9110eeb2eaf1dd44fcab16ccbd1c8c5fad4.tar.xz
linux-4355a9110eeb2eaf1dd44fcab16ccbd1c8c5fad4.zip
tcm_fc: Convert ft_send_work to use target_submit_cmd
This patch converts the main ft_send_work() I/O path to use target_submit_cmd() with a single se_cmd->cmd_kref reference that is released via the existing ft_check_stop_free() response path callback. It also makes ft_send_tm() use transport_init_se_cmd() and target_get_sess_cmd() to also use single se_cmd->cmd_kref reference. Cc: Christoph Hellwig <hch@lst.de> Cc: Kiran Patil <kiran.patil@intel.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/target/tcm_fc/tfc_cmd.c51
1 files changed, 13 insertions, 38 deletions
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c
index dbbbc8376d01..addc18f727ea 100644
--- a/drivers/target/tcm_fc/tfc_cmd.c
+++ b/drivers/target/tcm_fc/tfc_cmd.c
@@ -363,6 +363,11 @@ static void ft_send_tm(struct ft_cmd *cmd)
struct ft_sess *sess;
u8 tm_func;
+ transport_init_se_cmd(&cmd->se_cmd, &ft_configfs->tf_ops,
+ cmd->sess->se_sess, 0, DMA_NONE, 0,
+ &cmd->ft_sense_buffer[0]);
+ target_get_sess_cmd(cmd->sess->se_sess, &cmd->se_cmd, false);
+
fcp = fc_frame_payload_get(cmd->req_frame, sizeof(*fcp));
switch (fcp->fc_tm_flags) {
@@ -416,7 +421,6 @@ static void ft_send_tm(struct ft_cmd *cmd)
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);
ft_sess_put(sess);
return;
}
@@ -532,7 +536,6 @@ static void ft_send_work(struct work_struct *work)
{
struct ft_cmd *cmd = container_of(work, struct ft_cmd, work);
struct fc_frame_header *fh = fc_frame_header_get(cmd->req_frame);
- struct se_cmd *se_cmd;
struct fcp_cmnd *fcp;
int data_dir = 0;
u32 data_len;
@@ -587,15 +590,6 @@ static void ft_send_work(struct work_struct *work)
data_len = ntohl(fcp->fc_dl);
cmd->cdb = fcp->fc_cdb;
}
-
- se_cmd = &cmd->se_cmd;
- /*
- * Initialize struct se_cmd descriptor from target_core_mod
- * infrastructure
- */
- transport_init_se_cmd(se_cmd, &ft_configfs->tf_ops, cmd->sess->se_sess,
- data_len, data_dir, task_attr,
- &cmd->ft_sense_buffer[0]);
/*
* Check for FCP task management flags
*/
@@ -603,39 +597,20 @@ static void ft_send_work(struct work_struct *work)
ft_send_tm(cmd);
return;
}
-
fc_seq_exch(cmd->seq)->lp->tt.seq_set_resp(cmd->seq, ft_recv_seq, cmd);
-
cmd->lun = scsilun_to_int((struct scsi_lun *)fcp->fc_lun);
- ret = transport_lookup_cmd_lun(&cmd->se_cmd, cmd->lun);
+ /*
+ * Use a single se_cmd->cmd_kref as we expect to release se_cmd
+ * directly from ft_check_stop_free callback in response path.
+ */
+ ret = target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, cmd->cdb,
+ &cmd->ft_sense_buffer[0], cmd->lun, data_len,
+ task_attr, data_dir, 0);
+ pr_debug("r_ctl %x alloc target_submit_cmd %d\n", fh->fh_r_ctl, ret);
if (ret < 0) {
ft_dump_cmd(cmd, __func__);
- transport_send_check_condition_and_sense(&cmd->se_cmd,
- cmd->se_cmd.scsi_sense_reason, 0);
- return;
- }
-
- ret = transport_generic_allocate_tasks(se_cmd, cmd->cdb);
-
- pr_debug("r_ctl %x alloc task ret %d\n", fh->fh_r_ctl, ret);
- ft_dump_cmd(cmd, __func__);
-
- if (ret == -ENOMEM) {
- transport_send_check_condition_and_sense(se_cmd,
- TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
- transport_generic_free_cmd(se_cmd, 0);
- return;
- }
- if (ret == -EINVAL) {
- if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT)
- ft_queue_status(se_cmd);
- else
- transport_send_check_condition_and_sense(se_cmd,
- se_cmd->scsi_sense_reason, 0);
- transport_generic_free_cmd(se_cmd, 0);
return;
}
- transport_handle_cdb_direct(se_cmd);
return;
err: