diff options
author | Bart Van Assche <bvanassche@acm.org> | 2013-06-12 15:23:04 +0200 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2013-06-28 01:44:39 +0200 |
commit | 086f44f58855ae18bab19fb794cce6c6d2c6143b (patch) | |
tree | e4cad038ce28f9d137f4534f10b456ebd60f51cc /drivers/infiniband/ulp | |
parent | IB/srp: Fix remove_one crash due to resource exhaustion (diff) | |
download | linux-086f44f58855ae18bab19fb794cce6c6d2c6143b.tar.xz linux-086f44f58855ae18bab19fb794cce6c6d2c6143b.zip |
IB/srp: Avoid skipping srp_reset_host() after a transport error
The SCSI error handler assumes that the transport layer is operational
if an eh_abort_handler() returns SUCCESS. Hence srp_abort() only
should return SUCCESS if sending the ABORT TASK task management
function succeeded. This patch avoids the SCSI error handler skipping
the srp_reset_host() call after a transport layer error.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Acked-by: David Dillow <dillowda@ornl.gov>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/ulp')
-rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 368d1606e16f..759c55b9685f 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -1744,18 +1744,23 @@ static int srp_abort(struct scsi_cmnd *scmnd) { struct srp_target_port *target = host_to_target(scmnd->device->host); struct srp_request *req = (struct srp_request *) scmnd->host_scribble; + int ret; shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); if (!req || !srp_claim_req(target, req, scmnd)) return FAILED; - srp_send_tsk_mgmt(target, req->index, scmnd->device->lun, - SRP_TSK_ABORT_TASK); + if (srp_send_tsk_mgmt(target, req->index, scmnd->device->lun, + SRP_TSK_ABORT_TASK) == 0 || + target->transport_offline) + ret = SUCCESS; + else + ret = FAILED; srp_free_req(target, req, scmnd, 0); scmnd->result = DID_ABORT << 16; scmnd->scsi_done(scmnd); - return SUCCESS; + return ret; } static int srp_reset_device(struct scsi_cmnd *scmnd) |