Commit f200dad9 authored by Martin K. Petersen's avatar Martin K. Petersen

Merge patch series "libfc: fixup command abort handling"

Hannes Reinecke <hare@kernel.org> says:

Hi all,

when testing command timeout with the help of XDP I found that
scsi_try_to_abort_cmd() would always return 'SUCCESS' for FCoE, even
if no commands could be sent over the wire.  Which is not only
surprising, but also can lead to data corruption as commands were
never aborted.  Root cause was that aborts had been sent twice, once
from FC error recovery and once from SCSI EH, with the former inducing
the latter to assume that the command was already aborted.

As usual, comments and reviews are welcome.

Link: https://lore.kernel.org/r/20231129165832.224100-1-hare@kernel.orgSigned-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parents aef6ac12 be40572c
...@@ -265,6 +265,11 @@ static int fc_fcp_send_abort(struct fc_fcp_pkt *fsp) ...@@ -265,6 +265,11 @@ static int fc_fcp_send_abort(struct fc_fcp_pkt *fsp)
if (!fsp->seq_ptr) if (!fsp->seq_ptr)
return -EINVAL; return -EINVAL;
if (fsp->state & FC_SRB_ABORT_PENDING) {
FC_FCP_DBG(fsp, "abort already pending\n");
return -EBUSY;
}
this_cpu_inc(fsp->lp->stats->FcpPktAborts); this_cpu_inc(fsp->lp->stats->FcpPktAborts);
fsp->state |= FC_SRB_ABORT_PENDING; fsp->state |= FC_SRB_ABORT_PENDING;
...@@ -1671,7 +1676,7 @@ static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) ...@@ -1671,7 +1676,7 @@ static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
fc_fcp_rec(fsp); fc_fcp_rec(fsp);
else else
fc_fcp_recovery(fsp, FC_ERROR); fc_fcp_recovery(fsp, FC_TIMED_OUT);
break; break;
} }
fc_fcp_unlock_pkt(fsp); fc_fcp_unlock_pkt(fsp);
...@@ -1690,11 +1695,12 @@ static void fc_fcp_recovery(struct fc_fcp_pkt *fsp, u8 code) ...@@ -1690,11 +1695,12 @@ static void fc_fcp_recovery(struct fc_fcp_pkt *fsp, u8 code)
fsp->status_code = code; fsp->status_code = code;
fsp->cdb_status = 0; fsp->cdb_status = 0;
fsp->io_status = 0; fsp->io_status = 0;
/* if (!fsp->cmd)
* if this fails then we let the scsi command timer fire and /*
* scsi-ml escalate. * Only abort non-scsi commands; otherwise let the
*/ * scsi command timer fire and scsi-ml escalate.
fc_fcp_send_abort(fsp); */
fc_fcp_send_abort(fsp);
} }
/** /**
...@@ -2056,9 +2062,9 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) ...@@ -2056,9 +2062,9 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
sc_cmd->result = (DID_PARITY << 16); sc_cmd->result = (DID_PARITY << 16);
break; break;
case FC_TIMED_OUT: case FC_TIMED_OUT:
FC_FCP_DBG(fsp, "Returning DID_BUS_BUSY to scsi-ml " FC_FCP_DBG(fsp, "Returning DID_TIME_OUT to scsi-ml "
"due to FC_TIMED_OUT\n"); "due to FC_TIMED_OUT\n");
sc_cmd->result = (DID_BUS_BUSY << 16) | fsp->io_status; sc_cmd->result = (DID_TIME_OUT << 16);
break; break;
default: default:
FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml " FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml "
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment