aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorJeff Moyer <jmoyer@redhat.com>2013-12-03 16:23:00 -0500
committerJens Axboe <axboe@kernel.dk>2013-12-03 16:24:28 -0500
commit959a35f13eb785f982d79b1aaa75872d05c821da (patch)
treecf6d053aee1a645f5ec9fc8e81d5f153b5a8692d /block
parente345d767f6530ec9cb0aabab7ea248072a9c6975 (diff)
blk-mq: fix dereference of rq->mq_ctx if allocation fails
If __GFP_WAIT isn't set and we fail allocating, when we go to drop the reference on the ctx, we will attempt to dereference the NULL rq. Fix that. Signed-off-by: Jeff Moyer <jmoyer@redhat.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r--block/blk-mq.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c
index cdc629cf075b..70fd6f996600 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -202,10 +202,12 @@ static struct request *blk_mq_alloc_request_pinned(struct request_queue *q,
202 if (rq) { 202 if (rq) {
203 blk_mq_rq_ctx_init(q, ctx, rq, rw); 203 blk_mq_rq_ctx_init(q, ctx, rq, rw);
204 break; 204 break;
205 } else if (!(gfp & __GFP_WAIT)) 205 }
206 break;
207 206
208 blk_mq_put_ctx(ctx); 207 blk_mq_put_ctx(ctx);
208 if (!(gfp & __GFP_WAIT))
209 break;
210
209 __blk_mq_run_hw_queue(hctx); 211 __blk_mq_run_hw_queue(hctx);
210 blk_mq_wait_for_tags(hctx->tags); 212 blk_mq_wait_for_tags(hctx->tags);
211 } while (1); 213 } while (1);
@@ -222,7 +224,8 @@ struct request *blk_mq_alloc_request(struct request_queue *q, int rw,
222 return NULL; 224 return NULL;
223 225
224 rq = blk_mq_alloc_request_pinned(q, rw, gfp, reserved); 226 rq = blk_mq_alloc_request_pinned(q, rw, gfp, reserved);
225 blk_mq_put_ctx(rq->mq_ctx); 227 if (rq)
228 blk_mq_put_ctx(rq->mq_ctx);
226 return rq; 229 return rq;
227} 230}
228 231
@@ -235,7 +238,8 @@ struct request *blk_mq_alloc_reserved_request(struct request_queue *q, int rw,
235 return NULL; 238 return NULL;
236 239
237 rq = blk_mq_alloc_request_pinned(q, rw, gfp, true); 240 rq = blk_mq_alloc_request_pinned(q, rw, gfp, true);
238 blk_mq_put_ctx(rq->mq_ctx); 241 if (rq)
242 blk_mq_put_ctx(rq->mq_ctx);
239 return rq; 243 return rq;
240} 244}
241EXPORT_SYMBOL(blk_mq_alloc_reserved_request); 245EXPORT_SYMBOL(blk_mq_alloc_reserved_request);