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 89a51bd49ab75e814c20371d630430e722dea649..9cf98b29588aea532d0bcd1253ebe4eac254bc31 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 3c18ea60cb1c0b7dd6a038905c0c62bc795dbc89..af393d5a96807c6c59ce45a031c14042b72b5e6a 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 5df13041b8513128c9e1e028e0711895b0ad365d..99038830fb426252144814afaf9a34954a809867 100644 (file)
@@ -672,6 +672,13 @@ static struct request *attempt_merge(struct request_queue *q,
            !blk_write_same_mergeable(req->bio, next->bio))
                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
@@ -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 e210da6d14b8fb55716e261724c9f623c8240e8f..d2eb87c84d82b7eb737d9f8a4e052d687a2dca2e 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 bf2157141d53e071808c1189b06cca9f9bc03727..0eebd3bcfd8581a37b538970b851df6766fd51b2 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;