| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * blk-integrity.c - Block layer data integrity extensions |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2007, 2008 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> |
|---|
| .. | .. |
|---|
| 49 | 35 | bio_for_each_integrity_vec(iv, bio, iter) { |
|---|
| 50 | 36 | |
|---|
| 51 | 37 | if (prev) { |
|---|
| 52 | | - if (!BIOVEC_PHYS_MERGEABLE(&ivprv, &iv)) |
|---|
| 38 | + if (!biovec_phys_mergeable(q, &ivprv, &iv)) |
|---|
| 53 | 39 | goto new_segment; |
|---|
| 54 | | - |
|---|
| 55 | | - if (!BIOVEC_SEG_BOUNDARY(q, &ivprv, &iv)) |
|---|
| 56 | | - goto new_segment; |
|---|
| 57 | | - |
|---|
| 58 | 40 | if (seg_size + iv.bv_len > queue_max_segment_size(q)) |
|---|
| 59 | 41 | goto new_segment; |
|---|
| 60 | 42 | |
|---|
| .. | .. |
|---|
| 95 | 77 | bio_for_each_integrity_vec(iv, bio, iter) { |
|---|
| 96 | 78 | |
|---|
| 97 | 79 | if (prev) { |
|---|
| 98 | | - if (!BIOVEC_PHYS_MERGEABLE(&ivprv, &iv)) |
|---|
| 80 | + if (!biovec_phys_mergeable(q, &ivprv, &iv)) |
|---|
| 99 | 81 | goto new_segment; |
|---|
| 100 | | - |
|---|
| 101 | | - if (!BIOVEC_SEG_BOUNDARY(q, &ivprv, &iv)) |
|---|
| 102 | | - goto new_segment; |
|---|
| 103 | | - |
|---|
| 104 | 82 | if (sg->length + iv.bv_len > queue_max_segment_size(q)) |
|---|
| 105 | 83 | goto new_segment; |
|---|
| 106 | 84 | |
|---|
| .. | .. |
|---|
| 205 | 183 | |
|---|
| 206 | 184 | return true; |
|---|
| 207 | 185 | } |
|---|
| 208 | | -EXPORT_SYMBOL(blk_integrity_merge_rq); |
|---|
| 209 | 186 | |
|---|
| 210 | 187 | bool blk_integrity_merge_bio(struct request_queue *q, struct request *req, |
|---|
| 211 | 188 | struct bio *bio) |
|---|
| .. | .. |
|---|
| 234 | 211 | |
|---|
| 235 | 212 | return true; |
|---|
| 236 | 213 | } |
|---|
| 237 | | -EXPORT_SYMBOL(blk_integrity_merge_bio); |
|---|
| 238 | 214 | |
|---|
| 239 | 215 | struct integrity_sysfs_entry { |
|---|
| 240 | 216 | struct attribute attr; |
|---|
| .. | .. |
|---|
| 373 | 349 | &integrity_device_entry.attr, |
|---|
| 374 | 350 | NULL, |
|---|
| 375 | 351 | }; |
|---|
| 352 | +ATTRIBUTE_GROUPS(integrity); |
|---|
| 376 | 353 | |
|---|
| 377 | 354 | static const struct sysfs_ops integrity_ops = { |
|---|
| 378 | 355 | .show = &integrity_attr_show, |
|---|
| .. | .. |
|---|
| 380 | 357 | }; |
|---|
| 381 | 358 | |
|---|
| 382 | 359 | static struct kobj_type integrity_ktype = { |
|---|
| 383 | | - .default_attrs = integrity_attrs, |
|---|
| 360 | + .default_groups = integrity_groups, |
|---|
| 384 | 361 | .sysfs_ops = &integrity_ops, |
|---|
| 385 | 362 | }; |
|---|
| 386 | 363 | |
|---|
| .. | .. |
|---|
| 389 | 366 | return BLK_STS_OK; |
|---|
| 390 | 367 | } |
|---|
| 391 | 368 | |
|---|
| 369 | +static void blk_integrity_nop_prepare(struct request *rq) |
|---|
| 370 | +{ |
|---|
| 371 | +} |
|---|
| 372 | + |
|---|
| 373 | +static void blk_integrity_nop_complete(struct request *rq, |
|---|
| 374 | + unsigned int nr_bytes) |
|---|
| 375 | +{ |
|---|
| 376 | +} |
|---|
| 377 | + |
|---|
| 392 | 378 | static const struct blk_integrity_profile nop_profile = { |
|---|
| 393 | 379 | .name = "nop", |
|---|
| 394 | 380 | .generate_fn = blk_integrity_nop_fn, |
|---|
| 395 | 381 | .verify_fn = blk_integrity_nop_fn, |
|---|
| 382 | + .prepare_fn = blk_integrity_nop_prepare, |
|---|
| 383 | + .complete_fn = blk_integrity_nop_complete, |
|---|
| 396 | 384 | }; |
|---|
| 397 | 385 | |
|---|
| 398 | 386 | /** |
|---|
| .. | .. |
|---|
| 404 | 392 | * send/receive integrity metadata it must use this function to register |
|---|
| 405 | 393 | * the capability with the block layer. The template is a blk_integrity |
|---|
| 406 | 394 | * struct with values appropriate for the underlying hardware. See |
|---|
| 407 | | - * Documentation/block/data-integrity.txt. |
|---|
| 395 | + * Documentation/block/data-integrity.rst. |
|---|
| 408 | 396 | */ |
|---|
| 409 | 397 | void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template) |
|---|
| 410 | 398 | { |
|---|
| .. | .. |
|---|
| 418 | 406 | bi->tuple_size = template->tuple_size; |
|---|
| 419 | 407 | bi->tag_size = template->tag_size; |
|---|
| 420 | 408 | |
|---|
| 421 | | - disk->queue->backing_dev_info->capabilities |= BDI_CAP_STABLE_WRITES; |
|---|
| 409 | + blk_queue_flag_set(QUEUE_FLAG_STABLE_WRITES, disk->queue); |
|---|
| 410 | + |
|---|
| 411 | +#ifdef CONFIG_BLK_INLINE_ENCRYPTION |
|---|
| 412 | + if (disk->queue->ksm) { |
|---|
| 413 | + pr_warn("blk-integrity: Integrity and hardware inline encryption are not supported together. Disabling hardware inline encryption.\n"); |
|---|
| 414 | + blk_ksm_unregister(disk->queue); |
|---|
| 415 | + } |
|---|
| 416 | +#endif |
|---|
| 422 | 417 | } |
|---|
| 423 | 418 | EXPORT_SYMBOL(blk_integrity_register); |
|---|
| 424 | 419 | |
|---|
| .. | .. |
|---|
| 431 | 426 | */ |
|---|
| 432 | 427 | void blk_integrity_unregister(struct gendisk *disk) |
|---|
| 433 | 428 | { |
|---|
| 434 | | - disk->queue->backing_dev_info->capabilities &= ~BDI_CAP_STABLE_WRITES; |
|---|
| 435 | | - memset(&disk->queue->integrity, 0, sizeof(struct blk_integrity)); |
|---|
| 429 | + struct blk_integrity *bi = &disk->queue->integrity; |
|---|
| 430 | + |
|---|
| 431 | + if (!bi->profile) |
|---|
| 432 | + return; |
|---|
| 433 | + |
|---|
| 434 | + /* ensure all bios are off the integrity workqueue */ |
|---|
| 435 | + blk_flush_integrity(); |
|---|
| 436 | + blk_queue_flag_clear(QUEUE_FLAG_STABLE_WRITES, disk->queue); |
|---|
| 437 | + memset(bi, 0, sizeof(*bi)); |
|---|
| 436 | 438 | } |
|---|
| 437 | 439 | EXPORT_SYMBOL(blk_integrity_unregister); |
|---|
| 438 | 440 | |
|---|