Blame view
block/bio-integrity.c
13.8 KB
7ba1ba12e block: Block laye... |
1 2 3 |
/* * bio-integrity.c - bio data integrity extensions * |
7878cba9f block: Create bip... |
4 |
* Copyright (C) 2007, 2008, 2009 Oracle Corporation |
7ba1ba12e block: Block laye... |
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
* Written by: Martin K. Petersen <martin.petersen@oracle.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, * USA. * */ #include <linux/blkdev.h> #include <linux/mempool.h> |
afeacc8c1 fs: add export.h ... |
25 |
#include <linux/export.h> |
7ba1ba12e block: Block laye... |
26 27 |
#include <linux/bio.h> #include <linux/workqueue.h> |
5a0e3ad6a include cleanup: ... |
28 |
#include <linux/slab.h> |
1179a5a08 block/bio-integri... |
29 |
#include "blk.h" |
7ba1ba12e block: Block laye... |
30 |
|
9f060e223 block: Convert in... |
31 |
#define BIP_INLINE_VECS 4 |
7878cba9f block: Create bip... |
32 |
|
9f060e223 block: Convert in... |
33 |
static struct kmem_cache *bip_slab; |
7ba1ba12e block: Block laye... |
34 |
static struct workqueue_struct *kintegrityd_wq; |
5a48fc147 block: blk_flush_... |
35 36 37 38 |
void blk_flush_integrity(void) { flush_workqueue(kintegrityd_wq); } |
7ba1ba12e block: Block laye... |
39 |
/** |
1e2a410ff block: Ues bi_poo... |
40 |
* bio_integrity_alloc - Allocate integrity payload and attach it to bio |
7ba1ba12e block: Block laye... |
41 42 43 |
* @bio: bio to attach integrity metadata to * @gfp_mask: Memory allocation mask * @nr_vecs: Number of integrity metadata scatter-gather elements |
7ba1ba12e block: Block laye... |
44 45 46 47 48 |
* * Description: This function prepares a bio for attaching integrity * metadata. nr_vecs specifies the maximum number of pages containing * integrity metadata that can be attached. */ |
1e2a410ff block: Ues bi_poo... |
49 50 51 |
struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, gfp_t gfp_mask, unsigned int nr_vecs) |
7ba1ba12e block: Block laye... |
52 53 |
{ struct bio_integrity_payload *bip; |
1e2a410ff block: Ues bi_poo... |
54 |
struct bio_set *bs = bio->bi_pool; |
9f060e223 block: Convert in... |
55 |
unsigned inline_vecs; |
8aa6ba2f6 block: Convert bi... |
56 |
if (!bs || !mempool_initialized(&bs->bio_integrity_pool)) { |
9f060e223 block: Convert in... |
57 58 59 60 |
bip = kmalloc(sizeof(struct bio_integrity_payload) + sizeof(struct bio_vec) * nr_vecs, gfp_mask); inline_vecs = nr_vecs; } else { |
8aa6ba2f6 block: Convert bi... |
61 |
bip = mempool_alloc(&bs->bio_integrity_pool, gfp_mask); |
9f060e223 block: Convert in... |
62 |
inline_vecs = BIP_INLINE_VECS; |
7ba1ba12e block: Block laye... |
63 |
} |
9f060e223 block: Convert in... |
64 |
if (unlikely(!bip)) |
06c1e3902 blk-integrity: em... |
65 |
return ERR_PTR(-ENOMEM); |
9f060e223 block: Convert in... |
66 |
|
7878cba9f block: Create bip... |
67 |
memset(bip, 0, sizeof(*bip)); |
9f060e223 block: Convert in... |
68 |
if (nr_vecs > inline_vecs) { |
ed996a52c block: simplify a... |
69 |
unsigned long idx = 0; |
9f060e223 block: Convert in... |
70 |
bip->bip_vec = bvec_alloc(gfp_mask, nr_vecs, &idx, |
8aa6ba2f6 block: Convert bi... |
71 |
&bs->bvec_integrity_pool); |
9f060e223 block: Convert in... |
72 73 |
if (!bip->bip_vec) goto err; |
cbcd1054a bio-integrity: ad... |
74 |
bip->bip_max_vcnt = bvec_nr_vecs(idx); |
ed996a52c block: simplify a... |
75 |
bip->bip_slab = idx; |
9f060e223 block: Convert in... |
76 77 |
} else { bip->bip_vec = bip->bip_inline_vecs; |
cbcd1054a bio-integrity: ad... |
78 |
bip->bip_max_vcnt = inline_vecs; |
9f060e223 block: Convert in... |
79 |
} |
7ba1ba12e block: Block laye... |
80 81 |
bip->bip_bio = bio; bio->bi_integrity = bip; |
1eff9d322 block: rename bio... |
82 |
bio->bi_opf |= REQ_INTEGRITY; |
7ba1ba12e block: Block laye... |
83 84 |
return bip; |
9f060e223 block: Convert in... |
85 |
err: |
8aa6ba2f6 block: Convert bi... |
86 |
mempool_free(bip, &bs->bio_integrity_pool); |
06c1e3902 blk-integrity: em... |
87 |
return ERR_PTR(-ENOMEM); |
7ba1ba12e block: Block laye... |
88 |
} |
7ba1ba12e block: Block laye... |
89 90 91 92 93 |
EXPORT_SYMBOL(bio_integrity_alloc); /** * bio_integrity_free - Free bio integrity payload * @bio: bio containing bip to be freed |
7ba1ba12e block: Block laye... |
94 95 96 97 |
* * Description: Used to free the integrity portion of a bio. Usually * called from bio_free(). */ |
7c20f1168 bio-integrity: st... |
98 |
static void bio_integrity_free(struct bio *bio) |
7ba1ba12e block: Block laye... |
99 |
{ |
180b2f95d block: Replace bi... |
100 |
struct bio_integrity_payload *bip = bio_integrity(bio); |
1e2a410ff block: Ues bi_poo... |
101 |
struct bio_set *bs = bio->bi_pool; |
b1f013885 block: Relocate b... |
102 |
if (bip->bip_flags & BIP_BLOCK_INTEGRITY) |
5f9378fa9 block: Remove bip... |
103 104 |
kfree(page_address(bip->bip_vec->bv_page) + bip->bip_vec->bv_offset); |
7ba1ba12e block: Block laye... |
105 |
|
8aa6ba2f6 block: Convert bi... |
106 107 |
if (bs && mempool_initialized(&bs->bio_integrity_pool)) { bvec_free(&bs->bvec_integrity_pool, bip->bip_vec, bip->bip_slab); |
9f060e223 block: Convert in... |
108 |
|
8aa6ba2f6 block: Convert bi... |
109 |
mempool_free(bip, &bs->bio_integrity_pool); |
9f060e223 block: Convert in... |
110 111 112 |
} else { kfree(bip); } |
7ba1ba12e block: Block laye... |
113 114 |
bio->bi_integrity = NULL; |
7c20f1168 bio-integrity: st... |
115 |
bio->bi_opf &= ~REQ_INTEGRITY; |
7ba1ba12e block: Block laye... |
116 |
} |
7ba1ba12e block: Block laye... |
117 118 119 120 121 122 123 124 125 126 127 128 129 |
/** * bio_integrity_add_page - Attach integrity metadata * @bio: bio to update * @page: page containing integrity metadata * @len: number of bytes of integrity metadata in page * @offset: start offset within page * * Description: Attach a page containing integrity metadata to bio. */ int bio_integrity_add_page(struct bio *bio, struct page *page, unsigned int len, unsigned int offset) { |
180b2f95d block: Replace bi... |
130 |
struct bio_integrity_payload *bip = bio_integrity(bio); |
7ba1ba12e block: Block laye... |
131 |
struct bio_vec *iv; |
cbcd1054a bio-integrity: ad... |
132 |
if (bip->bip_vcnt >= bip->bip_max_vcnt) { |
7ba1ba12e block: Block laye... |
133 134 135 136 |
printk(KERN_ERR "%s: bip_vec full ", __func__); return 0; } |
d57a5f7c6 bio-integrity: Co... |
137 |
iv = bip->bip_vec + bip->bip_vcnt; |
7ba1ba12e block: Block laye... |
138 |
|
87a816df5 block: Refuse add... |
139 |
if (bip->bip_vcnt && |
74d46992e block: replace bi... |
140 |
bvec_gap_to_prev(bio->bi_disk->queue, |
87a816df5 block: Refuse add... |
141 142 |
&bip->bip_vec[bip->bip_vcnt - 1], offset)) return 0; |
7ba1ba12e block: Block laye... |
143 144 145 146 147 148 149 150 151 152 |
iv->bv_page = page; iv->bv_len = len; iv->bv_offset = offset; bip->bip_vcnt++; return len; } EXPORT_SYMBOL(bio_integrity_add_page); /** |
3be91c4a3 block: Deprecate ... |
153 |
* bio_integrity_intervals - Return number of integrity intervals for a bio |
7ba1ba12e block: Block laye... |
154 |
* @bi: blk_integrity profile for device |
3be91c4a3 block: Deprecate ... |
155 |
* @sectors: Size of the bio in 512-byte sectors |
7ba1ba12e block: Block laye... |
156 157 |
* * Description: The block layer calculates everything in 512 byte |
3be91c4a3 block: Deprecate ... |
158 159 160 |
* sectors but integrity metadata is done in terms of the data integrity * interval size of the storage device. Convert the block layer sectors * to the appropriate number of integrity intervals. |
7ba1ba12e block: Block laye... |
161 |
*/ |
3be91c4a3 block: Deprecate ... |
162 163 |
static inline unsigned int bio_integrity_intervals(struct blk_integrity *bi, unsigned int sectors) |
7ba1ba12e block: Block laye... |
164 |
{ |
a48f041d9 block: Reduce the... |
165 |
return sectors >> (bi->interval_exp - 9); |
7ba1ba12e block: Block laye... |
166 |
} |
d57a5f7c6 bio-integrity: Co... |
167 168 169 |
static inline unsigned int bio_integrity_bytes(struct blk_integrity *bi, unsigned int sectors) { |
3be91c4a3 block: Deprecate ... |
170 |
return bio_integrity_intervals(bi, sectors) * bi->tuple_size; |
d57a5f7c6 bio-integrity: Co... |
171 |
} |
7ba1ba12e block: Block laye... |
172 |
/** |
185930885 block: Clean up t... |
173 |
* bio_integrity_process - Process integrity metadata for a bio |
bf36f9cfa fs/bio-integrity:... |
174 |
* @bio: bio to generate/verify integrity metadata for |
63573e359 bio-integrity: Re... |
175 |
* @proc_iter: iterator to process |
185930885 block: Clean up t... |
176 |
* @proc_fn: Pointer to the relevant processing function |
7ba1ba12e block: Block laye... |
177 |
*/ |
4e4cbee93 block: switch bio... |
178 |
static blk_status_t bio_integrity_process(struct bio *bio, |
63573e359 bio-integrity: Re... |
179 |
struct bvec_iter *proc_iter, integrity_processing_fn *proc_fn) |
7ba1ba12e block: Block laye... |
180 |
{ |
74d46992e block: replace bi... |
181 |
struct blk_integrity *bi = blk_get_integrity(bio->bi_disk); |
185930885 block: Clean up t... |
182 |
struct blk_integrity_iter iter; |
594416a72 block: fix regres... |
183 184 |
struct bvec_iter bviter; struct bio_vec bv; |
5f9378fa9 block: Remove bip... |
185 |
struct bio_integrity_payload *bip = bio_integrity(bio); |
4e4cbee93 block: switch bio... |
186 |
blk_status_t ret = BLK_STS_OK; |
5f9378fa9 block: Remove bip... |
187 188 |
void *prot_buf = page_address(bip->bip_vec->bv_page) + bip->bip_vec->bv_offset; |
7ba1ba12e block: Block laye... |
189 |
|
74d46992e block: replace bi... |
190 |
iter.disk_name = bio->bi_disk->disk_name; |
a48f041d9 block: Reduce the... |
191 |
iter.interval = 1 << bi->interval_exp; |
63573e359 bio-integrity: Re... |
192 |
iter.seed = proc_iter->bi_sector; |
185930885 block: Clean up t... |
193 |
iter.prot_buf = prot_buf; |
7ba1ba12e block: Block laye... |
194 |
|
63573e359 bio-integrity: Re... |
195 |
__bio_for_each_segment(bv, bio, bviter, *proc_iter) { |
594416a72 block: fix regres... |
196 |
void *kaddr = kmap_atomic(bv.bv_page); |
7ba1ba12e block: Block laye... |
197 |
|
594416a72 block: fix regres... |
198 199 |
iter.data_buf = kaddr + bv.bv_offset; iter.data_size = bv.bv_len; |
185930885 block: Clean up t... |
200 201 202 203 204 205 |
ret = proc_fn(&iter); if (ret) { kunmap_atomic(kaddr); return ret; } |
7ba1ba12e block: Block laye... |
206 |
|
e8e3c3d66 fs: remove the se... |
207 |
kunmap_atomic(kaddr); |
7ba1ba12e block: Block laye... |
208 |
} |
bf36f9cfa fs/bio-integrity:... |
209 210 211 212 |
return ret; } /** |
7ba1ba12e block: Block laye... |
213 214 215 |
* bio_integrity_prep - Prepare bio for integrity I/O * @bio: bio to prepare * |
e23947bd7 bio-integrity: fo... |
216 217 218 219 220 221 |
* Description: Checks if the bio already has an integrity payload attached. * If it does, the payload has been generated by another kernel subsystem, * and we just pass it through. Otherwise allocates integrity payload. * The bio must have data direction, target device and start sector set priot * to calling. In the WRITE case, integrity metadata will be generated using * the block device's integrity function. In the READ case, the buffer |
7ba1ba12e block: Block laye... |
222 223 |
* will be prepared for DMA and a suitable end_io handler set up. */ |
e23947bd7 bio-integrity: fo... |
224 |
bool bio_integrity_prep(struct bio *bio) |
7ba1ba12e block: Block laye... |
225 226 |
{ struct bio_integrity_payload *bip; |
74d46992e block: replace bi... |
227 228 |
struct blk_integrity *bi = blk_get_integrity(bio->bi_disk); struct request_queue *q = bio->bi_disk->queue; |
7ba1ba12e block: Block laye... |
229 230 231 232 |
void *buf; unsigned long start, end; unsigned int len, nr_pages; unsigned int bytes, offset, i; |
3be91c4a3 block: Deprecate ... |
233 |
unsigned int intervals; |
e23947bd7 bio-integrity: fo... |
234 |
blk_status_t status; |
7ba1ba12e block: Block laye... |
235 |
|
9346beb9d bio-integrity: mo... |
236 237 |
if (!bi) return true; |
e23947bd7 bio-integrity: fo... |
238 239 240 241 242 |
if (bio_op(bio) != REQ_OP_READ && bio_op(bio) != REQ_OP_WRITE) return true; if (!bio_sectors(bio)) return true; |
7ba1ba12e block: Block laye... |
243 |
|
e23947bd7 bio-integrity: fo... |
244 245 246 |
/* Already protected? */ if (bio_integrity(bio)) return true; |
e23947bd7 bio-integrity: fo... |
247 248 249 250 251 252 253 254 255 |
if (bio_data_dir(bio) == READ) { if (!bi->profile->verify_fn || !(bi->flags & BLK_INTEGRITY_VERIFY)) return true; } else { if (!bi->profile->generate_fn || !(bi->flags & BLK_INTEGRITY_GENERATE)) return true; } |
3be91c4a3 block: Deprecate ... |
256 |
intervals = bio_integrity_intervals(bi, bio_sectors(bio)); |
7ba1ba12e block: Block laye... |
257 258 |
/* Allocate kernel buffer for protection data */ |
3be91c4a3 block: Deprecate ... |
259 |
len = intervals * bi->tuple_size; |
72f465033 bio-integrity.c: ... |
260 |
buf = kmalloc(len, GFP_NOIO | q->bounce_gfp); |
e23947bd7 bio-integrity: fo... |
261 |
status = BLK_STS_RESOURCE; |
7ba1ba12e block: Block laye... |
262 263 264 |
if (unlikely(buf == NULL)) { printk(KERN_ERR "could not allocate integrity buffer "); |
e23947bd7 bio-integrity: fo... |
265 |
goto err_end_io; |
7ba1ba12e block: Block laye... |
266 267 268 269 270 271 272 273 |
} end = (((unsigned long) buf) + len + PAGE_SIZE - 1) >> PAGE_SHIFT; start = ((unsigned long) buf) >> PAGE_SHIFT; nr_pages = end - start; /* Allocate bio integrity payload and integrity vectors */ bip = bio_integrity_alloc(bio, GFP_NOIO, nr_pages); |
7b6c0f803 blk-integrity: ch... |
274 |
if (IS_ERR(bip)) { |
7ba1ba12e block: Block laye... |
275 276 277 |
printk(KERN_ERR "could not allocate data integrity bioset "); kfree(buf); |
e23947bd7 bio-integrity: fo... |
278 279 |
status = BLK_STS_RESOURCE; goto err_end_io; |
7ba1ba12e block: Block laye... |
280 |
} |
b1f013885 block: Relocate b... |
281 |
bip->bip_flags |= BIP_BLOCK_INTEGRITY; |
d57a5f7c6 bio-integrity: Co... |
282 |
bip->bip_iter.bi_size = len; |
185930885 block: Clean up t... |
283 |
bip_set_seed(bip, bio->bi_iter.bi_sector); |
7ba1ba12e block: Block laye... |
284 |
|
aae7df501 block: Integrity ... |
285 286 |
if (bi->flags & BLK_INTEGRITY_IP_CHECKSUM) bip->bip_flags |= BIP_IP_CHECKSUM; |
7ba1ba12e block: Block laye... |
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
/* Map it */ offset = offset_in_page(buf); for (i = 0 ; i < nr_pages ; i++) { int ret; bytes = PAGE_SIZE - offset; if (len <= 0) break; if (bytes > len) bytes = len; ret = bio_integrity_add_page(bio, virt_to_page(buf), bytes, offset); if (ret == 0) |
ea4d12dab bio-integrity: fi... |
303 |
return false; |
7ba1ba12e block: Block laye... |
304 305 306 307 308 309 310 311 |
if (ret < bytes) break; buf += bytes; len -= bytes; offset = 0; } |
7ba1ba12e block: Block laye... |
312 |
/* Auto-generate integrity metadata if this is a write */ |
63573e359 bio-integrity: Re... |
313 314 315 316 |
if (bio_data_dir(bio) == WRITE) { bio_integrity_process(bio, &bio->bi_iter, bi->profile->generate_fn); } |
e23947bd7 bio-integrity: fo... |
317 318 319 320 321 322 |
return true; err_end_io: bio->bi_status = status; bio_endio(bio); return false; |
7ba1ba12e block: Block laye... |
323 |
|
7ba1ba12e block: Block laye... |
324 325 326 327 |
} EXPORT_SYMBOL(bio_integrity_prep); /** |
7ba1ba12e block: Block laye... |
328 329 330 331 332 333 334 335 336 |
* bio_integrity_verify_fn - Integrity I/O completion worker * @work: Work struct stored in bio to be verified * * Description: This workqueue function is called to complete a READ * request. The function verifies the transferred integrity metadata * and then calls the original bio end_io function. */ static void bio_integrity_verify_fn(struct work_struct *work) { |
b984679ef block: integrity ... |
337 |
struct bio_integrity_payload *bip = |
7ba1ba12e block: Block laye... |
338 339 |
container_of(work, struct bio_integrity_payload, bip_work); struct bio *bio = bip->bip_bio; |
74d46992e block: replace bi... |
340 |
struct blk_integrity *bi = blk_get_integrity(bio->bi_disk); |
63573e359 bio-integrity: Re... |
341 342 343 344 345 346 347 348 349 350 351 352 353 |
struct bvec_iter iter = bio->bi_iter; /* * At the moment verify is called bio's iterator was advanced * during split and completion, we need to rewind iterator to * it's original position. */ if (bio_rewind_iter(bio, &iter, iter.bi_done)) { bio->bi_status = bio_integrity_process(bio, &iter, bi->profile->verify_fn); } else { bio->bi_status = BLK_STS_IOERR; } |
7ba1ba12e block: Block laye... |
354 |
|
7c20f1168 bio-integrity: st... |
355 |
bio_integrity_free(bio); |
4246a0b63 block: add a bi_e... |
356 |
bio_endio(bio); |
7ba1ba12e block: Block laye... |
357 358 359 |
} /** |
7c20f1168 bio-integrity: st... |
360 |
* __bio_integrity_endio - Integrity I/O completion function |
7ba1ba12e block: Block laye... |
361 |
* @bio: Protected bio |
7ba1ba12e block: Block laye... |
362 363 364 365 366 367 368 369 |
* * Description: Completion for integrity I/O * * Normally I/O completion is done in interrupt context. However, * verifying I/O integrity is a time-consuming task which must be run * in process context. This function postpones completion * accordingly. */ |
7c20f1168 bio-integrity: st... |
370 |
bool __bio_integrity_endio(struct bio *bio) |
7ba1ba12e block: Block laye... |
371 |
{ |
97e05463e bio-integrity: Fi... |
372 |
struct blk_integrity *bi = blk_get_integrity(bio->bi_disk); |
f86e28c4d bio-integrity: on... |
373 |
struct bio_integrity_payload *bip = bio_integrity(bio); |
c775d2098 bio-integrity: Fi... |
374 375 |
if (bio_op(bio) == REQ_OP_READ && !bio->bi_status && |
f86e28c4d bio-integrity: on... |
376 |
(bip->bip_flags & BIP_BLOCK_INTEGRITY) && bi->profile->verify_fn) { |
7c20f1168 bio-integrity: st... |
377 378 379 |
INIT_WORK(&bip->bip_work, bio_integrity_verify_fn); queue_work(kintegrityd_wq, &bip->bip_work); return false; |
7b24fc4d7 block: Don't veri... |
380 |
} |
7c20f1168 bio-integrity: st... |
381 382 |
bio_integrity_free(bio); return true; |
7ba1ba12e block: Block laye... |
383 |
} |
7ba1ba12e block: Block laye... |
384 385 |
/** |
7ba1ba12e block: Block laye... |
386 387 388 389 390 391 392 393 394 395 |
* bio_integrity_advance - Advance integrity vector * @bio: bio whose integrity vector to update * @bytes_done: number of data bytes that have been completed * * Description: This function calculates how many integrity bytes the * number of completed data bytes correspond to and advances the * integrity vector accordingly. */ void bio_integrity_advance(struct bio *bio, unsigned int bytes_done) { |
180b2f95d block: Replace bi... |
396 |
struct bio_integrity_payload *bip = bio_integrity(bio); |
74d46992e block: replace bi... |
397 |
struct blk_integrity *bi = blk_get_integrity(bio->bi_disk); |
d57a5f7c6 bio-integrity: Co... |
398 |
unsigned bytes = bio_integrity_bytes(bi, bytes_done >> 9); |
7ba1ba12e block: Block laye... |
399 |
|
309a62fa3 bio-integrity: bi... |
400 |
bip->bip_iter.bi_sector += bytes_done >> 9; |
d57a5f7c6 bio-integrity: Co... |
401 |
bvec_iter_advance(bip->bip_vec, &bip->bip_iter, bytes); |
7ba1ba12e block: Block laye... |
402 403 404 405 406 407 |
} EXPORT_SYMBOL(bio_integrity_advance); /** * bio_integrity_trim - Trim integrity vector * @bio: bio whose integrity vector to update |
7ba1ba12e block: Block laye... |
408 409 |
* * Description: Used to trim the integrity vector in a cloned bio. |
7ba1ba12e block: Block laye... |
410 |
*/ |
fbd08e767 bio-integrity: fi... |
411 |
void bio_integrity_trim(struct bio *bio) |
7ba1ba12e block: Block laye... |
412 |
{ |
180b2f95d block: Replace bi... |
413 |
struct bio_integrity_payload *bip = bio_integrity(bio); |
74d46992e block: replace bi... |
414 |
struct blk_integrity *bi = blk_get_integrity(bio->bi_disk); |
7ba1ba12e block: Block laye... |
415 |
|
fbd08e767 bio-integrity: fi... |
416 |
bip->bip_iter.bi_size = bio_integrity_bytes(bi, bio_sectors(bio)); |
7ba1ba12e block: Block laye... |
417 418 419 420 |
} EXPORT_SYMBOL(bio_integrity_trim); /** |
7ba1ba12e block: Block laye... |
421 422 423 |
* bio_integrity_clone - Callback for cloning bios with integrity metadata * @bio: New bio * @bio_src: Original bio |
87092698c block: Add gfp_ma... |
424 |
* @gfp_mask: Memory allocation mask |
7ba1ba12e block: Block laye... |
425 426 427 |
* * Description: Called to allocate a bip when cloning a bio */ |
7878cba9f block: Create bip... |
428 |
int bio_integrity_clone(struct bio *bio, struct bio *bio_src, |
1e2a410ff block: Ues bi_poo... |
429 |
gfp_t gfp_mask) |
7ba1ba12e block: Block laye... |
430 |
{ |
180b2f95d block: Replace bi... |
431 |
struct bio_integrity_payload *bip_src = bio_integrity(bio_src); |
7ba1ba12e block: Block laye... |
432 433 434 |
struct bio_integrity_payload *bip; BUG_ON(bip_src == NULL); |
1e2a410ff block: Ues bi_poo... |
435 |
bip = bio_integrity_alloc(bio, gfp_mask, bip_src->bip_vcnt); |
7b6c0f803 blk-integrity: ch... |
436 437 |
if (IS_ERR(bip)) return PTR_ERR(bip); |
7ba1ba12e block: Block laye... |
438 439 440 |
memcpy(bip->bip_vec, bip_src->bip_vec, bip_src->bip_vcnt * sizeof(struct bio_vec)); |
7ba1ba12e block: Block laye... |
441 |
bip->bip_vcnt = bip_src->bip_vcnt; |
d57a5f7c6 bio-integrity: Co... |
442 |
bip->bip_iter = bip_src->bip_iter; |
7ba1ba12e block: Block laye... |
443 444 445 446 |
return 0; } EXPORT_SYMBOL(bio_integrity_clone); |
7878cba9f block: Create bip... |
447 |
int bioset_integrity_create(struct bio_set *bs, int pool_size) |
7ba1ba12e block: Block laye... |
448 |
{ |
8aa6ba2f6 block: Convert bi... |
449 |
if (mempool_initialized(&bs->bio_integrity_pool)) |
a91a2785b block: Require su... |
450 |
return 0; |
8aa6ba2f6 block: Convert bi... |
451 452 |
if (mempool_init_slab_pool(&bs->bio_integrity_pool, pool_size, bip_slab)) |
9f060e223 block: Convert in... |
453 |
return -1; |
7ba1ba12e block: Block laye... |
454 |
|
8aa6ba2f6 block: Convert bi... |
455 456 |
if (biovec_init_pool(&bs->bvec_integrity_pool, pool_size)) { mempool_exit(&bs->bio_integrity_pool); |
7878cba9f block: Create bip... |
457 |
return -1; |
bc5c8f078 fs/bio-integrity:... |
458 |
} |
7878cba9f block: Create bip... |
459 460 461 462 463 464 465 |
return 0; } EXPORT_SYMBOL(bioset_integrity_create); void bioset_integrity_free(struct bio_set *bs) { |
8aa6ba2f6 block: Convert bi... |
466 467 |
mempool_exit(&bs->bio_integrity_pool); mempool_exit(&bs->bvec_integrity_pool); |
7878cba9f block: Create bip... |
468 469 470 471 472 |
} EXPORT_SYMBOL(bioset_integrity_free); void __init bio_integrity_init(void) { |
a6e8dc46f bio-integrity: ma... |
473 474 475 476 477 478 |
/* * kintegrityd won't block much but may burn a lot of CPU cycles. * Make it highpri CPU intensive wq with max concurrency of 1. */ kintegrityd_wq = alloc_workqueue("kintegrityd", WQ_MEM_RECLAIM | WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1); |
6d2a78e78 block: add privat... |
479 480 481 |
if (!kintegrityd_wq) panic("Failed to create kintegrityd "); |
7ba1ba12e block: Block laye... |
482 |
|
9f060e223 block: Convert in... |
483 484 485 486 |
bip_slab = kmem_cache_create("bio_integrity_payload", sizeof(struct bio_integrity_payload) + sizeof(struct bio_vec) * BIP_INLINE_VECS, 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); |
7ba1ba12e block: Block laye... |
487 |
} |