[COMMON] bio: support diskcipher
authorBoojin Kim <boojin.kim@samsung.com>
Wed, 24 Jan 2018 08:01:43 +0000 (17:01 +0900)
committerJaeHun Jung <jh0801.jung@samsung.com>
Tue, 8 May 2018 08:20:59 +0000 (17:20 +0900)
Change-Id: I61774e13ba45c5a21ea9e08d820534302deaf91d
Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
block/bio.c
block/blk-merge.c
include/linux/bio.h
include/linux/blk_types.h
include/linux/blkdev.h

index 7f978eac9a7ae9729082a87ffb39b7c4db3a544a..01a037c1d3f4bef3219e50b730540024dfe80c93 100644 (file)
@@ -607,6 +607,9 @@ void __bio_clone_fast(struct bio *bio, struct bio *bio_src)
        bio->bi_io_vec = bio_src->bi_io_vec;
 
        bio_clone_blkcg_association(bio, bio_src);
+
+       if (bio->bi_opf & REQ_AUX_PRIV)
+               bio->bi_aux_private = bio_src->bi_aux_private;
 }
 EXPORT_SYMBOL(__bio_clone_fast);
 
@@ -689,6 +692,8 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
        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;
+       if (bio->bi_opf & REQ_AUX_PRIV)
+               bio->bi_aux_private = bio_src->bi_aux_private;
 
        switch (bio_op(bio)) {
        case REQ_OP_DISCARD:
index f5dedd57dff6b40fb6e88faa532bb88a94fcde61..7e7f42e2e450d62ff01c10da5d21ddfc91047352 100644 (file)
@@ -673,6 +673,9 @@ static struct request *attempt_merge(struct request_queue *q,
            !blk_write_same_mergeable(req->bio, next->bio))
                return NULL;
 
+       if (!blk_crypt_mergeable(req->bio, next->bio))
+               return NULL;
+
        /*
         * Don't allow merge of different write hints, or for a hint with
         * non-hint IO.
@@ -799,6 +802,8 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
            !blk_write_same_mergeable(rq->bio, bio))
                return false;
 
+       if (!blk_crypt_mergeable(rq->bio, bio))
+               return false;
        /*
         * Don't allow merge of different write hints, or for a hint with
         * non-hint IO.
index 45f00dd6323c90abbde48255cc018bb7befd7f5f..52cb51456ce2d310de3448f945f4f54fdcbdc187 100644 (file)
@@ -123,6 +123,14 @@ static inline void *bio_data(struct bio *bio)
        return NULL;
 }
 
+static inline bool bio_has_crypt(struct bio *bio)
+{
+       if (bio && (bio->bi_opf & REQ_CRYPT))
+               return true;
+       else
+               return false;
+}
+
 /*
  * will die
  */
index 1c8a8a2aedf7134cca3599fde2890e7085558e90..4dc0b3e03dac83fa389ebde63c1d0a7b6e6f665a 100644 (file)
@@ -78,6 +78,8 @@ struct bio {
        bio_end_io_t            *bi_end_io;
 
        void                    *bi_private;
+       void                    *bi_aux_private;
+
 #ifdef CONFIG_BLK_CGROUP
        /*
         * Optional ioc and css associated with this bio.  Put on bio
@@ -222,6 +224,8 @@ enum req_flag_bits {
        __REQ_INTEGRITY,        /* I/O includes block integrity payload */
        __REQ_FUA,              /* forced unit access */
        __REQ_PREFLUSH,         /* request for cache flush */
+       __REQ_AUX_PRIV,         /* use bi_aux_private */
+       __REQ_CRYPT,            /* request inline crypt */
        __REQ_RAHEAD,           /* read ahead, can fail anytime */
        __REQ_BACKGROUND,       /* background IO */
 
@@ -241,6 +245,8 @@ enum req_flag_bits {
 #define REQ_NOMERGE            (1ULL << __REQ_NOMERGE)
 #define REQ_IDLE               (1ULL << __REQ_IDLE)
 #define REQ_INTEGRITY          (1ULL << __REQ_INTEGRITY)
+#define REQ_AUX_PRIV           (1ULL << __REQ_AUX_PRIV)
+#define REQ_CRYPT              (1ULL << __REQ_CRYPT)
 #define REQ_FUA                        (1ULL << __REQ_FUA)
 #define REQ_PREFLUSH           (1ULL << __REQ_PREFLUSH)
 #define REQ_RAHEAD             (1ULL << __REQ_RAHEAD)
index 6362e3606aa50948d3c6ed19eeb836b3386e3063..c280518d8f8f1d300aa01920d25d2a82bd30e920 100644 (file)
@@ -866,6 +866,15 @@ static inline unsigned int blk_queue_depth(struct request_queue *q)
        return q->nr_requests;
 }
 
+static inline bool blk_crypt_mergeable(struct bio *a, struct bio *b)
+{
+       if (bio_has_crypt(a) && bio_has_crypt(b))
+               if (a->bi_aux_private != b->bi_aux_private)
+                       return false;
+
+       return true;
+}
+
 /*
  * q->prep_rq_fn return values
  */