diff options
author | Joe Lawrence <joe.lawrence@stratus.com> | 2014-08-28 10:15:21 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2014-08-28 12:03:46 -0400 |
commit | a492f075450f3ba87de36e5ffe92a9d0c7af9723 (patch) | |
tree | 61960a71c7fde0eee3d77cda460154d2f7715d2f /drivers/scsi/device_handler | |
parent | eb571eeade2598635f813b3284d02c13a380301e (diff) |
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>
Diffstat (limited to 'drivers/scsi/device_handler')
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_alua.c | 2 | ||||
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_emc.c | 2 | ||||
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_hp_sw.c | 4 | ||||
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_rdac.c | 2 |
4 files changed, 5 insertions, 5 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 7bcf67eec921..e99507ed0e3c 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c | |||
@@ -115,7 +115,7 @@ static struct request *get_alua_req(struct scsi_device *sdev, | |||
115 | 115 | ||
116 | rq = blk_get_request(q, rw, GFP_NOIO); | 116 | rq = blk_get_request(q, rw, GFP_NOIO); |
117 | 117 | ||
118 | if (!rq) { | 118 | if (IS_ERR(rq)) { |
119 | sdev_printk(KERN_INFO, sdev, | 119 | sdev_printk(KERN_INFO, sdev, |
120 | "%s: blk_get_request failed\n", __func__); | 120 | "%s: blk_get_request failed\n", __func__); |
121 | return NULL; | 121 | return NULL; |
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c index 6f07f7fe3aa1..84765384c47c 100644 --- a/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/drivers/scsi/device_handler/scsi_dh_emc.c | |||
@@ -275,7 +275,7 @@ static struct request *get_req(struct scsi_device *sdev, int cmd, | |||
275 | 275 | ||
276 | rq = blk_get_request(sdev->request_queue, | 276 | rq = blk_get_request(sdev->request_queue, |
277 | (cmd != INQUIRY) ? WRITE : READ, GFP_NOIO); | 277 | (cmd != INQUIRY) ? WRITE : READ, GFP_NOIO); |
278 | if (!rq) { | 278 | if (IS_ERR(rq)) { |
279 | sdev_printk(KERN_INFO, sdev, "get_req: blk_get_request failed"); | 279 | sdev_printk(KERN_INFO, sdev, "get_req: blk_get_request failed"); |
280 | return NULL; | 280 | return NULL; |
281 | } | 281 | } |
diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c index e9d9fea9e272..4ee2759f5299 100644 --- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c +++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c | |||
@@ -117,7 +117,7 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h) | |||
117 | 117 | ||
118 | retry: | 118 | retry: |
119 | req = blk_get_request(sdev->request_queue, WRITE, GFP_NOIO); | 119 | req = blk_get_request(sdev->request_queue, WRITE, GFP_NOIO); |
120 | if (!req) | 120 | if (IS_ERR(req)) |
121 | return SCSI_DH_RES_TEMP_UNAVAIL; | 121 | return SCSI_DH_RES_TEMP_UNAVAIL; |
122 | 122 | ||
123 | blk_rq_set_block_pc(req); | 123 | blk_rq_set_block_pc(req); |
@@ -247,7 +247,7 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h) | |||
247 | struct request *req; | 247 | struct request *req; |
248 | 248 | ||
249 | req = blk_get_request(h->sdev->request_queue, WRITE, GFP_ATOMIC); | 249 | req = blk_get_request(h->sdev->request_queue, WRITE, GFP_ATOMIC); |
250 | if (!req) | 250 | if (IS_ERR(req)) |
251 | return SCSI_DH_RES_TEMP_UNAVAIL; | 251 | return SCSI_DH_RES_TEMP_UNAVAIL; |
252 | 252 | ||
253 | blk_rq_set_block_pc(req); | 253 | blk_rq_set_block_pc(req); |
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index 826069db9848..1b5bc9293e37 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c | |||
@@ -274,7 +274,7 @@ static struct request *get_rdac_req(struct scsi_device *sdev, | |||
274 | 274 | ||
275 | rq = blk_get_request(q, rw, GFP_NOIO); | 275 | rq = blk_get_request(q, rw, GFP_NOIO); |
276 | 276 | ||
277 | if (!rq) { | 277 | if (IS_ERR(rq)) { |
278 | sdev_printk(KERN_INFO, sdev, | 278 | sdev_printk(KERN_INFO, sdev, |
279 | "get_rdac_req: blk_get_request failed.\n"); | 279 | "get_rdac_req: blk_get_request failed.\n"); |
280 | return NULL; | 280 | return NULL; |