1 This adds optional integrity functions for given bio, they are
2 passed to bio_integrity_prep and initialized in
4 The optional integrity generate/verify functions take priority
5 over the ones registered on the block device.
7 It brings flexibility to bio integrity handling. e.g. a network
8 filesystem with integrity support would have integrity
9 generation happen on the clients, and send them over the wire.
10 On the server side once we receive the integrity bits and pass
11 the network layer checksums we would merely pass it on to the
12 block devices have integrity support, so we don't have to
13 calculate the integrity again.
14 Verification shares the same principle: on the server we just
15 copy the integrity bits from the device and send them through
16 the wire, then the verification happens on the clients.
18 Index: linux-4.18.0-80.el8/block/bio-integrity.c
19 ===================================================================
20 --- linux-4.18.0-80.el8.orig/block/bio-integrity.c
21 +++ linux-4.18.0-80.el8/block/bio-integrity.c
22 @@ -39,7 +39,7 @@ void blk_flush_integrity(void)
26 - * bio_integrity_alloc - Allocate integrity payload and attach it to bio
27 + * bio_integrity_alloc_fn - Allocate integrity payload and attach it to bio
28 * @bio: bio to attach integrity metadata to
29 * @gfp_mask: Memory allocation mask
30 * @nr_vecs: Number of integrity metadata scatter-gather elements
31 @@ -48,9 +48,11 @@ void blk_flush_integrity(void)
32 * metadata. nr_vecs specifies the maximum number of pages containing
33 * integrity metadata that can be attached.
35 -struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio,
37 - unsigned int nr_vecs)
38 +struct bio_integrity_payload *bio_integrity_alloc_fn(struct bio *bio,
40 + unsigned int nr_vecs,
41 + integrity_processing_fn *generate_fn,
42 + integrity_processing_fn *verify_fn)
44 struct bio_integrity_payload *bip;
45 struct bio_set *bs = bio->bi_pool;
46 @@ -85,6 +87,8 @@ struct bio_integrity_payload *bio_integr
50 + bip->bip_generate_fn = generate_fn;
51 + bip->bip_verify_fn = verify_fn;
52 bio->bi_integrity = bip;
53 bio->bi_opf |= REQ_INTEGRITY;
55 @@ -93,6 +97,13 @@ err:
56 mempool_free(bip, &bs->bio_integrity_pool);
57 return ERR_PTR(-ENOMEM);
59 +EXPORT_SYMBOL(bio_integrity_alloc_fn);
61 +struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, gfp_t gfp,
64 + return bio_integrity_alloc_fn(bio, gfp, nr, NULL, NULL);
66 EXPORT_SYMBOL(bio_integrity_alloc);
69 @@ -213,7 +224,7 @@ static blk_status_t bio_integrity_proces
71 bool bio_integrity_prep(struct bio *bio)
73 - struct bio_integrity_payload *bip;
74 + struct bio_integrity_payload *bip = bio_integrity(bio);
75 struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
76 struct request_queue *q = bio->bi_disk->queue;
78 @@ -222,6 +233,8 @@ bool bio_integrity_prep(struct bio *bio)
79 unsigned int bytes, offset, i;
80 unsigned int intervals;
82 + integrity_processing_fn *generate_fn;
83 + integrity_processing_fn *verify_fn;
87 @@ -232,16 +245,20 @@ bool bio_integrity_prep(struct bio *bio)
88 if (!bio_sectors(bio))
91 - /* Already protected? */
92 - if (bio_integrity(bio))
95 + generate_fn = bip->bip_generate_fn ?: bi->profile->generate_fn;
96 + verify_fn = bip->bip_verify_fn ?: bi->profile->verify_fn;
98 + generate_fn = bi->profile->generate_fn;
99 + verify_fn = bi->profile->verify_fn;
102 if (bio_data_dir(bio) == READ) {
103 - if (!bi->profile->verify_fn ||
105 !(bi->flags & BLK_INTEGRITY_VERIFY))
108 - if (!bi->profile->generate_fn ||
109 + if (!generate_fn ||
110 !(bi->flags & BLK_INTEGRITY_GENERATE))
113 @@ -261,7 +278,8 @@ bool bio_integrity_prep(struct bio *bio)
114 nr_pages = end - start;
116 /* Allocate bio integrity payload and integrity vectors */
117 - bip = bio_integrity_alloc(bio, GFP_NOIO, nr_pages);
118 + bip = bio_integrity_alloc_fn(bio, GFP_NOIO, nr_pages,
119 + generate_fn, verify_fn);
121 printk(KERN_ERR "could not allocate data integrity bioset\n");
123 @@ -304,8 +322,7 @@ bool bio_integrity_prep(struct bio *bio)
125 /* Auto-generate integrity metadata if this is a write */
126 if (bio_data_dir(bio) == WRITE) {
127 - bio_integrity_process(bio, &bio->bi_iter,
128 - bi->profile->generate_fn);
129 + bio_integrity_process(bio, &bio->bi_iter, generate_fn);
131 bip->bio_iter = bio->bi_iter;
133 @@ -333,6 +350,13 @@ static void bio_integrity_verify_fn(stru
134 container_of(work, struct bio_integrity_payload, bip_work);
135 struct bio *bio = bip->bip_bio;
136 struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
137 + struct bio_integrity_payload *bio_bip = bio_integrity(bio);
138 + integrity_processing_fn *verify_fn;
140 + if (bio_bip != NULL)
141 + verify_fn = bio_bip->bip_verify_fn ?: bi->profile->verify_fn;
143 + verify_fn = bi->profile->verify_fn;
146 * At the moment verify is called bio's iterator was advanced
147 @@ -340,7 +364,7 @@ static void bio_integrity_verify_fn(stru
148 * it's original position.
150 bio->bi_status = bio_integrity_process(bio, &bip->bio_iter,
151 - bi->profile->verify_fn);
153 bio_integrity_free(bio);
156 @@ -423,7 +447,9 @@ int bio_integrity_clone(struct bio *bio,
158 BUG_ON(bip_src == NULL);
160 - bip = bio_integrity_alloc(bio, gfp_mask, bip_src->bip_vcnt);
161 + bip = bio_integrity_alloc_fn(bio, gfp_mask, bip_src->bip_vcnt,
162 + bip_src->bip_generate_fn,
163 + bip_src->bip_verify_fn);
167 Index: linux-4.18.0-80.el8/include/linux/bio.h
168 ===================================================================
169 --- linux-4.18.0-80.el8.orig/include/linux/bio.h
170 +++ linux-4.18.0-80.el8/include/linux/bio.h
171 @@ -313,6 +313,10 @@ struct bio_integrity_payload {
173 struct bio_vec *bip_vec;
175 + /* put after bip_vec as that is last externally-accessed bip_ field */
176 + integrity_processing_fn *bip_generate_fn;
177 + integrity_processing_fn *bip_verify_fn;
182 @@ -760,6 +764,11 @@ static inline bool bioset_initialized(st
183 bip_for_each_vec(_bvl, _bio->bi_integrity, _iter)
185 extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int);
186 +extern struct bio_integrity_payload *bio_integrity_alloc_fn(struct bio *bio,
188 + unsigned int nr_vecs,
189 + integrity_processing_fn *generate_fn,
190 + integrity_processing_fn *verify_fn);
191 extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int);
192 extern bool bio_integrity_prep(struct bio *);
193 extern void bio_integrity_advance(struct bio *, unsigned int);
194 Index: linux-4.18.0-80.el8/include/linux/blk_types.h
195 ===================================================================
196 --- linux-4.18.0-80.el8.orig/include/linux/blk_types.h
197 +++ linux-4.18.0-80.el8/include/linux/blk_types.h
198 @@ -18,6 +18,7 @@ struct page;
201 struct cgroup_subsys_state;
202 +struct blk_integrity_iter;
203 typedef void (bio_end_io_t) (struct bio *);
206 @@ -29,6 +30,9 @@ typedef u32 __bitwise blk_status_t;
208 typedef u8 __bitwise blk_status_t;
211 +typedef blk_status_t (integrity_processing_fn) (struct blk_integrity_iter *);
214 #define BLK_STS_NOTSUPP ((__force blk_status_t)1)
215 #define BLK_STS_TIMEOUT ((__force blk_status_t)2)