Add blk_mq_complete_request_locally() for completing request via blk_mq_tagset_busy_iter(), so that we can avoid request UAF related with queue releasing, or request freeing. Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx> --- block/blk-mq.c | 16 ++++++++++++++++ include/linux/blk-mq.h | 1 + 2 files changed, 17 insertions(+) diff --git a/block/blk-mq.c b/block/blk-mq.c index 927189a55575..e3d1067b10c3 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -681,6 +681,22 @@ void blk_mq_complete_request(struct request *rq) } EXPORT_SYMBOL(blk_mq_complete_request); +/** + * blk_mq_complete_request_locally - end I/O on a request locally + * @rq: the request being processed + * + * Description: + * Complete a request by calling the ->complete_rq directly, + * and it is usually used in error handling via + * blk_mq_tagset_busy_iter(). + **/ +void blk_mq_complete_request_locally(struct request *rq) +{ + WRITE_ONCE(rq->state, MQ_RQ_COMPLETE); + rq->q->mq_ops->complete(rq); +} +EXPORT_SYMBOL(blk_mq_complete_request_locally); + static void hctx_unlock(struct blk_mq_hw_ctx *hctx, int srcu_idx) __releases(hctx->srcu) { diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index 2c473c9b8990..f630bf9e497e 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h @@ -511,6 +511,7 @@ void blk_mq_kick_requeue_list(struct request_queue *q); void blk_mq_delay_kick_requeue_list(struct request_queue *q, unsigned long msecs); void blk_mq_complete_request(struct request *rq); bool blk_mq_complete_request_remote(struct request *rq); +void blk_mq_complete_request_locally(struct request *rq); bool blk_mq_queue_stopped(struct request_queue *q); void blk_mq_stop_hw_queue(struct blk_mq_hw_ctx *hctx); void blk_mq_start_hw_queue(struct blk_mq_hw_ctx *hctx); -- 2.29.2