| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * bio-integrity.c - bio data integrity extensions |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2007, 2008, 2009 Oracle Corporation |
|---|
| 5 | 6 | * Written by: Martin K. Petersen <martin.petersen@oracle.com> |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or |
|---|
| 8 | | - * modify it under the terms of the GNU General Public License version |
|---|
| 9 | | - * 2 as published by the Free Software Foundation. |
|---|
| 10 | | - * |
|---|
| 11 | | - * This program is distributed in the hope that it will be useful, but |
|---|
| 12 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 14 | | - * General Public License for more details. |
|---|
| 15 | | - * |
|---|
| 16 | | - * You should have received a copy of the GNU General Public License |
|---|
| 17 | | - * along with this program; see the file COPYING. If not, write to |
|---|
| 18 | | - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, |
|---|
| 19 | | - * USA. |
|---|
| 20 | | - * |
|---|
| 21 | 7 | */ |
|---|
| 22 | 8 | |
|---|
| 23 | 9 | #include <linux/blkdev.h> |
|---|
| .. | .. |
|---|
| 38 | 24 | flush_workqueue(kintegrityd_wq); |
|---|
| 39 | 25 | } |
|---|
| 40 | 26 | |
|---|
| 41 | | -void __bio_integrity_free(struct bio_set *bs, struct bio_integrity_payload *bip) |
|---|
| 27 | +static void __bio_integrity_free(struct bio_set *bs, |
|---|
| 28 | + struct bio_integrity_payload *bip) |
|---|
| 42 | 29 | { |
|---|
| 43 | 30 | if (bs && mempool_initialized(&bs->bio_integrity_pool)) { |
|---|
| 44 | 31 | if (bip->bip_vec) |
|---|
| .. | .. |
|---|
| 68 | 55 | struct bio_set *bs = bio->bi_pool; |
|---|
| 69 | 56 | unsigned inline_vecs; |
|---|
| 70 | 57 | |
|---|
| 58 | + if (WARN_ON_ONCE(bio_has_crypt_ctx(bio))) |
|---|
| 59 | + return ERR_PTR(-EOPNOTSUPP); |
|---|
| 60 | + |
|---|
| 71 | 61 | if (!bs || !mempool_initialized(&bs->bio_integrity_pool)) { |
|---|
| 72 | | - bip = kmalloc(sizeof(struct bio_integrity_payload) + |
|---|
| 73 | | - sizeof(struct bio_vec) * nr_vecs, gfp_mask); |
|---|
| 62 | + bip = kmalloc(struct_size(bip, bip_inline_vecs, nr_vecs), gfp_mask); |
|---|
| 74 | 63 | inline_vecs = nr_vecs; |
|---|
| 75 | 64 | } else { |
|---|
| 76 | 65 | bip = mempool_alloc(&bs->bio_integrity_pool, gfp_mask); |
|---|
| .. | .. |
|---|
| 114 | 103 | * Description: Used to free the integrity portion of a bio. Usually |
|---|
| 115 | 104 | * called from bio_free(). |
|---|
| 116 | 105 | */ |
|---|
| 117 | | -static void bio_integrity_free(struct bio *bio) |
|---|
| 106 | +void bio_integrity_free(struct bio *bio) |
|---|
| 118 | 107 | { |
|---|
| 119 | 108 | struct bio_integrity_payload *bip = bio_integrity(bio); |
|---|
| 120 | 109 | struct bio_set *bs = bio->bi_pool; |
|---|
| .. | .. |
|---|
| 314 | 303 | if (bio_data_dir(bio) == WRITE) { |
|---|
| 315 | 304 | bio_integrity_process(bio, &bio->bi_iter, |
|---|
| 316 | 305 | bi->profile->generate_fn); |
|---|
| 306 | + } else { |
|---|
| 307 | + bip->bio_iter = bio->bi_iter; |
|---|
| 317 | 308 | } |
|---|
| 318 | 309 | return true; |
|---|
| 319 | 310 | |
|---|
| .. | .. |
|---|
| 339 | 330 | container_of(work, struct bio_integrity_payload, bip_work); |
|---|
| 340 | 331 | struct bio *bio = bip->bip_bio; |
|---|
| 341 | 332 | struct blk_integrity *bi = blk_get_integrity(bio->bi_disk); |
|---|
| 342 | | - struct bvec_iter iter = bio->bi_iter; |
|---|
| 343 | 333 | |
|---|
| 344 | 334 | /* |
|---|
| 345 | 335 | * At the moment verify is called bio's iterator was advanced |
|---|
| 346 | 336 | * during split and completion, we need to rewind iterator to |
|---|
| 347 | 337 | * it's original position. |
|---|
| 348 | 338 | */ |
|---|
| 349 | | - if (bio_rewind_iter(bio, &iter, iter.bi_done)) { |
|---|
| 350 | | - bio->bi_status = bio_integrity_process(bio, &iter, |
|---|
| 351 | | - bi->profile->verify_fn); |
|---|
| 352 | | - } else { |
|---|
| 353 | | - bio->bi_status = BLK_STS_IOERR; |
|---|
| 354 | | - } |
|---|
| 355 | | - |
|---|
| 339 | + bio->bi_status = bio_integrity_process(bio, &bip->bio_iter, |
|---|
| 340 | + bi->profile->verify_fn); |
|---|
| 356 | 341 | bio_integrity_free(bio); |
|---|
| 357 | 342 | bio_endio(bio); |
|---|
| 358 | 343 | } |
|---|
| .. | .. |
|---|
| 402 | 387 | bip->bip_iter.bi_sector += bio_integrity_intervals(bi, bytes_done >> 9); |
|---|
| 403 | 388 | bvec_iter_advance(bip->bip_vec, &bip->bip_iter, bytes); |
|---|
| 404 | 389 | } |
|---|
| 405 | | -EXPORT_SYMBOL(bio_integrity_advance); |
|---|
| 406 | 390 | |
|---|
| 407 | 391 | /** |
|---|
| 408 | 392 | * bio_integrity_trim - Trim integrity vector |
|---|
| .. | .. |
|---|
| 444 | 428 | |
|---|
| 445 | 429 | bip->bip_vcnt = bip_src->bip_vcnt; |
|---|
| 446 | 430 | bip->bip_iter = bip_src->bip_iter; |
|---|
| 431 | + bip->bip_flags = bip_src->bip_flags & ~BIP_BLOCK_INTEGRITY; |
|---|
| 447 | 432 | |
|---|
| 448 | 433 | return 0; |
|---|
| 449 | 434 | } |
|---|
| .. | .. |
|---|
| 472 | 457 | mempool_exit(&bs->bio_integrity_pool); |
|---|
| 473 | 458 | mempool_exit(&bs->bvec_integrity_pool); |
|---|
| 474 | 459 | } |
|---|
| 475 | | -EXPORT_SYMBOL(bioset_integrity_free); |
|---|
| 476 | 460 | |
|---|
| 477 | 461 | void __init bio_integrity_init(void) |
|---|
| 478 | 462 | { |
|---|