Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-6.0/dm-changes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Pull more device mapper updates from Mike Snitzer:

- Add flags argument to dm_bufio_client_create and introduce
DM_BUFIO_CLIENT_NO_SLEEP flag to have dm-bufio use spinlock rather
than mutex for its locking.

- Add optional "try_verify_in_tasklet" feature to DM verity target.
This feature gives users the option to improve IO latency by using a
tasklet to verify, using hashes in bufio's cache, rather than wait to
schedule a work item via workqueue. But if there is a bufio cache
miss, or an error, then the tasklet will fallback to using workqueue.

- Incremental changes to both dm-bufio and the DM verity target to use
jump_label to minimize cost of branching associated with the niche
"try_verify_in_tasklet" feature. DM-bufio in particular is used by
quite a few other DM targets so it doesn't make sense to incur
additional bufio cost in those targets purely for the benefit of this
niche verity feature if the feature isn't ever used.

- Optimize verity_verify_io, which is used by both workqueue and
tasklet based verification, if FEC is not configured or tasklet based
verification isn't used.

- Remove DM verity target's verify_wq's use of the WQ_CPU_INTENSIVE
flag since it uses WQ_UNBOUND. Also, use the WQ_HIGHPRI flag if
"try_verify_in_tasklet" is specified.

* tag 'for-6.0/dm-changes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
dm verity: have verify_wq use WQ_HIGHPRI if "try_verify_in_tasklet"
dm verity: remove WQ_CPU_INTENSIVE flag since using WQ_UNBOUND
dm verity: only copy bvec_iter in verity_verify_io if in_tasklet
dm verity: optimize verity_verify_io if FEC not configured
dm verity: conditionally enable branching for "try_verify_in_tasklet"
dm bufio: conditionally enable branching for DM_BUFIO_CLIENT_NO_SLEEP
dm verity: allow optional args to alter primary args handling
dm verity: Add optional "try_verify_in_tasklet" feature
dm bufio: Add DM_BUFIO_CLIENT_NO_SLEEP flag
dm bufio: Add flags argument to dm_bufio_client_create

+187 -33
+28 -4
drivers/md/dm-bufio.c
··· 18 18 #include <linux/module.h> 19 19 #include <linux/rbtree.h> 20 20 #include <linux/stacktrace.h> 21 + #include <linux/jump_label.h> 21 22 22 23 #define DM_MSG_PREFIX "bufio" 23 24 ··· 82 81 */ 83 82 struct dm_bufio_client { 84 83 struct mutex lock; 84 + spinlock_t spinlock; 85 + unsigned long spinlock_flags; 85 86 86 87 struct list_head lru[LIST_SIZE]; 87 88 unsigned long n_buffers[LIST_SIZE]; ··· 93 90 s8 sectors_per_block_bits; 94 91 void (*alloc_callback)(struct dm_buffer *); 95 92 void (*write_callback)(struct dm_buffer *); 93 + bool no_sleep; 96 94 97 95 struct kmem_cache *slab_buffer; 98 96 struct kmem_cache *slab_cache; ··· 165 161 #endif 166 162 }; 167 163 164 + static DEFINE_STATIC_KEY_FALSE(no_sleep_enabled); 165 + 168 166 /*----------------------------------------------------------------*/ 169 167 170 168 #define dm_bufio_in_request() (!!current->bio_list) 171 169 172 170 static void dm_bufio_lock(struct dm_bufio_client *c) 173 171 { 174 - mutex_lock_nested(&c->lock, dm_bufio_in_request()); 172 + if (static_branch_unlikely(&no_sleep_enabled) && c->no_sleep) 173 + spin_lock_irqsave_nested(&c->spinlock, c->spinlock_flags, dm_bufio_in_request()); 174 + else 175 + mutex_lock_nested(&c->lock, dm_bufio_in_request()); 175 176 } 176 177 177 178 static int dm_bufio_trylock(struct dm_bufio_client *c) 178 179 { 179 - return mutex_trylock(&c->lock); 180 + if (static_branch_unlikely(&no_sleep_enabled) && c->no_sleep) 181 + return spin_trylock_irqsave(&c->spinlock, c->spinlock_flags); 182 + else 183 + return mutex_trylock(&c->lock); 180 184 } 181 185 182 186 static void dm_bufio_unlock(struct dm_bufio_client *c) 183 187 { 184 - mutex_unlock(&c->lock); 188 + if (static_branch_unlikely(&no_sleep_enabled) && c->no_sleep) 189 + spin_unlock_irqrestore(&c->spinlock, c->spinlock_flags); 190 + else 191 + mutex_unlock(&c->lock); 185 192 } 186 193 187 194 /*----------------------------------------------------------------*/ ··· 1730 1715 struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsigned block_size, 1731 1716 unsigned reserved_buffers, unsigned aux_size, 1732 1717 void (*alloc_callback)(struct dm_buffer *), 1733 - void (*write_callback)(struct dm_buffer *)) 1718 + void (*write_callback)(struct dm_buffer *), 1719 + unsigned int flags) 1734 1720 { 1735 1721 int r; 1736 1722 struct dm_bufio_client *c; ··· 1761 1745 c->alloc_callback = alloc_callback; 1762 1746 c->write_callback = write_callback; 1763 1747 1748 + if (flags & DM_BUFIO_CLIENT_NO_SLEEP) { 1749 + c->no_sleep = true; 1750 + static_branch_inc(&no_sleep_enabled); 1751 + } 1752 + 1764 1753 for (i = 0; i < LIST_SIZE; i++) { 1765 1754 INIT_LIST_HEAD(&c->lru[i]); 1766 1755 c->n_buffers[i] = 0; 1767 1756 } 1768 1757 1769 1758 mutex_init(&c->lock); 1759 + spin_lock_init(&c->spinlock); 1770 1760 INIT_LIST_HEAD(&c->reserved_buffers); 1771 1761 c->need_reserved_buffers = reserved_buffers; 1772 1762 ··· 1899 1877 kmem_cache_destroy(c->slab_buffer); 1900 1878 dm_io_client_destroy(c->dm_io); 1901 1879 mutex_destroy(&c->lock); 1880 + if (c->no_sleep) 1881 + static_branch_dec(&no_sleep_enabled); 1902 1882 kfree(c); 1903 1883 } 1904 1884 EXPORT_SYMBOL_GPL(dm_bufio_client_destroy);
+2 -1
drivers/md/dm-ebs-target.c
··· 313 313 goto bad; 314 314 } 315 315 316 - ec->bufio = dm_bufio_client_create(ec->dev->bdev, to_bytes(ec->u_bs), 1, 0, NULL, NULL); 316 + ec->bufio = dm_bufio_client_create(ec->dev->bdev, to_bytes(ec->u_bs), 1, 317 + 0, NULL, NULL, 0); 317 318 if (IS_ERR(ec->bufio)) { 318 319 ti->error = "Cannot create dm bufio client"; 319 320 r = PTR_ERR(ec->bufio);
+1 -1
drivers/md/dm-integrity.c
··· 4439 4439 } 4440 4440 4441 4441 ic->bufio = dm_bufio_client_create(ic->meta_dev ? ic->meta_dev->bdev : ic->dev->bdev, 4442 - 1U << (SECTOR_SHIFT + ic->log2_buffer_sectors), 1, 0, NULL, NULL); 4442 + 1U << (SECTOR_SHIFT + ic->log2_buffer_sectors), 1, 0, NULL, NULL, 0); 4443 4443 if (IS_ERR(ic->bufio)) { 4444 4444 r = PTR_ERR(ic->bufio); 4445 4445 ti->error = "Cannot initialize dm-bufio";
+1 -1
drivers/md/dm-snap-persistent.c
··· 493 493 494 494 client = dm_bufio_client_create(dm_snap_cow(ps->store->snap)->bdev, 495 495 ps->store->chunk_size << SECTOR_SHIFT, 496 - 1, 0, NULL, NULL); 496 + 1, 0, NULL, NULL, 0); 497 497 498 498 if (IS_ERR(client)) 499 499 return PTR_ERR(client);
+2 -2
drivers/md/dm-verity-fec.c
··· 749 749 750 750 f->bufio = dm_bufio_client_create(f->dev->bdev, 751 751 f->io_size, 752 - 1, 0, NULL, NULL); 752 + 1, 0, NULL, NULL, 0); 753 753 if (IS_ERR(f->bufio)) { 754 754 ti->error = "Cannot initialize FEC bufio client"; 755 755 return PTR_ERR(f->bufio); ··· 765 765 766 766 f->data_bufio = dm_bufio_client_create(v->data_dev->bdev, 767 767 1 << v->data_dev_block_bits, 768 - 1, 0, NULL, NULL); 768 + 1, 0, NULL, NULL, 0); 769 769 if (IS_ERR(f->data_bufio)) { 770 770 ti->error = "Cannot initialize FEC data bufio client"; 771 771 return PTR_ERR(f->data_bufio);
+139 -21
drivers/md/dm-verity-target.c
··· 20 20 #include <linux/reboot.h> 21 21 #include <linux/scatterlist.h> 22 22 #include <linux/string.h> 23 + #include <linux/jump_label.h> 23 24 24 25 #define DM_MSG_PREFIX "verity" 25 26 ··· 36 35 #define DM_VERITY_OPT_PANIC "panic_on_corruption" 37 36 #define DM_VERITY_OPT_IGN_ZEROES "ignore_zero_blocks" 38 37 #define DM_VERITY_OPT_AT_MOST_ONCE "check_at_most_once" 38 + #define DM_VERITY_OPT_TASKLET_VERIFY "try_verify_in_tasklet" 39 39 40 40 #define DM_VERITY_OPTS_MAX (3 + DM_VERITY_OPTS_FEC + \ 41 41 DM_VERITY_ROOT_HASH_VERIFICATION_OPTS) ··· 44 42 static unsigned dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE; 45 43 46 44 module_param_named(prefetch_cluster, dm_verity_prefetch_cluster, uint, S_IRUGO | S_IWUSR); 45 + 46 + static DEFINE_STATIC_KEY_FALSE(use_tasklet_enabled); 47 47 48 48 struct dm_verity_prefetch_work { 49 49 struct work_struct work; ··· 225 221 struct mapped_device *md = dm_table_get_md(v->ti->table); 226 222 227 223 /* Corruption should be visible in device status in all modes */ 228 - v->hash_failed = 1; 224 + v->hash_failed = true; 229 225 230 226 if (v->corrupted_errs >= DM_VERITY_MAX_CORRUPTED_ERRS) 231 227 goto out; ··· 291 287 292 288 verity_hash_at_level(v, block, level, &hash_block, &offset); 293 289 294 - data = dm_bufio_read(v->bufio, hash_block, &buf); 290 + if (static_branch_unlikely(&use_tasklet_enabled) && io->in_tasklet) { 291 + data = dm_bufio_get(v->bufio, hash_block, &buf); 292 + if (data == NULL) { 293 + /* 294 + * In tasklet and the hash was not in the bufio cache. 295 + * Return early and resume execution from a work-queue 296 + * to read the hash from disk. 297 + */ 298 + return -EAGAIN; 299 + } 300 + } else 301 + data = dm_bufio_read(v->bufio, hash_block, &buf); 302 + 295 303 if (IS_ERR(data)) 296 304 return PTR_ERR(data); 297 305 ··· 324 308 if (likely(memcmp(verity_io_real_digest(v, io), want_digest, 325 309 v->digest_size) == 0)) 326 310 aux->hash_verified = 1; 311 + else if (static_branch_unlikely(&use_tasklet_enabled) && 312 + io->in_tasklet) { 313 + /* 314 + * Error handling code (FEC included) cannot be run in a 315 + * tasklet since it may sleep, so fallback to work-queue. 316 + */ 317 + r = -EAGAIN; 318 + goto release_ret_r; 319 + } 327 320 else if (verity_fec_decode(v, io, 328 321 DM_VERITY_BLOCK_TYPE_METADATA, 329 322 hash_block, data, NULL) == 0) ··· 499 474 { 500 475 bool is_zero; 501 476 struct dm_verity *v = io->v; 477 + #if defined(CONFIG_DM_VERITY_FEC) 502 478 struct bvec_iter start; 503 - unsigned b; 479 + #endif 480 + struct bvec_iter iter_copy; 481 + struct bvec_iter *iter; 504 482 struct crypto_wait wait; 505 483 struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size); 484 + unsigned int b; 485 + 486 + if (static_branch_unlikely(&use_tasklet_enabled) && io->in_tasklet) { 487 + /* 488 + * Copy the iterator in case we need to restart 489 + * verification in a work-queue. 490 + */ 491 + iter_copy = io->iter; 492 + iter = &iter_copy; 493 + } else 494 + iter = &io->iter; 506 495 507 496 for (b = 0; b < io->n_blocks; b++) { 508 497 int r; ··· 525 486 526 487 if (v->validated_blocks && 527 488 likely(test_bit(cur_block, v->validated_blocks))) { 528 - verity_bv_skip_block(v, io, &io->iter); 489 + verity_bv_skip_block(v, io, iter); 529 490 continue; 530 491 } 531 492 ··· 540 501 * If we expect a zero block, don't validate, just 541 502 * return zeros. 542 503 */ 543 - r = verity_for_bv_block(v, io, &io->iter, 504 + r = verity_for_bv_block(v, io, iter, 544 505 verity_bv_zero); 545 506 if (unlikely(r < 0)) 546 507 return r; ··· 552 513 if (unlikely(r < 0)) 553 514 return r; 554 515 555 - start = io->iter; 556 - r = verity_for_io_block(v, io, &io->iter, &wait); 516 + #if defined(CONFIG_DM_VERITY_FEC) 517 + if (verity_fec_is_enabled(v)) 518 + start = *iter; 519 + #endif 520 + r = verity_for_io_block(v, io, iter, &wait); 557 521 if (unlikely(r < 0)) 558 522 return r; 559 523 ··· 570 528 if (v->validated_blocks) 571 529 set_bit(cur_block, v->validated_blocks); 572 530 continue; 531 + } else if (static_branch_unlikely(&use_tasklet_enabled) && 532 + io->in_tasklet) { 533 + /* 534 + * Error handling code (FEC included) cannot be run in a 535 + * tasklet since it may sleep, so fallback to work-queue. 536 + */ 537 + return -EAGAIN; 538 + #if defined(CONFIG_DM_VERITY_FEC) 573 539 } else if (verity_fec_decode(v, io, DM_VERITY_BLOCK_TYPE_DATA, 574 - cur_block, NULL, &start) == 0) { 540 + cur_block, NULL, &start) == 0) { 575 541 continue; 542 + #endif 576 543 } else { 577 544 if (bio->bi_status) { 578 545 /* ··· 618 567 bio->bi_end_io = io->orig_bi_end_io; 619 568 bio->bi_status = status; 620 569 621 - verity_fec_finish_io(io); 570 + if (!static_branch_unlikely(&use_tasklet_enabled) || !io->in_tasklet) 571 + verity_fec_finish_io(io); 622 572 623 573 bio_endio(bio); 624 574 } ··· 628 576 { 629 577 struct dm_verity_io *io = container_of(w, struct dm_verity_io, work); 630 578 579 + io->in_tasklet = false; 580 + 581 + verity_fec_init_io(io); 631 582 verity_finish_io(io, errno_to_blk_status(verity_verify_io(io))); 583 + } 584 + 585 + static void verity_tasklet(unsigned long data) 586 + { 587 + struct dm_verity_io *io = (struct dm_verity_io *)data; 588 + int err; 589 + 590 + io->in_tasklet = true; 591 + err = verity_verify_io(io); 592 + if (err == -EAGAIN) { 593 + /* fallback to retrying with work-queue */ 594 + INIT_WORK(&io->work, verity_work); 595 + queue_work(io->v->verify_wq, &io->work); 596 + return; 597 + } 598 + 599 + verity_finish_io(io, errno_to_blk_status(err)); 632 600 } 633 601 634 602 static void verity_end_io(struct bio *bio) ··· 661 589 return; 662 590 } 663 591 664 - INIT_WORK(&io->work, verity_work); 665 - queue_work(io->v->verify_wq, &io->work); 592 + if (static_branch_unlikely(&use_tasklet_enabled) && io->v->use_tasklet) { 593 + tasklet_init(&io->tasklet, verity_tasklet, (unsigned long)io); 594 + tasklet_schedule(&io->tasklet); 595 + } else { 596 + INIT_WORK(&io->work, verity_work); 597 + queue_work(io->v->verify_wq, &io->work); 598 + } 666 599 } 667 600 668 601 /* ··· 778 701 bio->bi_private = io; 779 702 io->iter = bio->bi_iter; 780 703 781 - verity_fec_init_io(io); 782 - 783 704 verity_submit_prefetch(v, io); 784 705 785 706 submit_bio_noacct(bio); ··· 827 752 args++; 828 753 if (v->validated_blocks) 829 754 args++; 755 + if (v->use_tasklet) 756 + args++; 830 757 if (v->signature_key_desc) 831 758 args += DM_VERITY_ROOT_HASH_VERIFICATION_OPTS; 832 759 if (!args) ··· 854 777 DMEMIT(" " DM_VERITY_OPT_IGN_ZEROES); 855 778 if (v->validated_blocks) 856 779 DMEMIT(" " DM_VERITY_OPT_AT_MOST_ONCE); 780 + if (v->use_tasklet) 781 + DMEMIT(" " DM_VERITY_OPT_TASKLET_VERIFY); 857 782 sz = verity_fec_status_table(v, sz, result, maxlen); 858 783 if (v->signature_key_desc) 859 784 DMEMIT(" " DM_VERITY_ROOT_HASH_VERIFICATION_OPT_SIG_KEY ··· 969 890 970 891 kfree(v->signature_key_desc); 971 892 893 + if (v->use_tasklet) 894 + static_branch_dec(&use_tasklet_enabled); 895 + 972 896 kfree(v); 973 897 } 974 898 ··· 1050 968 } 1051 969 1052 970 static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v, 1053 - struct dm_verity_sig_opts *verify_args) 971 + struct dm_verity_sig_opts *verify_args, 972 + bool only_modifier_opts) 1054 973 { 1055 974 int r; 1056 975 unsigned argc; ··· 1074 991 argc--; 1075 992 1076 993 if (verity_is_verity_mode(arg_name)) { 994 + if (only_modifier_opts) 995 + continue; 1077 996 r = verity_parse_verity_mode(v, arg_name); 1078 997 if (r) { 1079 998 ti->error = "Conflicting error handling parameters"; ··· 1084 999 continue; 1085 1000 1086 1001 } else if (!strcasecmp(arg_name, DM_VERITY_OPT_IGN_ZEROES)) { 1002 + if (only_modifier_opts) 1003 + continue; 1087 1004 r = verity_alloc_zero_digest(v); 1088 1005 if (r) { 1089 1006 ti->error = "Cannot allocate zero digest"; ··· 1094 1007 continue; 1095 1008 1096 1009 } else if (!strcasecmp(arg_name, DM_VERITY_OPT_AT_MOST_ONCE)) { 1010 + if (only_modifier_opts) 1011 + continue; 1097 1012 r = verity_alloc_most_once(v); 1098 1013 if (r) 1099 1014 return r; 1100 1015 continue; 1101 1016 1017 + } else if (!strcasecmp(arg_name, DM_VERITY_OPT_TASKLET_VERIFY)) { 1018 + v->use_tasklet = true; 1019 + static_branch_inc(&use_tasklet_enabled); 1020 + continue; 1021 + 1102 1022 } else if (verity_is_fec_opt_arg(arg_name)) { 1023 + if (only_modifier_opts) 1024 + continue; 1103 1025 r = verity_fec_parse_opt_args(as, v, &argc, arg_name); 1104 1026 if (r) 1105 1027 return r; 1106 1028 continue; 1029 + 1107 1030 } else if (verity_verify_is_sig_opt_arg(arg_name)) { 1031 + if (only_modifier_opts) 1032 + continue; 1108 1033 r = verity_verify_sig_parse_opt_args(as, v, 1109 1034 verify_args, 1110 1035 &argc, arg_name); 1111 1036 if (r) 1112 1037 return r; 1113 1038 continue; 1114 - 1115 1039 } 1116 1040 1117 1041 ti->error = "Unrecognized verity feature request"; ··· 1152 1054 struct dm_verity_sig_opts verify_args = {0}; 1153 1055 struct dm_arg_set as; 1154 1056 unsigned int num; 1057 + unsigned int wq_flags; 1155 1058 unsigned long long num_ll; 1156 1059 int r; 1157 1060 int i; ··· 1182 1083 ti->error = "Not enough arguments"; 1183 1084 r = -EINVAL; 1184 1085 goto bad; 1086 + } 1087 + 1088 + /* Parse optional parameters that modify primary args */ 1089 + if (argc > 10) { 1090 + as.argc = argc - 10; 1091 + as.argv = argv + 10; 1092 + r = verity_parse_opt_args(&as, v, &verify_args, true); 1093 + if (r < 0) 1094 + goto bad; 1185 1095 } 1186 1096 1187 1097 if (sscanf(argv[0], "%u%c", &num, &dummy) != 1 || ··· 1264 1156 goto bad; 1265 1157 } 1266 1158 1267 - v->tfm = crypto_alloc_ahash(v->alg_name, 0, 0); 1159 + v->tfm = crypto_alloc_ahash(v->alg_name, 0, 1160 + v->use_tasklet ? CRYPTO_ALG_ASYNC : 0); 1268 1161 if (IS_ERR(v->tfm)) { 1269 1162 ti->error = "Cannot initialize hash function"; 1270 1163 r = PTR_ERR(v->tfm); ··· 1327 1218 if (argc) { 1328 1219 as.argc = argc; 1329 1220 as.argv = argv; 1330 - 1331 - r = verity_parse_opt_args(&as, v, &verify_args); 1221 + r = verity_parse_opt_args(&as, v, &verify_args, false); 1332 1222 if (r < 0) 1333 1223 goto bad; 1334 1224 } ··· 1374 1266 1375 1267 v->bufio = dm_bufio_client_create(v->hash_dev->bdev, 1376 1268 1 << v->hash_dev_block_bits, 1, sizeof(struct buffer_aux), 1377 - dm_bufio_alloc_callback, NULL); 1269 + dm_bufio_alloc_callback, NULL, 1270 + v->use_tasklet ? DM_BUFIO_CLIENT_NO_SLEEP : 0); 1378 1271 if (IS_ERR(v->bufio)) { 1379 1272 ti->error = "Cannot initialize dm-bufio"; 1380 1273 r = PTR_ERR(v->bufio); ··· 1390 1281 } 1391 1282 1392 1283 /* WQ_UNBOUND greatly improves performance when running on ramdisk */ 1393 - v->verify_wq = alloc_workqueue("kverityd", WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM | WQ_UNBOUND, num_online_cpus()); 1284 + wq_flags = WQ_MEM_RECLAIM | WQ_UNBOUND; 1285 + if (v->use_tasklet) { 1286 + /* 1287 + * Allow verify_wq to preempt softirq since verification in 1288 + * tasklet will fall-back to using it for error handling 1289 + * (or if the bufio cache doesn't have required hashes). 1290 + */ 1291 + wq_flags |= WQ_HIGHPRI; 1292 + } 1293 + v->verify_wq = alloc_workqueue("kverityd", wq_flags, num_online_cpus()); 1394 1294 if (!v->verify_wq) { 1395 1295 ti->error = "Cannot allocate workqueue"; 1396 1296 r = -ENOMEM; ··· 1461 1343 static struct target_type verity_target = { 1462 1344 .name = "verity", 1463 1345 .features = DM_TARGET_IMMUTABLE, 1464 - .version = {1, 8, 1}, 1346 + .version = {1, 9, 0}, 1465 1347 .module = THIS_MODULE, 1466 1348 .ctr = verity_ctr, 1467 1349 .dtr = verity_dtr,
+5 -1
drivers/md/dm-verity.h
··· 13 13 14 14 #include <linux/dm-bufio.h> 15 15 #include <linux/device-mapper.h> 16 + #include <linux/interrupt.h> 16 17 #include <crypto/hash.h> 17 18 18 19 #define DM_VERITY_MAX_LEVELS 63 ··· 52 51 unsigned char hash_per_block_bits; /* log2(hashes in hash block) */ 53 52 unsigned char levels; /* the number of tree levels */ 54 53 unsigned char version; 54 + bool hash_failed:1; /* set if hash of any block failed */ 55 + bool use_tasklet:1; /* try to verify in tasklet before work-queue */ 55 56 unsigned digest_size; /* digest size for the current hash algorithm */ 56 57 unsigned int ahash_reqsize;/* the size of temporary space for crypto */ 57 - int hash_failed; /* set to 1 if hash of any block failed */ 58 58 enum verity_mode mode; /* mode for handling verification errors */ 59 59 unsigned corrupted_errs;/* Number of errors for corrupted blocks */ 60 60 ··· 78 76 79 77 sector_t block; 80 78 unsigned n_blocks; 79 + bool in_tasklet; 81 80 82 81 struct bvec_iter iter; 83 82 84 83 struct work_struct work; 84 + struct tasklet_struct tasklet; 85 85 86 86 /* 87 87 * Three variably-size fields follow this struct:
+2 -1
drivers/md/persistent-data/dm-block-manager.c
··· 391 391 bm->bufio = dm_bufio_client_create(bdev, block_size, max_held_per_thread, 392 392 sizeof(struct buffer_aux), 393 393 dm_block_manager_alloc_callback, 394 - dm_block_manager_write_callback); 394 + dm_block_manager_write_callback, 395 + 0); 395 396 if (IS_ERR(bm->bufio)) { 396 397 r = PTR_ERR(bm->bufio); 397 398 kfree(bm);
+7 -1
include/linux/dm-bufio.h
··· 18 18 struct dm_buffer; 19 19 20 20 /* 21 + * Flags for dm_bufio_client_create 22 + */ 23 + #define DM_BUFIO_CLIENT_NO_SLEEP 0x1 24 + 25 + /* 21 26 * Create a buffered IO cache on a given device 22 27 */ 23 28 struct dm_bufio_client * 24 29 dm_bufio_client_create(struct block_device *bdev, unsigned block_size, 25 30 unsigned reserved_buffers, unsigned aux_size, 26 31 void (*alloc_callback)(struct dm_buffer *), 27 - void (*write_callback)(struct dm_buffer *)); 32 + void (*write_callback)(struct dm_buffer *), 33 + unsigned int flags); 28 34 29 35 /* 30 36 * Release a buffered IO cache.