mirror of
https://github.com/torvalds/linux.git
synced 2024-11-18 01:51:53 +00:00
[SCSI] libfc: Remove the reference to FCP packet from scsi_cmnd in case of error
fc_queuecommand() allocates an FCP packet for each SCSI command and sends it out on the wire. In the process it stores the reference to the FCP packet in the scsi_cmnd structure. Now, in case under stress testing the libfc exchange layer runs out of exchanges the fc_queuecommand() may not be able to send out commands out on the wire. In such a scenario if there is an error in sending the FCP packet out the wire; fc_queuecommand() deletes the FCP packet from internal queue, releases the FCP packet and returns a SCSI_MLQUEUE_HOST_BUSY status to the scsi-ml. But, the reference to the FCP packet set in the scsi_cmnd is not removed from the scsi_cmnd in this code path. This might lead to a crash under stress testing where the scsi_cmnd failed by fc_queuecommand() comes up to fc_eh_abort() via scsi eh thread. fc_eh_abort() will get reference to the FCP packet to be aborted from the scsi_cmnd for further FCP abort related processing and then try to release the FCP packet that has already been released. This patch removes the FCP packet reference from the scsi_cmnd before returning back from fc_queuecommand() in case of an error in sending out the FCP packet. Signed-off-by: Neerav Parikh <Neerav.Parikh@intel.com> Tested-by: Ross Brattain <ross.b.brattain@intel.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
8598212727
commit
c9d24a7618
@ -1084,6 +1084,7 @@ static int fc_fcp_pkt_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp)
|
|||||||
rc = lport->tt.fcp_cmd_send(lport, fsp, fc_fcp_recv);
|
rc = lport->tt.fcp_cmd_send(lport, fsp, fc_fcp_recv);
|
||||||
if (unlikely(rc)) {
|
if (unlikely(rc)) {
|
||||||
spin_lock_irqsave(&si->scsi_queue_lock, flags);
|
spin_lock_irqsave(&si->scsi_queue_lock, flags);
|
||||||
|
fsp->cmd->SCp.ptr = NULL;
|
||||||
list_del(&fsp->list);
|
list_del(&fsp->list);
|
||||||
spin_unlock_irqrestore(&si->scsi_queue_lock, flags);
|
spin_unlock_irqrestore(&si->scsi_queue_lock, flags);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user