diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 6311fd448c36..4591cc7b8240 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -600,12 +600,19 @@ static void srp_path_rec_completion(int status, static int srp_lookup_path(struct srp_target_port *target) { - int ret; + int ret = -ENODEV; target->path.numb_path = 1; init_completion(&target->done); + /* + * Avoid that the SCSI host can be removed by srp_remove_target() + * before srp_path_rec_completion() is called. + */ + if (!scsi_host_get(target->scsi_host)) + goto out; + target->path_query_id = ib_sa_path_rec_get(&srp_sa_client, target->srp_host->srp_dev->dev, target->srp_host->port, @@ -619,18 +626,24 @@ static int srp_lookup_path(struct srp_target_port *target) GFP_KERNEL, srp_path_rec_completion, target, &target->path_query); - if (target->path_query_id < 0) - return target->path_query_id; + ret = target->path_query_id; + if (ret < 0) + goto put; ret = wait_for_completion_interruptible(&target->done); if (ret < 0) return ret; - if (target->status < 0) + ret = target->status; + if (ret < 0) shost_printk(KERN_WARNING, target->scsi_host, PFX "Path record query failed\n"); - return target->status; +put: + scsi_host_put(target->scsi_host); + +out: + return ret; } static int srp_send_req(struct srp_target_port *target)