tcm_fc: Add abort flag for gracefully handling exchange timeout

Add abort flag and use it to terminate processing when an exchange
is timed out or is reset. The abort flag is used in place of the
transport_generic_free_cmd function call in the reset and timeout
cases, because calling that function in that context would free
memory that was in use. The aborted flag allows the lifetime to
be managed in a more normal way, while truncating the processing.

This change eliminates a source of memory corruption which
manifested in a variety of ugly ways.

(nab: Drop unused struct fc_exch *ep in ft_recv_seq)

Signed-off-by: Mark Rustad <mark.d.rustad@intel.com>
Acked-by: Kiran Patil <Kiran.patil@intel.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
此提交包含在:
Mark Rustad
2012-04-03 10:24:41 -07:00
提交者 Nicholas Bellinger
父節點 dd775ae254
當前提交 e1c4038282
共有 3 個檔案被更改,包括 11 行新增2 行删除

查看文件

@@ -121,6 +121,8 @@ int ft_queue_status(struct se_cmd *se_cmd)
struct fc_exch *ep;
size_t len;
if (cmd->aborted)
return 0;
ft_dump_cmd(cmd, __func__);
ep = fc_seq_exch(cmd->seq);
lport = ep->lp;
@@ -187,6 +189,8 @@ int ft_write_pending(struct se_cmd *se_cmd)
ft_dump_cmd(cmd, __func__);
if (cmd->aborted)
return 0;
ep = fc_seq_exch(cmd->seq);
lport = ep->lp;
fp = fc_frame_alloc(lport, sizeof(*txrdy));
@@ -252,10 +256,10 @@ static void ft_recv_seq(struct fc_seq *sp, struct fc_frame *fp, void *arg)
struct ft_cmd *cmd = arg;
struct fc_frame_header *fh;
if (IS_ERR(fp)) {
if (unlikely(IS_ERR(fp))) {
/* XXX need to find cmd if queued */
cmd->seq = NULL;
transport_generic_free_cmd(&cmd->se_cmd, 0);
cmd->aborted = true;
return;
}
@@ -399,6 +403,8 @@ int ft_queue_tm_resp(struct se_cmd *se_cmd)
struct se_tmr_req *tmr = se_cmd->se_tmr_req;
enum fcp_resp_rsp_codes code;
if (cmd->aborted)
return 0;
switch (tmr->response) {
case TMR_FUNCTION_COMPLETE:
code = FCP_TMF_CMPL;