diff options
| author | Jeff Moyer <jmoyer@redhat.com> | 2013-12-03 16:23:00 -0500 |
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2013-12-03 16:24:28 -0500 |
| commit | 959a35f13eb785f982d79b1aaa75872d05c821da (patch) | |
| tree | cf6d053aee1a645f5ec9fc8e81d5f153b5a8692d /block | |
| parent | e345d767f6530ec9cb0aabab7ea248072a9c6975 (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.c | 12 |
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 | } |
| 241 | EXPORT_SYMBOL(blk_mq_alloc_reserved_request); | 245 | EXPORT_SYMBOL(blk_mq_alloc_reserved_request); |
