block: add support for write hints in a bio
authorJens Axboe <axboe@kernel.dk>
Tue, 27 Jun 2017 15:22:02 +0000 (09:22 -0600)
committerJens Axboe <axboe@kernel.dk>
Tue, 27 Jun 2017 18:05:27 +0000 (12:05 -0600)
No functional changes in this patch, we just use up some holes
in the bio and request structures to define a write hint that
we psas down the stack.

Ensure that we don't merge requests that have different life time
hints assigned to them, and that we inherit the write hint when
cloning a bio.

Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/bio.c
block/blk-core.c
block/blk-merge.c
include/linux/blk_types.h
include/linux/blkdev.h

index 89a51bd..9cf98b2 100644 (file)
@@ -596,6 +596,7 @@ void __bio_clone_fast(struct bio *bio, struct bio *bio_src)
        bio->bi_bdev = bio_src->bi_bdev;
        bio_set_flag(bio, BIO_CLONED);
        bio->bi_opf = bio_src->bi_opf;
+       bio->bi_write_hint = bio_src->bi_write_hint;
        bio->bi_iter = bio_src->bi_iter;
        bio->bi_io_vec = bio_src->bi_io_vec;
 
@@ -679,6 +680,7 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
                return NULL;
        bio->bi_bdev            = bio_src->bi_bdev;
        bio->bi_opf             = bio_src->bi_opf;
+       bio->bi_write_hint      = bio_src->bi_write_hint;
        bio->bi_iter.bi_sector  = bio_src->bi_iter.bi_sector;
        bio->bi_iter.bi_size    = bio_src->bi_iter.bi_size;
 
index 3c18ea6..af393d5 100644 (file)
@@ -1765,6 +1765,7 @@ void blk_init_request_from_bio(struct request *req, struct bio *bio)
                req->ioprio = ioc->ioprio;
        else
                req->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 0);
+       req->write_hint = bio->bi_write_hint;
        blk_rq_bio_prep(req->q, req, bio);
 }
 EXPORT_SYMBOL_GPL(blk_init_request_from_bio);
index 5df1304..9903883 100644 (file)
@@ -673,6 +673,13 @@ static struct request *attempt_merge(struct request_queue *q,
                return NULL;
 
        /*
+        * Don't allow merge of different write hints, or for a hint with
+        * non-hint IO.
+        */
+       if (req->write_hint != next->write_hint)
+               return NULL;
+
+       /*
         * If we are allowed to merge, then append bio list
         * from next to rq and release next. merge_requests_fn
         * will have updated segment counts, update sector
@@ -791,6 +798,13 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
            !blk_write_same_mergeable(rq->bio, bio))
                return false;
 
+       /*
+        * Don't allow merge of different write hints, or for a hint with
+        * non-hint IO.
+        */
+       if (rq->write_hint != bio->bi_write_hint)
+               return false;
+
        return true;
 }
 
index e210da6..d2eb87c 100644 (file)
@@ -56,6 +56,7 @@ struct bio {
                                                 */
        unsigned short          bi_flags;       /* status, etc and bvec pool number */
        unsigned short          bi_ioprio;
+       unsigned short          bi_write_hint;
 
        struct bvec_iter        bi_iter;
 
index bf21571..0eebd3b 100644 (file)
@@ -225,6 +225,8 @@ struct request {
 
        unsigned int extra_len; /* length of alignment and padding */
 
+       unsigned short write_hint;
+
        unsigned long deadline;
        struct list_head timeout_list;