block,scsi: fixup blk_get_request dead queue scenarios
The blk_get_request function may fail in low-memory conditions or during device removal (even if __GFP_WAIT is set). To distinguish between these errors, modify the blk_get_request call stack to return the appropriate ERR_PTR. Verify that all callers check the return status and consider IS_ERR instead of a simple NULL pointer check. For consistency, make a similar change to the blk_mq_alloc_request leg of blk_get_request. It may fail if the queue is dead, or the caller was unwilling to wait. Signed-off-by: Joe Lawrence <joe.lawrence@stratus.com> Acked-by: Jiri Kosina <jkosina@suse.cz> [for pktdvd] Acked-by: Boaz Harrosh <bharrosh@panasas.com> [for osd] Reviewed-by: Jeff Moyer <jmoyer@redhat.com> Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
@@ -115,7 +115,7 @@ static struct request *get_alua_req(struct scsi_device *sdev,
|
||||
|
||||
rq = blk_get_request(q, rw, GFP_NOIO);
|
||||
|
||||
if (!rq) {
|
||||
if (IS_ERR(rq)) {
|
||||
sdev_printk(KERN_INFO, sdev,
|
||||
"%s: blk_get_request failed\n", __func__);
|
||||
return NULL;
|
||||
|
@@ -275,7 +275,7 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
|
||||
|
||||
rq = blk_get_request(sdev->request_queue,
|
||||
(cmd != INQUIRY) ? WRITE : READ, GFP_NOIO);
|
||||
if (!rq) {
|
||||
if (IS_ERR(rq)) {
|
||||
sdev_printk(KERN_INFO, sdev, "get_req: blk_get_request failed");
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -117,7 +117,7 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h)
|
||||
|
||||
retry:
|
||||
req = blk_get_request(sdev->request_queue, WRITE, GFP_NOIO);
|
||||
if (!req)
|
||||
if (IS_ERR(req))
|
||||
return SCSI_DH_RES_TEMP_UNAVAIL;
|
||||
|
||||
blk_rq_set_block_pc(req);
|
||||
@@ -247,7 +247,7 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)
|
||||
struct request *req;
|
||||
|
||||
req = blk_get_request(h->sdev->request_queue, WRITE, GFP_ATOMIC);
|
||||
if (!req)
|
||||
if (IS_ERR(req))
|
||||
return SCSI_DH_RES_TEMP_UNAVAIL;
|
||||
|
||||
blk_rq_set_block_pc(req);
|
||||
|
@@ -274,7 +274,7 @@ static struct request *get_rdac_req(struct scsi_device *sdev,
|
||||
|
||||
rq = blk_get_request(q, rw, GFP_NOIO);
|
||||
|
||||
if (!rq) {
|
||||
if (IS_ERR(rq)) {
|
||||
sdev_printk(KERN_INFO, sdev,
|
||||
"get_rdac_req: blk_get_request failed.\n");
|
||||
return NULL;
|
||||
|
@@ -1567,8 +1567,8 @@ static struct request *_make_request(struct request_queue *q, bool has_write,
|
||||
struct request *req;
|
||||
|
||||
req = blk_get_request(q, has_write ? WRITE : READ, flags);
|
||||
if (unlikely(!req))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
if (IS_ERR(req))
|
||||
return req;
|
||||
|
||||
blk_rq_set_block_pc(req);
|
||||
return req;
|
||||
|
@@ -362,7 +362,7 @@ static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd,
|
||||
int write = (data_direction == DMA_TO_DEVICE);
|
||||
|
||||
req = blk_get_request(SRpnt->stp->device->request_queue, write, GFP_KERNEL);
|
||||
if (!req)
|
||||
if (IS_ERR(req))
|
||||
return DRIVER_ERROR << 24;
|
||||
|
||||
blk_rq_set_block_pc(req);
|
||||
|
@@ -1960,7 +1960,7 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
|
||||
* request becomes available
|
||||
*/
|
||||
req = blk_get_request(sdev->request_queue, READ, GFP_KERNEL);
|
||||
if (!req)
|
||||
if (IS_ERR(req))
|
||||
return;
|
||||
|
||||
blk_rq_set_block_pc(req);
|
||||
|
@@ -221,7 +221,7 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
|
||||
int ret = DRIVER_ERROR << 24;
|
||||
|
||||
req = blk_get_request(sdev->request_queue, write, __GFP_WAIT);
|
||||
if (!req)
|
||||
if (IS_ERR(req))
|
||||
return ret;
|
||||
blk_rq_set_block_pc(req);
|
||||
|
||||
|
@@ -1711,9 +1711,9 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
|
||||
}
|
||||
|
||||
rq = blk_get_request(q, rw, GFP_ATOMIC);
|
||||
if (!rq) {
|
||||
if (IS_ERR(rq)) {
|
||||
kfree(long_cmdp);
|
||||
return -ENOMEM;
|
||||
return PTR_ERR(rq);
|
||||
}
|
||||
|
||||
blk_rq_set_block_pc(rq);
|
||||
|
@@ -490,7 +490,7 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
|
||||
|
||||
req = blk_get_request(SRpnt->stp->device->request_queue, write,
|
||||
GFP_KERNEL);
|
||||
if (!req)
|
||||
if (IS_ERR(req))
|
||||
return DRIVER_ERROR << 24;
|
||||
|
||||
blk_rq_set_block_pc(req);
|
||||
|
Reference in New Issue
Block a user