block: enumify ELEVATOR_*_MERGE
Switch these constants to an enum, and make let the compiler ensure that all callers of blk_try_merge and elv_merge handle all potential values. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
Родитель
6cf7677f1a
Коммит
34fe7c0540
|
@ -1511,12 +1511,11 @@ bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,
|
|||
{
|
||||
struct blk_plug *plug;
|
||||
struct request *rq;
|
||||
bool ret = false;
|
||||
struct list_head *plug_list;
|
||||
|
||||
plug = current->plug;
|
||||
if (!plug)
|
||||
goto out;
|
||||
return false;
|
||||
*request_count = 0;
|
||||
|
||||
if (q->mq_ops)
|
||||
|
@ -1525,7 +1524,7 @@ bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,
|
|||
plug_list = &plug->list;
|
||||
|
||||
list_for_each_entry_reverse(rq, plug_list, queuelist) {
|
||||
int el_ret;
|
||||
bool merged = false;
|
||||
|
||||
if (rq->q == q) {
|
||||
(*request_count)++;
|
||||
|
@ -1541,19 +1540,22 @@ bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,
|
|||
if (rq->q != q || !blk_rq_merge_ok(rq, bio))
|
||||
continue;
|
||||
|
||||
el_ret = blk_try_merge(rq, bio);
|
||||
if (el_ret == ELEVATOR_BACK_MERGE) {
|
||||
ret = bio_attempt_back_merge(q, rq, bio);
|
||||
if (ret)
|
||||
break;
|
||||
} else if (el_ret == ELEVATOR_FRONT_MERGE) {
|
||||
ret = bio_attempt_front_merge(q, rq, bio);
|
||||
if (ret)
|
||||
break;
|
||||
switch (blk_try_merge(rq, bio)) {
|
||||
case ELEVATOR_BACK_MERGE:
|
||||
merged = bio_attempt_back_merge(q, rq, bio);
|
||||
break;
|
||||
case ELEVATOR_FRONT_MERGE:
|
||||
merged = bio_attempt_front_merge(q, rq, bio);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (merged)
|
||||
return true;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int blk_plug_queued_count(struct request_queue *q)
|
||||
|
@ -1595,7 +1597,7 @@ void init_request_from_bio(struct request *req, struct bio *bio)
|
|||
static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio)
|
||||
{
|
||||
struct blk_plug *plug;
|
||||
int el_ret, where = ELEVATOR_INSERT_SORT;
|
||||
int where = ELEVATOR_INSERT_SORT;
|
||||
struct request *req, *free;
|
||||
unsigned int request_count = 0;
|
||||
unsigned int wb_acct;
|
||||
|
@ -1633,27 +1635,29 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio)
|
|||
|
||||
spin_lock_irq(q->queue_lock);
|
||||
|
||||
el_ret = elv_merge(q, &req, bio);
|
||||
if (el_ret == ELEVATOR_BACK_MERGE) {
|
||||
if (bio_attempt_back_merge(q, req, bio)) {
|
||||
elv_bio_merged(q, req, bio);
|
||||
free = attempt_back_merge(q, req);
|
||||
if (!free)
|
||||
elv_merged_request(q, req, el_ret);
|
||||
else
|
||||
__blk_put_request(q, free);
|
||||
goto out_unlock;
|
||||
}
|
||||
} else if (el_ret == ELEVATOR_FRONT_MERGE) {
|
||||
if (bio_attempt_front_merge(q, req, bio)) {
|
||||
elv_bio_merged(q, req, bio);
|
||||
free = attempt_front_merge(q, req);
|
||||
if (!free)
|
||||
elv_merged_request(q, req, el_ret);
|
||||
else
|
||||
__blk_put_request(q, free);
|
||||
goto out_unlock;
|
||||
}
|
||||
switch (elv_merge(q, &req, bio)) {
|
||||
case ELEVATOR_BACK_MERGE:
|
||||
if (!bio_attempt_back_merge(q, req, bio))
|
||||
break;
|
||||
elv_bio_merged(q, req, bio);
|
||||
free = attempt_back_merge(q, req);
|
||||
if (free)
|
||||
__blk_put_request(q, free);
|
||||
else
|
||||
elv_merged_request(q, req, ELEVATOR_BACK_MERGE);
|
||||
goto out_unlock;
|
||||
case ELEVATOR_FRONT_MERGE:
|
||||
if (!bio_attempt_front_merge(q, req, bio))
|
||||
break;
|
||||
elv_bio_merged(q, req, bio);
|
||||
free = attempt_front_merge(q, req);
|
||||
if (free)
|
||||
__blk_put_request(q, free);
|
||||
else
|
||||
elv_merged_request(q, req, ELEVATOR_FRONT_MERGE);
|
||||
goto out_unlock;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
get_rq:
|
||||
|
|
|
@ -801,7 +801,7 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
|
|||
return true;
|
||||
}
|
||||
|
||||
int blk_try_merge(struct request *rq, struct bio *bio)
|
||||
enum elv_merge blk_try_merge(struct request *rq, struct bio *bio)
|
||||
{
|
||||
if (blk_rq_pos(rq) + blk_rq_sectors(rq) == bio->bi_iter.bi_sector)
|
||||
return ELEVATOR_BACK_MERGE;
|
||||
|
|
|
@ -238,30 +238,29 @@ bool blk_mq_sched_try_merge(struct request_queue *q, struct bio *bio,
|
|||
struct request **merged_request)
|
||||
{
|
||||
struct request *rq;
|
||||
int ret;
|
||||
|
||||
ret = elv_merge(q, &rq, bio);
|
||||
if (ret == ELEVATOR_BACK_MERGE) {
|
||||
switch (elv_merge(q, &rq, bio)) {
|
||||
case ELEVATOR_BACK_MERGE:
|
||||
if (!blk_mq_sched_allow_merge(q, rq, bio))
|
||||
return false;
|
||||
if (bio_attempt_back_merge(q, rq, bio)) {
|
||||
*merged_request = attempt_back_merge(q, rq);
|
||||
if (!*merged_request)
|
||||
elv_merged_request(q, rq, ret);
|
||||
return true;
|
||||
}
|
||||
} else if (ret == ELEVATOR_FRONT_MERGE) {
|
||||
if (!bio_attempt_back_merge(q, rq, bio))
|
||||
return false;
|
||||
*merged_request = attempt_back_merge(q, rq);
|
||||
if (!*merged_request)
|
||||
elv_merged_request(q, rq, ELEVATOR_BACK_MERGE);
|
||||
return true;
|
||||
case ELEVATOR_FRONT_MERGE:
|
||||
if (!blk_mq_sched_allow_merge(q, rq, bio))
|
||||
return false;
|
||||
if (bio_attempt_front_merge(q, rq, bio)) {
|
||||
*merged_request = attempt_front_merge(q, rq);
|
||||
if (!*merged_request)
|
||||
elv_merged_request(q, rq, ret);
|
||||
return true;
|
||||
}
|
||||
if (!bio_attempt_front_merge(q, rq, bio))
|
||||
return false;
|
||||
*merged_request = attempt_front_merge(q, rq);
|
||||
if (!*merged_request)
|
||||
elv_merged_request(q, rq, ELEVATOR_FRONT_MERGE);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blk_mq_sched_try_merge);
|
||||
|
||||
|
|
|
@ -763,7 +763,7 @@ static bool blk_mq_attempt_merge(struct request_queue *q,
|
|||
int checked = 8;
|
||||
|
||||
list_for_each_entry_reverse(rq, &ctx->rq_list, queuelist) {
|
||||
int el_ret;
|
||||
bool merged = false;
|
||||
|
||||
if (!checked--)
|
||||
break;
|
||||
|
@ -771,26 +771,22 @@ static bool blk_mq_attempt_merge(struct request_queue *q,
|
|||
if (!blk_rq_merge_ok(rq, bio))
|
||||
continue;
|
||||
|
||||
el_ret = blk_try_merge(rq, bio);
|
||||
if (el_ret == ELEVATOR_NO_MERGE)
|
||||
switch (blk_try_merge(rq, bio)) {
|
||||
case ELEVATOR_BACK_MERGE:
|
||||
if (blk_mq_sched_allow_merge(q, rq, bio))
|
||||
merged = bio_attempt_back_merge(q, rq, bio);
|
||||
break;
|
||||
case ELEVATOR_FRONT_MERGE:
|
||||
if (blk_mq_sched_allow_merge(q, rq, bio))
|
||||
merged = bio_attempt_front_merge(q, rq, bio);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
|
||||
if (!blk_mq_sched_allow_merge(q, rq, bio))
|
||||
break;
|
||||
|
||||
if (el_ret == ELEVATOR_BACK_MERGE) {
|
||||
if (bio_attempt_back_merge(q, rq, bio)) {
|
||||
ctx->rq_merged++;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
} else if (el_ret == ELEVATOR_FRONT_MERGE) {
|
||||
if (bio_attempt_front_merge(q, rq, bio)) {
|
||||
ctx->rq_merged++;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (merged)
|
||||
ctx->rq_merged++;
|
||||
return merged;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -215,7 +215,7 @@ int blk_attempt_req_merge(struct request_queue *q, struct request *rq,
|
|||
void blk_recalc_rq_segments(struct request *rq);
|
||||
void blk_rq_set_mixed_merge(struct request *rq);
|
||||
bool blk_rq_merge_ok(struct request *rq, struct bio *bio);
|
||||
int blk_try_merge(struct request *rq, struct bio *bio);
|
||||
enum elv_merge blk_try_merge(struct request *rq, struct bio *bio);
|
||||
|
||||
void blk_queue_congestion_threshold(struct request_queue *q);
|
||||
|
||||
|
|
|
@ -2528,7 +2528,7 @@ static void cfq_remove_request(struct request *rq)
|
|||
}
|
||||
}
|
||||
|
||||
static int cfq_merge(struct request_queue *q, struct request **req,
|
||||
static enum elv_merge cfq_merge(struct request_queue *q, struct request **req,
|
||||
struct bio *bio)
|
||||
{
|
||||
struct cfq_data *cfqd = q->elevator->elevator_data;
|
||||
|
@ -2544,7 +2544,7 @@ static int cfq_merge(struct request_queue *q, struct request **req,
|
|||
}
|
||||
|
||||
static void cfq_merged_request(struct request_queue *q, struct request *req,
|
||||
int type)
|
||||
enum elv_merge type)
|
||||
{
|
||||
if (type == ELEVATOR_FRONT_MERGE) {
|
||||
struct cfq_queue *cfqq = RQ_CFQQ(req);
|
||||
|
|
|
@ -120,12 +120,11 @@ static void deadline_remove_request(struct request_queue *q, struct request *rq)
|
|||
deadline_del_rq_rb(dd, rq);
|
||||
}
|
||||
|
||||
static int
|
||||
static enum elv_merge
|
||||
deadline_merge(struct request_queue *q, struct request **req, struct bio *bio)
|
||||
{
|
||||
struct deadline_data *dd = q->elevator->elevator_data;
|
||||
struct request *__rq;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* check for front merge
|
||||
|
@ -138,20 +137,17 @@ deadline_merge(struct request_queue *q, struct request **req, struct bio *bio)
|
|||
BUG_ON(sector != blk_rq_pos(__rq));
|
||||
|
||||
if (elv_bio_merge_ok(__rq, bio)) {
|
||||
ret = ELEVATOR_FRONT_MERGE;
|
||||
goto out;
|
||||
*req = __rq;
|
||||
return ELEVATOR_FRONT_MERGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ELEVATOR_NO_MERGE;
|
||||
out:
|
||||
*req = __rq;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void deadline_merged_request(struct request_queue *q,
|
||||
struct request *req, int type)
|
||||
struct request *req, enum elv_merge type)
|
||||
{
|
||||
struct deadline_data *dd = q->elevator->elevator_data;
|
||||
|
||||
|
|
|
@ -427,11 +427,11 @@ void elv_dispatch_add_tail(struct request_queue *q, struct request *rq)
|
|||
}
|
||||
EXPORT_SYMBOL(elv_dispatch_add_tail);
|
||||
|
||||
int elv_merge(struct request_queue *q, struct request **req, struct bio *bio)
|
||||
enum elv_merge elv_merge(struct request_queue *q, struct request **req,
|
||||
struct bio *bio)
|
||||
{
|
||||
struct elevator_queue *e = q->elevator;
|
||||
struct request *__rq;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Levels of merges:
|
||||
|
@ -446,7 +446,8 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio)
|
|||
* First try one-hit cache.
|
||||
*/
|
||||
if (q->last_merge && elv_bio_merge_ok(q->last_merge, bio)) {
|
||||
ret = blk_try_merge(q->last_merge, bio);
|
||||
enum elv_merge ret = blk_try_merge(q->last_merge, bio);
|
||||
|
||||
if (ret != ELEVATOR_NO_MERGE) {
|
||||
*req = q->last_merge;
|
||||
return ret;
|
||||
|
@ -514,7 +515,8 @@ bool elv_attempt_insert_merge(struct request_queue *q, struct request *rq)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void elv_merged_request(struct request_queue *q, struct request *rq, int type)
|
||||
void elv_merged_request(struct request_queue *q, struct request *rq,
|
||||
enum elv_merge type)
|
||||
{
|
||||
struct elevator_queue *e = q->elevator;
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ static void deadline_remove_request(struct request_queue *q, struct request *rq)
|
|||
}
|
||||
|
||||
static void dd_request_merged(struct request_queue *q, struct request *req,
|
||||
int type)
|
||||
enum elv_merge type)
|
||||
{
|
||||
struct deadline_data *dd = q->elevator->elevator_data;
|
||||
|
||||
|
|
|
@ -9,12 +9,21 @@
|
|||
struct io_cq;
|
||||
struct elevator_type;
|
||||
|
||||
typedef int (elevator_merge_fn) (struct request_queue *, struct request **,
|
||||
/*
|
||||
* Return values from elevator merger
|
||||
*/
|
||||
enum elv_merge {
|
||||
ELEVATOR_NO_MERGE = 0,
|
||||
ELEVATOR_FRONT_MERGE = 1,
|
||||
ELEVATOR_BACK_MERGE = 2,
|
||||
};
|
||||
|
||||
typedef enum elv_merge (elevator_merge_fn) (struct request_queue *, struct request **,
|
||||
struct bio *);
|
||||
|
||||
typedef void (elevator_merge_req_fn) (struct request_queue *, struct request *, struct request *);
|
||||
|
||||
typedef void (elevator_merged_fn) (struct request_queue *, struct request *, int);
|
||||
typedef void (elevator_merged_fn) (struct request_queue *, struct request *, enum elv_merge);
|
||||
|
||||
typedef int (elevator_allow_bio_merge_fn) (struct request_queue *,
|
||||
struct request *, struct bio *);
|
||||
|
@ -87,7 +96,7 @@ struct elevator_mq_ops {
|
|||
bool (*allow_merge)(struct request_queue *, struct request *, struct bio *);
|
||||
bool (*bio_merge)(struct blk_mq_hw_ctx *, struct bio *);
|
||||
int (*request_merge)(struct request_queue *q, struct request **, struct bio *);
|
||||
void (*request_merged)(struct request_queue *, struct request *, int);
|
||||
void (*request_merged)(struct request_queue *, struct request *, enum elv_merge);
|
||||
void (*requests_merged)(struct request_queue *, struct request *, struct request *);
|
||||
struct request *(*get_request)(struct request_queue *, unsigned int, struct blk_mq_alloc_data *);
|
||||
void (*put_request)(struct request *);
|
||||
|
@ -166,10 +175,12 @@ extern void elv_dispatch_sort(struct request_queue *, struct request *);
|
|||
extern void elv_dispatch_add_tail(struct request_queue *, struct request *);
|
||||
extern void elv_add_request(struct request_queue *, struct request *, int);
|
||||
extern void __elv_add_request(struct request_queue *, struct request *, int);
|
||||
extern int elv_merge(struct request_queue *, struct request **, struct bio *);
|
||||
extern enum elv_merge elv_merge(struct request_queue *, struct request **,
|
||||
struct bio *);
|
||||
extern void elv_merge_requests(struct request_queue *, struct request *,
|
||||
struct request *);
|
||||
extern void elv_merged_request(struct request_queue *, struct request *, int);
|
||||
extern void elv_merged_request(struct request_queue *, struct request *,
|
||||
enum elv_merge);
|
||||
extern void elv_bio_merged(struct request_queue *q, struct request *,
|
||||
struct bio *);
|
||||
extern bool elv_attempt_insert_merge(struct request_queue *, struct request *);
|
||||
|
@ -218,13 +229,6 @@ extern void elv_rb_add(struct rb_root *, struct request *);
|
|||
extern void elv_rb_del(struct rb_root *, struct request *);
|
||||
extern struct request *elv_rb_find(struct rb_root *, sector_t);
|
||||
|
||||
/*
|
||||
* Return values from elevator merger
|
||||
*/
|
||||
#define ELEVATOR_NO_MERGE 0
|
||||
#define ELEVATOR_FRONT_MERGE 1
|
||||
#define ELEVATOR_BACK_MERGE 2
|
||||
|
||||
/*
|
||||
* Insertion selection
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче