aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2009-05-27 08:17:08 -0400
committerJens Axboe <jens.axboe@oracle.com>2009-05-27 08:17:08 -0400
commitba396a6c104682dfe5c8b4fbbf5974d5ac9f3687 (patch)
treeba8bf30382d1891c7f540264b6229db1bc1eb797 /block
parent3b77f777b8f1c001b63e317c4ce317292ff0ff94 (diff)
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: James Bottomley <James.Bottomley@HansenPartnership.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block')
-rw-r--r--block/blk-core.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index 7a4c40184a64..8b3b74e69184 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -956,8 +956,6 @@ EXPORT_SYMBOL(blk_make_request);
956 */ 956 */
957void blk_requeue_request(struct request_queue *q, struct request *rq) 957void blk_requeue_request(struct request_queue *q, struct request *rq)
958{ 958{
959 BUG_ON(blk_queued_rq(rq));
960
961 blk_delete_timer(rq); 959 blk_delete_timer(rq);
962 blk_clear_rq_complete(rq); 960 blk_clear_rq_complete(rq);
963 trace_block_rq_requeue(q, rq); 961 trace_block_rq_requeue(q, rq);
@@ -965,6 +963,8 @@ void blk_requeue_request(struct request_queue *q, struct request *rq)
965 if (blk_rq_tagged(rq)) 963 if (blk_rq_tagged(rq))
966 blk_queue_end_tag(q, rq); 964 blk_queue_end_tag(q, rq);
967 965
966 BUG_ON(blk_queued_rq(rq));
967
968 elv_requeue_request(q, rq); 968 elv_requeue_request(q, rq);
969} 969}
970EXPORT_SYMBOL(blk_requeue_request); 970EXPORT_SYMBOL(blk_requeue_request);
@@ -2042,11 +2042,11 @@ static bool blk_update_bidi_request(struct request *rq, int error,
2042 */ 2042 */
2043static void blk_finish_request(struct request *req, int error) 2043static void blk_finish_request(struct request *req, int error)
2044{ 2044{
2045 BUG_ON(blk_queued_rq(req));
2046
2047 if (blk_rq_tagged(req)) 2045 if (blk_rq_tagged(req))
2048 blk_queue_end_tag(req->q, req); 2046 blk_queue_end_tag(req->q, req);
2049 2047
2048 BUG_ON(blk_queued_rq(req));
2049
2050 if (unlikely(laptop_mode) && blk_fs_request(req)) 2050 if (unlikely(laptop_mode) && blk_fs_request(req))
2051 laptop_io_completion(); 2051 laptop_io_completion();
2052 2052