Skip to content

Commit

Permalink
tcm_fc: Add abort flag for gracefully handling exchange timeout
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mark Rustad authored and Nicholas Bellinger committed Apr 7, 2012
1 parent dd775ae commit e1c4038
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 2 deletions.
1 change: 1 addition & 0 deletions drivers/target/tcm_fc/tcm_fc.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ struct ft_cmd {
/* Local sense buffer */
unsigned char ft_sense_buffer[TRANSPORT_SENSE_BUFFER];
u32 was_ddp_setup:1; /* Set only if ddp is setup */
u32 aborted:1; /* Set if aborted by reset or timeout */
struct scatterlist *sg; /* Set only if DDP is setup */
u32 sg_cnt; /* No. of item in scatterlist */
};
Expand Down
10 changes: 8 additions & 2 deletions drivers/target/tcm_fc/tfc_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions drivers/target/tcm_fc/tfc_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
void *from;
void *to = NULL;

if (cmd->aborted)
return 0;
ep = fc_seq_exch(cmd->seq);
lport = ep->lp;
cmd->seq = lport->tt.seq_start_next(cmd->seq);
Expand Down

0 comments on commit e1c4038

Please sign in to comment.