Commit ba396a6c authored by James Bottomley's avatar James Bottomley Committed by Jens Axboe

block: fix oops with block tag queueing

commit e8939a50466fd963eb1ba9118c34b9ffb7ff6aa6
Author: Tejun Heo <tj@kernel.org>
Date:   Fri May 8 11:54:16 2009 +0900

    block: implement and enforce request peek/start/fetch

Added a BUG_ON(blk_queued_rq(req)) to the top of blk_finish_req().
Unfortunately, this checks whether req->queuelist is empty.  This list
is doing double duty both as the queue list and the tag list, so tagged
requests come in here with this not empty and boom (the tag list is
emptied by blk_queue_end_tag() lower down).

Fix this by moving the BUG_ON to below the end tag we also seem
vulnerable to this in blk_requeue_request() as well.  I think all uses
of blk_queued_rq() need auditing because the check is clearly wrong in
the tagged case.
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent 3b77f777
...@@ -956,8 +956,6 @@ EXPORT_SYMBOL(blk_make_request); ...@@ -956,8 +956,6 @@ EXPORT_SYMBOL(blk_make_request);
*/ */
void blk_requeue_request(struct request_queue *q, struct request *rq) void blk_requeue_request(struct request_queue *q, struct request *rq)
{ {
BUG_ON(blk_queued_rq(rq));
blk_delete_timer(rq); blk_delete_timer(rq);
blk_clear_rq_complete(rq); blk_clear_rq_complete(rq);
trace_block_rq_requeue(q, rq); trace_block_rq_requeue(q, rq);
...@@ -965,6 +963,8 @@ void blk_requeue_request(struct request_queue *q, struct request *rq) ...@@ -965,6 +963,8 @@ void blk_requeue_request(struct request_queue *q, struct request *rq)
if (blk_rq_tagged(rq)) if (blk_rq_tagged(rq))
blk_queue_end_tag(q, rq); blk_queue_end_tag(q, rq);
BUG_ON(blk_queued_rq(rq));
elv_requeue_request(q, rq); elv_requeue_request(q, rq);
} }
EXPORT_SYMBOL(blk_requeue_request); EXPORT_SYMBOL(blk_requeue_request);
...@@ -2042,11 +2042,11 @@ static bool blk_update_bidi_request(struct request *rq, int error, ...@@ -2042,11 +2042,11 @@ static bool blk_update_bidi_request(struct request *rq, int error,
*/ */
static void blk_finish_request(struct request *req, int error) static void blk_finish_request(struct request *req, int error)
{ {
BUG_ON(blk_queued_rq(req));
if (blk_rq_tagged(req)) if (blk_rq_tagged(req))
blk_queue_end_tag(req->q, req); blk_queue_end_tag(req->q, req);
BUG_ON(blk_queued_rq(req));
if (unlikely(laptop_mode) && blk_fs_request(req)) if (unlikely(laptop_mode) && blk_fs_request(req))
laptop_io_completion(); laptop_io_completion();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment