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

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

Pull device mapper updates from Mikulas Patocka:

- Misc VDO fixes

- Remove unused declarations dm_get_rq_mapinfo() and dm_zone_map_bio()

- Dm-delay: Improve kernel documentation

- Dm-crypt: Allow to specify the integrity key size as an option

- Dm-bufio: Remove pointless NULL check

- Small code cleanups: Use ERR_CAST; remove unlikely() around IS_ERR;
use __assign_bit

- Dm-integrity: Fix gcc 5 warning; convert comma to semicolon; fix
smatch warning

- Dm-integrity: Support recalculation in the 'I' mode

- Revert "dm: requeue IO if mapping table not yet available"

- Dm-crypt: Small refactoring to make the code more readable

- Dm-cache: Remove pointless error check

- Dm: Fix spelling errors

- Dm-verity: Restart or panic on an I/O error if restart or panic was
requested

- Dm-verity: Fallback to platform keyring also if key in trusted
keyring is rejected

* tag 'for-6.12/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: (26 commits)
dm verity: fallback to platform keyring also if key in trusted keyring is rejected
dm-verity: restart or panic on an I/O error
dm: fix spelling errors
dm-cache: remove pointless error check
dm vdo: handle unaligned discards correctly
dm vdo indexer: Convert comma to semicolon
dm-crypt: Use common error handling code in crypt_set_keyring_key()
dm-crypt: Use up_read() together with key_put() only once in crypt_set_keyring_key()
Revert "dm: requeue IO if mapping table not yet available"
dm-integrity: check mac_size against HASH_MAX_DIGESTSIZE in sb_mac()
dm-integrity: support recalculation in the 'I' mode
dm integrity: Convert comma to semicolon
dm integrity: fix gcc 5 warning
dm: Make use of __assign_bit() API
dm integrity: Remove extra unlikely helper
dm: Convert to use ERR_CAST()
dm bufio: Remove NULL check of list_entry()
dm-crypt: Allow to specify the integrity key size as option
dm: Remove unused declaration and empty definition "dm_zone_map_bio"
dm delay: enhance kernel documentation
...

+488 -147
+33 -10
Documentation/admin-guide/device-mapper/delay.rst
··· 3 3 ======== 4 4 5 5 Device-Mapper's "delay" target delays reads and/or writes 6 - and maps them to different devices. 6 + and/or flushs and optionally maps them to different devices. 7 7 8 - Parameters:: 8 + Arguments:: 9 9 10 10 <device> <offset> <delay> [<write_device> <write_offset> <write_delay> 11 11 [<flush_device> <flush_offset> <flush_delay>]] 12 12 13 - With separate write parameters, the first set is only used for reads. 13 + Table line has to either have 3, 6 or 9 arguments: 14 + 15 + 3: apply offset and delay to read, write and flush operations on device 16 + 17 + 6: apply offset and delay to device, also apply write_offset and write_delay 18 + to write and flush operations on optionally different write_device with 19 + optionally different sector offset 20 + 21 + 9: same as 6 arguments plus define flush_offset and flush_delay explicitely 22 + on/with optionally different flush_device/flush_offset. 23 + 14 24 Offsets are specified in sectors. 25 + 15 26 Delays are specified in milliseconds. 27 + 16 28 17 29 Example scripts 18 30 =============== 19 31 20 32 :: 21 - 22 33 #!/bin/sh 23 - # Create device delaying rw operation for 500ms 24 - echo "0 `blockdev --getsz $1` delay $1 0 500" | dmsetup create delayed 34 + # 35 + # Create mapped device named "delayed" delaying read, write and flush operations for 500ms. 36 + # 37 + dmsetup create delayed --table "0 `blockdev --getsz $1` delay $1 0 500" 25 38 26 39 :: 27 - 28 40 #!/bin/sh 29 - # Create device delaying only write operation for 500ms and 30 - # splitting reads and writes to different devices $1 $2 31 - echo "0 `blockdev --getsz $1` delay $1 0 0 $2 0 500" | dmsetup create delayed 41 + # 42 + # Create mapped device delaying write and flush operations for 400ms and 43 + # splitting reads to device $1 but writes and flushs to different device $2 44 + # to different offsets of 2048 and 4096 sectors respectively. 45 + # 46 + dmsetup create delayed --table "0 `blockdev --getsz $1` delay $1 2048 0 $2 4096 400" 47 + 48 + :: 49 + #!/bin/sh 50 + # 51 + # Create mapped device delaying reads for 50ms, writes for 100ms and flushs for 333ms 52 + # onto the same backing device at offset 0 sectors. 53 + # 54 + dmsetup create delayed --table "0 `blockdev --getsz $1` delay $1 0 50 $2 0 100 $1 0 333"
+4
Documentation/admin-guide/device-mapper/dm-crypt.rst
··· 160 160 The <iv_offset> must be multiple of <sector_size> (in 512 bytes units) 161 161 if this flag is specified. 162 162 163 + integrity_key_size:<bytes> 164 + Use an integrity key of <bytes> size instead of using an integrity key size 165 + of the digest size of the used HMAC algorithm. 166 + 163 167 164 168 Module parameters:: 165 169 max_read_size
+6 -1
Documentation/admin-guide/device-mapper/vdo.rst
··· 251 251 by the vdostats userspace program to interpret the output 252 252 buffer. 253 253 254 - dump: 254 + config: 255 + Outputs useful vdo configuration information. Mostly used 256 + by users who want to recreate a similar VDO volume and 257 + want to know the creation configuration used. 258 + 259 + dump: 255 260 Dumps many internal structures to the system log. This is 256 261 not always safe to run, so it should only be used to debug 257 262 a hung vdo. Optional parameters to specify structures to
-3
drivers/md/dm-bufio.c
··· 529 529 { 530 530 struct lru_entry *le = list_entry(l, struct lru_entry, list); 531 531 532 - if (!le) 533 - return NULL; 534 - 535 532 return le_to_buffer(le); 536 533 } 537 534
+1 -5
drivers/md/dm-cache-target.c
··· 1368 1368 */ 1369 1369 bool rb = bio_detain_shared(mg->cache, mg->op->oblock, mg->overwrite_bio); 1370 1370 1371 - BUG_ON(rb); /* An exclussive lock must _not_ be held for this block */ 1371 + BUG_ON(rb); /* An exclusive lock must _not_ be held for this block */ 1372 1372 mg->overwrite_bio = NULL; 1373 1373 inc_io_migrations(mg->cache); 1374 1374 mg_full_copy(ws); ··· 3200 3200 * Try and parse form (ii) first. 3201 3201 */ 3202 3202 r = sscanf(str, "%llu-%llu%c", &b, &e, &dummy); 3203 - if (r < 0) 3204 - return r; 3205 3203 3206 3204 if (r == 2) { 3207 3205 result->begin = to_cblock(b); ··· 3211 3213 * That didn't work, try form (i). 3212 3214 */ 3213 3215 r = sscanf(str, "%llu%c", &b, &dummy); 3214 - if (r < 0) 3215 - return r; 3216 3216 3217 3217 if (r == 1) { 3218 3218 result->begin = to_cblock(b);
+1 -4
drivers/md/dm-clone-metadata.c
··· 530 530 return r; 531 531 532 532 for (i = 0; ; i++) { 533 - if (dm_bitset_cursor_get_value(&c)) 534 - __set_bit(i, cmd->region_map); 535 - else 536 - __clear_bit(i, cmd->region_map); 533 + __assign_bit(i, cmd->region_map, dm_bitset_cursor_get_value(&c)); 537 534 538 535 if (i >= (cmd->nr_regions - 1)) 539 536 break;
+27 -20
drivers/md/dm-crypt.c
··· 147 147 CRYPT_MODE_INTEGRITY_AEAD, /* Use authenticated mode for cipher */ 148 148 CRYPT_IV_LARGE_SECTORS, /* Calculate IV from sector_size, not 512B sectors */ 149 149 CRYPT_ENCRYPT_PREPROCESS, /* Must preprocess data for encryption (elephant) */ 150 + CRYPT_KEY_MAC_SIZE_SET, /* The integrity_key_size option was used */ 150 151 }; 151 152 152 153 /* ··· 2614 2613 2615 2614 key = request_key(type, key_desc + 1, NULL); 2616 2615 if (IS_ERR(key)) { 2617 - kfree_sensitive(new_key_string); 2618 - return PTR_ERR(key); 2616 + ret = PTR_ERR(key); 2617 + goto free_new_key_string; 2619 2618 } 2620 2619 2621 2620 down_read(&key->sem); 2622 - 2623 2621 ret = set_key(cc, key); 2624 - if (ret < 0) { 2625 - up_read(&key->sem); 2626 - key_put(key); 2627 - kfree_sensitive(new_key_string); 2628 - return ret; 2629 - } 2630 - 2631 2622 up_read(&key->sem); 2632 2623 key_put(key); 2624 + if (ret < 0) 2625 + goto free_new_key_string; 2633 2626 2634 2627 /* clear the flag since following operations may invalidate previously valid key */ 2635 2628 clear_bit(DM_CRYPT_KEY_VALID, &cc->flags); 2636 2629 2637 2630 ret = crypt_setkey(cc); 2631 + if (ret) 2632 + goto free_new_key_string; 2638 2633 2639 - if (!ret) { 2640 - set_bit(DM_CRYPT_KEY_VALID, &cc->flags); 2641 - kfree_sensitive(cc->key_string); 2642 - cc->key_string = new_key_string; 2643 - } else 2644 - kfree_sensitive(new_key_string); 2634 + set_bit(DM_CRYPT_KEY_VALID, &cc->flags); 2635 + kfree_sensitive(cc->key_string); 2636 + cc->key_string = new_key_string; 2637 + return 0; 2645 2638 2639 + free_new_key_string: 2640 + kfree_sensitive(new_key_string); 2646 2641 return ret; 2647 2642 } 2648 2643 ··· 2934 2937 if (IS_ERR(mac)) 2935 2938 return PTR_ERR(mac); 2936 2939 2937 - cc->key_mac_size = crypto_ahash_digestsize(mac); 2940 + if (!test_bit(CRYPT_KEY_MAC_SIZE_SET, &cc->cipher_flags)) 2941 + cc->key_mac_size = crypto_ahash_digestsize(mac); 2938 2942 crypto_free_ahash(mac); 2939 2943 2940 2944 cc->authenc_key = kmalloc(crypt_authenckey_size(cc), GFP_KERNEL); ··· 3217 3219 cc->cipher_auth = kstrdup(sval, GFP_KERNEL); 3218 3220 if (!cc->cipher_auth) 3219 3221 return -ENOMEM; 3222 + } else if (sscanf(opt_string, "integrity_key_size:%u%c", &val, &dummy) == 1) { 3223 + if (!val) { 3224 + ti->error = "Invalid integrity_key_size argument"; 3225 + return -EINVAL; 3226 + } 3227 + cc->key_mac_size = val; 3228 + set_bit(CRYPT_KEY_MAC_SIZE_SET, &cc->cipher_flags); 3220 3229 } else if (sscanf(opt_string, "sector_size:%hu%c", &cc->sector_size, &dummy) == 1) { 3221 3230 if (cc->sector_size < (1 << SECTOR_SHIFT) || 3222 3231 cc->sector_size > 4096 || ··· 3612 3607 num_feature_args += test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags); 3613 3608 num_feature_args += test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags); 3614 3609 num_feature_args += test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags); 3610 + num_feature_args += !!cc->used_tag_size; 3615 3611 num_feature_args += cc->sector_size != (1 << SECTOR_SHIFT); 3616 3612 num_feature_args += test_bit(CRYPT_IV_LARGE_SECTORS, &cc->cipher_flags); 3617 - if (cc->used_tag_size) 3618 - num_feature_args++; 3613 + num_feature_args += test_bit(CRYPT_KEY_MAC_SIZE_SET, &cc->cipher_flags); 3619 3614 if (num_feature_args) { 3620 3615 DMEMIT(" %d", num_feature_args); 3621 3616 if (ti->num_discard_bios) ··· 3636 3631 DMEMIT(" sector_size:%d", cc->sector_size); 3637 3632 if (test_bit(CRYPT_IV_LARGE_SECTORS, &cc->cipher_flags)) 3638 3633 DMEMIT(" iv_large_sectors"); 3634 + if (test_bit(CRYPT_KEY_MAC_SIZE_SET, &cc->cipher_flags)) 3635 + DMEMIT(" integrity_key_size:%u", cc->key_mac_size); 3639 3636 } 3640 3637 break; 3641 3638 ··· 3765 3758 3766 3759 static struct target_type crypt_target = { 3767 3760 .name = "crypt", 3768 - .version = {1, 27, 0}, 3761 + .version = {1, 28, 0}, 3769 3762 .module = THIS_MODULE, 3770 3763 .ctr = crypt_ctr, 3771 3764 .dtr = crypt_dtr,
+268 -58
drivers/md/dm-integrity.c
··· 284 284 285 285 mempool_t recheck_pool; 286 286 struct bio_set recheck_bios; 287 + struct bio_set recalc_bios; 287 288 288 289 struct notifier_block reboot_notifier; 289 290 }; ··· 322 321 struct dm_bio_details bio_details; 323 322 324 323 char *integrity_payload; 324 + unsigned payload_len; 325 325 bool integrity_payload_from_mempool; 326 + bool integrity_range_locked; 326 327 }; 327 328 328 329 struct journal_completion { ··· 362 359 #endif 363 360 364 361 static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map); 365 - static int dm_integrity_map_inline(struct dm_integrity_io *dio); 362 + static int dm_integrity_map_inline(struct dm_integrity_io *dio, bool from_map); 366 363 static void integrity_bio_wait(struct work_struct *w); 367 364 static void dm_integrity_dtr(struct dm_target *ti); 368 365 ··· 494 491 __u8 *sb = (__u8 *)ic->sb; 495 492 __u8 *mac = sb + (1 << SECTOR_SHIFT) - mac_size; 496 493 497 - if (sizeof(struct superblock) + mac_size > 1 << SECTOR_SHIFT) { 494 + if (sizeof(struct superblock) + mac_size > 1 << SECTOR_SHIFT || 495 + mac_size > HASH_MAX_DIGESTSIZE) { 498 496 dm_integrity_io_error(ic, "digest is too long", -EINVAL); 499 497 return -EINVAL; 500 498 } ··· 1504 1500 if (!ic->meta_dev) 1505 1501 flush_data = false; 1506 1502 if (flush_data) { 1507 - fr.io_req.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH | REQ_SYNC, 1508 - fr.io_req.mem.type = DM_IO_KMEM, 1509 - fr.io_req.mem.ptr.addr = NULL, 1510 - fr.io_req.notify.fn = flush_notify, 1503 + fr.io_req.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH | REQ_SYNC; 1504 + fr.io_req.mem.type = DM_IO_KMEM; 1505 + fr.io_req.mem.ptr.addr = NULL; 1506 + fr.io_req.notify.fn = flush_notify; 1511 1507 fr.io_req.notify.context = &fr; 1512 - fr.io_req.client = dm_bufio_get_dm_io_client(ic->bufio), 1513 - fr.io_reg.bdev = ic->dev->bdev, 1514 - fr.io_reg.sector = 0, 1515 - fr.io_reg.count = 0, 1508 + fr.io_req.client = dm_bufio_get_dm_io_client(ic->bufio); 1509 + fr.io_reg.bdev = ic->dev->bdev; 1510 + fr.io_reg.sector = 0; 1511 + fr.io_reg.count = 0; 1516 1512 fr.ic = ic; 1517 1513 init_completion(&fr.comp); 1518 1514 r = dm_io(&fr.io_req, 1, &fr.io_reg, NULL, IOPRIO_DEFAULT); ··· 1950 1946 dio->bi_status = 0; 1951 1947 dio->op = bio_op(bio); 1952 1948 1953 - if (ic->mode == 'I') 1954 - return dm_integrity_map_inline(dio); 1949 + if (ic->mode == 'I') { 1950 + bio->bi_iter.bi_sector = dm_target_offset(ic->ti, bio->bi_iter.bi_sector); 1951 + dio->integrity_payload = NULL; 1952 + dio->integrity_payload_from_mempool = false; 1953 + dio->integrity_range_locked = false; 1954 + return dm_integrity_map_inline(dio, true); 1955 + } 1955 1956 1956 1957 if (unlikely(dio->op == REQ_OP_DISCARD)) { 1957 1958 if (ti->max_io_len) { ··· 2406 2397 do_endio_flush(ic, dio); 2407 2398 } 2408 2399 2409 - static int dm_integrity_map_inline(struct dm_integrity_io *dio) 2400 + static int dm_integrity_map_inline(struct dm_integrity_io *dio, bool from_map) 2410 2401 { 2411 2402 struct dm_integrity_c *ic = dio->ic; 2412 2403 struct bio *bio = dm_bio_from_per_bio_data(dio, sizeof(struct dm_integrity_io)); 2413 2404 struct bio_integrity_payload *bip; 2414 - unsigned payload_len, digest_size, extra_size, ret; 2415 - 2416 - dio->integrity_payload = NULL; 2417 - dio->integrity_payload_from_mempool = false; 2405 + unsigned ret; 2406 + sector_t recalc_sector; 2418 2407 2419 2408 if (unlikely(bio_integrity(bio))) { 2420 2409 bio->bi_status = BLK_STS_NOTSUPP; ··· 2425 2418 return DM_MAPIO_REMAPPED; 2426 2419 2427 2420 retry: 2428 - payload_len = ic->tuple_size * (bio_sectors(bio) >> ic->sb->log2_sectors_per_block); 2429 - digest_size = crypto_shash_digestsize(ic->internal_hash); 2430 - extra_size = unlikely(digest_size > ic->tag_size) ? digest_size - ic->tag_size : 0; 2431 - payload_len += extra_size; 2432 - dio->integrity_payload = kmalloc(payload_len, GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); 2433 - if (unlikely(!dio->integrity_payload)) { 2434 - const unsigned x_size = PAGE_SIZE << 1; 2435 - if (payload_len > x_size) { 2436 - unsigned sectors = ((x_size - extra_size) / ic->tuple_size) << ic->sb->log2_sectors_per_block; 2437 - if (WARN_ON(!sectors || sectors >= bio_sectors(bio))) { 2438 - bio->bi_status = BLK_STS_NOTSUPP; 2439 - bio_endio(bio); 2440 - return DM_MAPIO_SUBMITTED; 2421 + if (!dio->integrity_payload) { 2422 + unsigned digest_size, extra_size; 2423 + dio->payload_len = ic->tuple_size * (bio_sectors(bio) >> ic->sb->log2_sectors_per_block); 2424 + digest_size = crypto_shash_digestsize(ic->internal_hash); 2425 + extra_size = unlikely(digest_size > ic->tag_size) ? digest_size - ic->tag_size : 0; 2426 + dio->payload_len += extra_size; 2427 + dio->integrity_payload = kmalloc(dio->payload_len, GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); 2428 + if (unlikely(!dio->integrity_payload)) { 2429 + const unsigned x_size = PAGE_SIZE << 1; 2430 + if (dio->payload_len > x_size) { 2431 + unsigned sectors = ((x_size - extra_size) / ic->tuple_size) << ic->sb->log2_sectors_per_block; 2432 + if (WARN_ON(!sectors || sectors >= bio_sectors(bio))) { 2433 + bio->bi_status = BLK_STS_NOTSUPP; 2434 + bio_endio(bio); 2435 + return DM_MAPIO_SUBMITTED; 2436 + } 2437 + dm_accept_partial_bio(bio, sectors); 2438 + goto retry; 2441 2439 } 2442 - dm_accept_partial_bio(bio, sectors); 2443 - goto retry; 2444 2440 } 2441 + } 2442 + 2443 + dio->range.logical_sector = bio->bi_iter.bi_sector; 2444 + dio->range.n_sectors = bio_sectors(bio); 2445 + 2446 + if (!(ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING))) 2447 + goto skip_spinlock; 2448 + #ifdef CONFIG_64BIT 2449 + /* 2450 + * On 64-bit CPUs we can optimize the lock away (so that it won't cause 2451 + * cache line bouncing) and use acquire/release barriers instead. 2452 + * 2453 + * Paired with smp_store_release in integrity_recalc_inline. 2454 + */ 2455 + recalc_sector = le64_to_cpu(smp_load_acquire(&ic->sb->recalc_sector)); 2456 + if (likely(dio->range.logical_sector + dio->range.n_sectors <= recalc_sector)) 2457 + goto skip_spinlock; 2458 + #endif 2459 + spin_lock_irq(&ic->endio_wait.lock); 2460 + recalc_sector = le64_to_cpu(ic->sb->recalc_sector); 2461 + if (dio->range.logical_sector + dio->range.n_sectors <= recalc_sector) 2462 + goto skip_unlock; 2463 + if (unlikely(!add_new_range(ic, &dio->range, true))) { 2464 + if (from_map) { 2465 + spin_unlock_irq(&ic->endio_wait.lock); 2466 + INIT_WORK(&dio->work, integrity_bio_wait); 2467 + queue_work(ic->wait_wq, &dio->work); 2468 + return DM_MAPIO_SUBMITTED; 2469 + } 2470 + wait_and_add_new_range(ic, &dio->range); 2471 + } 2472 + dio->integrity_range_locked = true; 2473 + skip_unlock: 2474 + spin_unlock_irq(&ic->endio_wait.lock); 2475 + skip_spinlock: 2476 + 2477 + if (unlikely(!dio->integrity_payload)) { 2445 2478 dio->integrity_payload = page_to_virt((struct page *)mempool_alloc(&ic->recheck_pool, GFP_NOIO)); 2446 2479 dio->integrity_payload_from_mempool = true; 2447 2480 } 2448 2481 2449 - bio->bi_iter.bi_sector = dm_target_offset(ic->ti, bio->bi_iter.bi_sector); 2450 2482 dio->bio_details.bi_iter = bio->bi_iter; 2451 2483 2452 2484 if (unlikely(!dm_integrity_check_limits(ic, bio->bi_iter.bi_sector, bio))) { ··· 2495 2449 bio->bi_iter.bi_sector += ic->start + SB_SECTORS; 2496 2450 2497 2451 bip = bio_integrity_alloc(bio, GFP_NOIO, 1); 2498 - if (unlikely(IS_ERR(bip))) { 2452 + if (IS_ERR(bip)) { 2499 2453 bio->bi_status = errno_to_blk_status(PTR_ERR(bip)); 2500 2454 bio_endio(bio); 2501 2455 return DM_MAPIO_SUBMITTED; ··· 2516 2470 } 2517 2471 2518 2472 ret = bio_integrity_add_page(bio, virt_to_page(dio->integrity_payload), 2519 - payload_len, offset_in_page(dio->integrity_payload)); 2520 - if (unlikely(ret != payload_len)) { 2473 + dio->payload_len, offset_in_page(dio->integrity_payload)); 2474 + if (unlikely(ret != dio->payload_len)) { 2521 2475 bio->bi_status = BLK_STS_RESOURCE; 2522 2476 bio_endio(bio); 2523 2477 return DM_MAPIO_SUBMITTED; ··· 2568 2522 } 2569 2523 2570 2524 bip = bio_integrity_alloc(outgoing_bio, GFP_NOIO, 1); 2571 - if (unlikely(IS_ERR(bip))) { 2525 + if (IS_ERR(bip)) { 2572 2526 bio_put(outgoing_bio); 2573 2527 bio->bi_status = errno_to_blk_status(PTR_ERR(bip)); 2574 2528 bio_endio(bio); ··· 2625 2579 struct dm_integrity_io *dio = dm_per_bio_data(bio, sizeof(struct dm_integrity_io)); 2626 2580 if (dio->op == REQ_OP_READ && likely(*status == BLK_STS_OK)) { 2627 2581 unsigned pos = 0; 2582 + if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING) && 2583 + unlikely(dio->integrity_range_locked)) 2584 + goto skip_check; 2628 2585 while (dio->bio_details.bi_iter.bi_size) { 2629 2586 char digest[HASH_MAX_DIGESTSIZE]; 2630 2587 struct bio_vec bv = bio_iter_iovec(bio, dio->bio_details.bi_iter); ··· 2647 2598 bio_advance_iter_single(bio, &dio->bio_details.bi_iter, ic->sectors_per_block << SECTOR_SHIFT); 2648 2599 } 2649 2600 } 2650 - if (likely(dio->op == REQ_OP_READ) || likely(dio->op == REQ_OP_WRITE)) { 2651 - dm_integrity_free_payload(dio); 2652 - } 2601 + skip_check: 2602 + dm_integrity_free_payload(dio); 2603 + if (unlikely(dio->integrity_range_locked)) 2604 + remove_range(ic, &dio->range); 2653 2605 } 2654 2606 return DM_ENDIO_DONE; 2655 2607 } ··· 2658 2608 static void integrity_bio_wait(struct work_struct *w) 2659 2609 { 2660 2610 struct dm_integrity_io *dio = container_of(w, struct dm_integrity_io, work); 2611 + struct dm_integrity_c *ic = dio->ic; 2661 2612 2662 - dm_integrity_map_continue(dio, false); 2613 + if (ic->mode == 'I') { 2614 + struct bio *bio = dm_bio_from_per_bio_data(dio, sizeof(struct dm_integrity_io)); 2615 + int r = dm_integrity_map_inline(dio, false); 2616 + switch (r) { 2617 + case DM_MAPIO_KILL: 2618 + bio->bi_status = BLK_STS_IOERR; 2619 + fallthrough; 2620 + case DM_MAPIO_REMAPPED: 2621 + submit_bio_noacct(bio); 2622 + fallthrough; 2623 + case DM_MAPIO_SUBMITTED: 2624 + return; 2625 + default: 2626 + BUG(); 2627 + } 2628 + } else { 2629 + dm_integrity_map_continue(dio, false); 2630 + } 2663 2631 } 2664 2632 2665 2633 static void pad_uncommitted(struct dm_integrity_c *ic) ··· 3147 3079 free_ret: 3148 3080 vfree(recalc_buffer); 3149 3081 kvfree(recalc_tags); 3082 + } 3083 + 3084 + static void integrity_recalc_inline(struct work_struct *w) 3085 + { 3086 + struct dm_integrity_c *ic = container_of(w, struct dm_integrity_c, recalc_work); 3087 + size_t recalc_tags_size; 3088 + u8 *recalc_buffer = NULL; 3089 + u8 *recalc_tags = NULL; 3090 + struct dm_integrity_range range; 3091 + struct bio *bio; 3092 + struct bio_integrity_payload *bip; 3093 + __u8 *t; 3094 + unsigned int i; 3095 + int r; 3096 + unsigned ret; 3097 + unsigned int super_counter = 0; 3098 + unsigned recalc_sectors = RECALC_SECTORS; 3099 + 3100 + retry: 3101 + recalc_buffer = kmalloc(recalc_sectors << SECTOR_SHIFT, GFP_NOIO | __GFP_NOWARN); 3102 + if (!recalc_buffer) { 3103 + oom: 3104 + recalc_sectors >>= 1; 3105 + if (recalc_sectors >= 1U << ic->sb->log2_sectors_per_block) 3106 + goto retry; 3107 + DMCRIT("out of memory for recalculate buffer - recalculation disabled"); 3108 + goto free_ret; 3109 + } 3110 + 3111 + recalc_tags_size = (recalc_sectors >> ic->sb->log2_sectors_per_block) * ic->tuple_size; 3112 + if (crypto_shash_digestsize(ic->internal_hash) > ic->tuple_size) 3113 + recalc_tags_size += crypto_shash_digestsize(ic->internal_hash) - ic->tuple_size; 3114 + recalc_tags = kmalloc(recalc_tags_size, GFP_NOIO | __GFP_NOWARN); 3115 + if (!recalc_tags) { 3116 + kfree(recalc_buffer); 3117 + recalc_buffer = NULL; 3118 + goto oom; 3119 + } 3120 + 3121 + spin_lock_irq(&ic->endio_wait.lock); 3122 + 3123 + next_chunk: 3124 + if (unlikely(dm_post_suspending(ic->ti))) 3125 + goto unlock_ret; 3126 + 3127 + range.logical_sector = le64_to_cpu(ic->sb->recalc_sector); 3128 + if (unlikely(range.logical_sector >= ic->provided_data_sectors)) 3129 + goto unlock_ret; 3130 + range.n_sectors = min((sector_t)recalc_sectors, ic->provided_data_sectors - range.logical_sector); 3131 + 3132 + add_new_range_and_wait(ic, &range); 3133 + spin_unlock_irq(&ic->endio_wait.lock); 3134 + 3135 + if (unlikely(++super_counter == RECALC_WRITE_SUPER)) { 3136 + recalc_write_super(ic); 3137 + super_counter = 0; 3138 + } 3139 + 3140 + if (unlikely(dm_integrity_failed(ic))) 3141 + goto err; 3142 + 3143 + DEBUG_print("recalculating: %llx - %llx\n", range.logical_sector, range.n_sectors); 3144 + 3145 + bio = bio_alloc_bioset(ic->dev->bdev, 1, REQ_OP_READ, GFP_NOIO, &ic->recalc_bios); 3146 + bio->bi_iter.bi_sector = ic->start + SB_SECTORS + range.logical_sector; 3147 + __bio_add_page(bio, virt_to_page(recalc_buffer), range.n_sectors << SECTOR_SHIFT, offset_in_page(recalc_buffer)); 3148 + r = submit_bio_wait(bio); 3149 + bio_put(bio); 3150 + if (unlikely(r)) { 3151 + dm_integrity_io_error(ic, "reading data", r); 3152 + goto err; 3153 + } 3154 + 3155 + t = recalc_tags; 3156 + for (i = 0; i < range.n_sectors; i += ic->sectors_per_block) { 3157 + memset(t, 0, ic->tuple_size); 3158 + integrity_sector_checksum(ic, range.logical_sector + i, recalc_buffer + (i << SECTOR_SHIFT), t); 3159 + t += ic->tuple_size; 3160 + } 3161 + 3162 + bio = bio_alloc_bioset(ic->dev->bdev, 1, REQ_OP_WRITE, GFP_NOIO, &ic->recalc_bios); 3163 + bio->bi_iter.bi_sector = ic->start + SB_SECTORS + range.logical_sector; 3164 + __bio_add_page(bio, virt_to_page(recalc_buffer), range.n_sectors << SECTOR_SHIFT, offset_in_page(recalc_buffer)); 3165 + 3166 + bip = bio_integrity_alloc(bio, GFP_NOIO, 1); 3167 + if (unlikely(IS_ERR(bip))) { 3168 + bio_put(bio); 3169 + DMCRIT("out of memory for bio integrity payload - recalculation disabled"); 3170 + goto err; 3171 + } 3172 + ret = bio_integrity_add_page(bio, virt_to_page(recalc_tags), t - recalc_tags, offset_in_page(recalc_tags)); 3173 + if (unlikely(ret != t - recalc_tags)) { 3174 + bio_put(bio); 3175 + dm_integrity_io_error(ic, "attaching integrity tags", -ENOMEM); 3176 + goto err; 3177 + } 3178 + 3179 + r = submit_bio_wait(bio); 3180 + bio_put(bio); 3181 + if (unlikely(r)) { 3182 + dm_integrity_io_error(ic, "writing data", r); 3183 + goto err; 3184 + } 3185 + 3186 + cond_resched(); 3187 + spin_lock_irq(&ic->endio_wait.lock); 3188 + remove_range_unlocked(ic, &range); 3189 + #ifdef CONFIG_64BIT 3190 + /* Paired with smp_load_acquire in dm_integrity_map_inline. */ 3191 + smp_store_release(&ic->sb->recalc_sector, cpu_to_le64(range.logical_sector + range.n_sectors)); 3192 + #else 3193 + ic->sb->recalc_sector = cpu_to_le64(range.logical_sector + range.n_sectors); 3194 + #endif 3195 + goto next_chunk; 3196 + 3197 + err: 3198 + remove_range(ic, &range); 3199 + goto free_ret; 3200 + 3201 + unlock_ret: 3202 + spin_unlock_irq(&ic->endio_wait.lock); 3203 + 3204 + recalc_write_super(ic); 3205 + 3206 + free_ret: 3207 + kfree(recalc_buffer); 3208 + kfree(recalc_tags); 3150 3209 } 3151 3210 3152 3211 static void bitmap_block_work(struct work_struct *w) ··· 4814 4619 r = -ENOMEM; 4815 4620 goto bad; 4816 4621 } 4622 + r = bioset_init(&ic->recalc_bios, 1, 0, BIOSET_NEED_BVECS); 4623 + if (r) { 4624 + ti->error = "Cannot allocate bio set"; 4625 + goto bad; 4626 + } 4627 + r = bioset_integrity_create(&ic->recalc_bios, 1); 4628 + if (r) { 4629 + ti->error = "Cannot allocate bio integrity set"; 4630 + r = -ENOMEM; 4631 + goto bad; 4632 + } 4817 4633 } 4818 4634 4819 4635 ic->metadata_wq = alloc_workqueue("dm-integrity-metadata", ··· 4923 4717 ti->error = "Block size doesn't match the information in superblock"; 4924 4718 goto bad; 4925 4719 } 4926 - if (!le32_to_cpu(ic->sb->journal_sections) != (ic->mode == 'I')) { 4927 - r = -EINVAL; 4928 - if (ic->mode != 'I') 4720 + if (ic->mode != 'I') { 4721 + if (!le32_to_cpu(ic->sb->journal_sections)) { 4722 + r = -EINVAL; 4929 4723 ti->error = "Corrupted superblock, journal_sections is 0"; 4930 - else 4724 + goto bad; 4725 + } 4726 + } else { 4727 + if (le32_to_cpu(ic->sb->journal_sections)) { 4728 + r = -EINVAL; 4931 4729 ti->error = "Corrupted superblock, journal_sections is not 0"; 4932 - goto bad; 4730 + goto bad; 4731 + } 4933 4732 } 4934 4733 /* make sure that ti->max_io_len doesn't overflow */ 4935 4734 if (!ic->meta_dev) { ··· 5041 4830 r = -ENOMEM; 5042 4831 goto bad; 5043 4832 } 5044 - INIT_WORK(&ic->recalc_work, integrity_recalc); 4833 + INIT_WORK(&ic->recalc_work, ic->mode == 'I' ? integrity_recalc_inline : integrity_recalc); 5045 4834 } else { 5046 4835 if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING)) { 5047 4836 ti->error = "Recalculate can only be specified with internal_hash"; ··· 5058 4847 goto bad; 5059 4848 } 5060 4849 5061 - if (ic->mode != 'I') { 5062 - ic->bufio = dm_bufio_client_create(ic->meta_dev ? ic->meta_dev->bdev : ic->dev->bdev, 5063 - 1U << (SECTOR_SHIFT + ic->log2_buffer_sectors), 1, 0, NULL, NULL, 0); 5064 - if (IS_ERR(ic->bufio)) { 5065 - r = PTR_ERR(ic->bufio); 5066 - ti->error = "Cannot initialize dm-bufio"; 5067 - ic->bufio = NULL; 5068 - goto bad; 5069 - } 5070 - dm_bufio_set_sector_offset(ic->bufio, ic->start + ic->initial_sectors); 4850 + ic->bufio = dm_bufio_client_create(ic->meta_dev ? ic->meta_dev->bdev : ic->dev->bdev, 4851 + 1U << (SECTOR_SHIFT + ic->log2_buffer_sectors), 1, 0, NULL, NULL, 0); 4852 + if (IS_ERR(ic->bufio)) { 4853 + r = PTR_ERR(ic->bufio); 4854 + ti->error = "Cannot initialize dm-bufio"; 4855 + ic->bufio = NULL; 4856 + goto bad; 5071 4857 } 4858 + dm_bufio_set_sector_offset(ic->bufio, ic->start + ic->initial_sectors); 5072 4859 5073 4860 if (ic->mode != 'R' && ic->mode != 'I') { 5074 4861 r = create_journal(ic, &ti->error); ··· 5188 4979 kvfree(ic->bbs); 5189 4980 if (ic->bufio) 5190 4981 dm_bufio_client_destroy(ic->bufio); 4982 + bioset_exit(&ic->recalc_bios); 5191 4983 bioset_exit(&ic->recheck_bios); 5192 4984 mempool_exit(&ic->recheck_pool); 5193 4985 mempool_exit(&ic->journal_io_mempool); ··· 5243 5033 5244 5034 static struct target_type integrity_target = { 5245 5035 .name = "integrity", 5246 - .version = {1, 12, 0}, 5036 + .version = {1, 13, 0}, 5247 5037 .module = THIS_MODULE, 5248 5038 .features = DM_TARGET_SINGLETON | DM_TARGET_INTEGRITY, 5249 5039 .ctr = dm_integrity_ctr,
+1 -1
drivers/md/dm-raid.c
··· 2519 2519 rdev->saved_raid_disk = rdev->raid_disk; 2520 2520 } 2521 2521 2522 - /* Reshape support -> restore repective data offsets */ 2522 + /* Reshape support -> restore respective data offsets */ 2523 2523 rdev->data_offset = le64_to_cpu(sb->data_offset); 2524 2524 rdev->new_data_offset = le64_to_cpu(sb->new_data_offset); 2525 2525
+3 -1
drivers/md/dm-rq.c
··· 496 496 497 497 map = dm_get_live_table(md, &srcu_idx); 498 498 if (unlikely(!map)) { 499 + DMERR_LIMIT("%s: mapping table unavailable, erroring io", 500 + dm_device_name(md)); 499 501 dm_put_live_table(md, srcu_idx); 500 - return BLK_STS_RESOURCE; 502 + return BLK_STS_IOERR; 501 503 } 502 504 ti = dm_table_find_target(map, 0); 503 505 dm_put_live_table(md, srcu_idx);
+1 -1
drivers/md/dm-thin.c
··· 2948 2948 pmd = dm_pool_metadata_open(metadata_dev, block_size, format_device); 2949 2949 if (IS_ERR(pmd)) { 2950 2950 *error = "Error creating metadata object"; 2951 - return (struct pool *)pmd; 2951 + return ERR_CAST(pmd); 2952 2952 } 2953 2953 2954 2954 pool = kzalloc(sizeof(*pool), GFP_KERNEL);
+9 -6
drivers/md/dm-vdo/data-vio.c
··· 501 501 502 502 memset(&data_vio->record_name, 0, sizeof(data_vio->record_name)); 503 503 memset(&data_vio->duplicate, 0, sizeof(data_vio->duplicate)); 504 + vdo_reset_completion(&data_vio->decrement_completion); 504 505 vdo_reset_completion(completion); 505 506 completion->error_handler = handle_data_vio_error; 506 507 set_data_vio_logical_callback(data_vio, attempt_logical_block_lock); ··· 1274 1273 static void finish_cleanup(struct data_vio *data_vio) 1275 1274 { 1276 1275 struct vdo_completion *completion = &data_vio->vio.completion; 1276 + u32 discard_size = min_t(u32, data_vio->remaining_discard, 1277 + VDO_BLOCK_SIZE - data_vio->offset); 1277 1278 1278 1279 VDO_ASSERT_LOG_ONLY(data_vio->allocation.lock == NULL, 1279 1280 "complete data_vio has no allocation lock"); 1280 1281 VDO_ASSERT_LOG_ONLY(data_vio->hash_lock == NULL, 1281 1282 "complete data_vio has no hash lock"); 1282 - if ((data_vio->remaining_discard <= VDO_BLOCK_SIZE) || 1283 + if ((data_vio->remaining_discard <= discard_size) || 1283 1284 (completion->result != VDO_SUCCESS)) { 1284 1285 struct data_vio_pool *pool = completion->vdo->data_vio_pool; 1285 1286 ··· 1290 1287 return; 1291 1288 } 1292 1289 1293 - data_vio->remaining_discard -= min_t(u32, data_vio->remaining_discard, 1294 - VDO_BLOCK_SIZE - data_vio->offset); 1290 + data_vio->remaining_discard -= discard_size; 1295 1291 data_vio->is_partial = (data_vio->remaining_discard < VDO_BLOCK_SIZE); 1296 1292 data_vio->read = data_vio->is_partial; 1297 1293 data_vio->offset = 0; 1298 1294 completion->requeue = true; 1295 + data_vio->first_reference_operation_complete = false; 1299 1296 launch_data_vio(data_vio, data_vio->logical.lbn + 1); 1300 1297 } 1301 1298 ··· 1968 1965 .state = VDO_MAPPING_STATE_UNCOMPRESSED, 1969 1966 }; 1970 1967 1971 - if (data_vio->fua) { 1968 + if (data_vio->fua || 1969 + data_vio->remaining_discard > (u32) (VDO_BLOCK_SIZE - data_vio->offset)) { 1972 1970 prepare_for_dedupe(data_vio); 1973 1971 return; 1974 1972 } ··· 2046 2042 return; 2047 2043 } 2048 2044 2049 - 2050 2045 /* 2051 2046 * We don't need to write any data, so skip allocation and just update the block map and 2052 2047 * reference counts (via the journal). ··· 2054 2051 if (data_vio->is_zero) 2055 2052 data_vio->new_mapped.state = VDO_MAPPING_STATE_UNCOMPRESSED; 2056 2053 2057 - if (data_vio->remaining_discard > VDO_BLOCK_SIZE) { 2054 + if (data_vio->remaining_discard > (u32) (VDO_BLOCK_SIZE - data_vio->offset)) { 2058 2055 /* This is not the final block of a discard so we can't acknowledge it yet. */ 2059 2056 update_metadata_for_data_vio_write(data_vio, NULL); 2060 2057 return;
+3
drivers/md/dm-vdo/dedupe.c
··· 729 729 !change_context_state(context, DEDUPE_CONTEXT_COMPLETE, DEDUPE_CONTEXT_IDLE)) 730 730 return; 731 731 732 + agent->dedupe_context = NULL; 732 733 release_context(context); 733 734 } 734 735 ··· 1649 1648 1650 1649 if (change_context_state(context, DEDUPE_CONTEXT_COMPLETE, DEDUPE_CONTEXT_IDLE)) { 1651 1650 agent->is_duplicate = decode_uds_advice(context); 1651 + agent->dedupe_context = NULL; 1652 1652 release_context(context); 1653 1653 } 1654 1654 } ··· 2323 2321 * send its requestor on its way. 2324 2322 */ 2325 2323 list_del_init(&context->list_entry); 2324 + context->requestor->dedupe_context = NULL; 2326 2325 continue_data_vio(context->requestor); 2327 2326 timed_out++; 2328 2327 }
+27 -2
drivers/md/dm-vdo/dm-vdo-target.c
··· 1105 1105 if ((argc == 1) && (strcasecmp(argv[0], "stats") == 0)) { 1106 1106 vdo_write_stats(vdo, result_buffer, maxlen); 1107 1107 result = 1; 1108 + } else if ((argc == 1) && (strcasecmp(argv[0], "config") == 0)) { 1109 + vdo_write_config(vdo, &result_buffer, &maxlen); 1110 + result = 1; 1108 1111 } else { 1109 1112 result = vdo_status_to_errno(process_vdo_message(vdo, argc, argv)); 1110 1113 } ··· 2296 2293 return; 2297 2294 } 2298 2295 2296 + if ((completion->result == VDO_UNSUPPORTED_VERSION) && 2297 + (vdo->admin.phase == LOAD_PHASE_MAKE_DIRTY)) { 2298 + vdo_log_error("Aborting load due to unsupported version"); 2299 + vdo->admin.phase = LOAD_PHASE_FINISHED; 2300 + load_callback(completion); 2301 + return; 2302 + } 2303 + 2299 2304 vdo_log_error_strerror(completion->result, 2300 2305 "Entering read-only mode due to load error"); 2301 2306 vdo->admin.phase = LOAD_PHASE_WAIT_FOR_READ_ONLY; ··· 2748 2737 vdo_log_info("starting device '%s'", device_name); 2749 2738 result = perform_admin_operation(vdo, LOAD_PHASE_START, load_callback, 2750 2739 handle_load_error, "load"); 2740 + if (result == VDO_UNSUPPORTED_VERSION) { 2741 + /* 2742 + * A component version is not supported. This can happen when the 2743 + * recovery journal metadata is in an old version format. Abort the 2744 + * load without saving the state. 2745 + */ 2746 + vdo->suspend_type = VDO_ADMIN_STATE_SUSPENDING; 2747 + perform_admin_operation(vdo, SUSPEND_PHASE_START, 2748 + suspend_callback, suspend_callback, 2749 + "suspend"); 2750 + return result; 2751 + } 2752 + 2751 2753 if ((result != VDO_SUCCESS) && (result != VDO_READ_ONLY)) { 2752 2754 /* 2753 2755 * Something has gone very wrong. Make sure everything has drained and ··· 2832 2808 2833 2809 vdo_register_thread_device_id(&instance_thread, &vdo->instance); 2834 2810 result = vdo_preresume_registered(ti, vdo); 2835 - if ((result == VDO_PARAMETER_MISMATCH) || (result == VDO_INVALID_ADMIN_STATE)) 2811 + if ((result == VDO_PARAMETER_MISMATCH) || (result == VDO_INVALID_ADMIN_STATE) || 2812 + (result == VDO_UNSUPPORTED_VERSION)) 2836 2813 result = -EINVAL; 2837 2814 vdo_unregister_thread_device_id(); 2838 2815 return vdo_status_to_errno(result); ··· 2857 2832 static struct target_type vdo_target_bio = { 2858 2833 .features = DM_TARGET_SINGLETON, 2859 2834 .name = "vdo", 2860 - .version = { 9, 0, 0 }, 2835 + .version = { 9, 1, 0 }, 2861 2836 .module = THIS_MODULE, 2862 2837 .ctr = vdo_ctr, 2863 2838 .dtr = vdo_dtr,
+1 -1
drivers/md/dm-vdo/indexer/chapter-index.c
··· 177 177 if (list_number < 0) 178 178 return UDS_OVERFLOW; 179 179 180 - next_list = first_list + list_number--, 180 + next_list = first_list + list_number--; 181 181 result = uds_start_delta_index_search(delta_index, next_list, 0, 182 182 &entry); 183 183 if (result != UDS_SUCCESS)
-1
drivers/md/dm-vdo/io-submitter.c
··· 346 346 347 347 348 348 VDO_ASSERT_LOG_ONLY(!code->quiescent, "I/O not allowed in state %s", code->name); 349 - VDO_ASSERT_LOG_ONLY(vio->bio->bi_next == NULL, "metadata bio has no next bio"); 350 349 351 350 vdo_reset_completion(completion); 352 351 completion->error_handler = error_handler;
+48
drivers/md/dm-vdo/message-stats.c
··· 4 4 */ 5 5 6 6 #include "dedupe.h" 7 + #include "indexer.h" 7 8 #include "logger.h" 8 9 #include "memory-alloc.h" 9 10 #include "message-stats.h" ··· 429 428 vdo_fetch_statistics(vdo, stats); 430 429 write_vdo_statistics(NULL, stats, NULL, &buf, &maxlen); 431 430 vdo_free(stats); 431 + return VDO_SUCCESS; 432 + } 433 + 434 + static void write_index_memory(u32 mem, char **buf, unsigned int *maxlen) 435 + { 436 + char *prefix = "memorySize : "; 437 + 438 + /* Convert index memory to fractional value */ 439 + if (mem == (u32)UDS_MEMORY_CONFIG_256MB) 440 + write_string(prefix, "0.25, ", NULL, buf, maxlen); 441 + else if (mem == (u32)UDS_MEMORY_CONFIG_512MB) 442 + write_string(prefix, "0.50, ", NULL, buf, maxlen); 443 + else if (mem == (u32)UDS_MEMORY_CONFIG_768MB) 444 + write_string(prefix, "0.75, ", NULL, buf, maxlen); 445 + else 446 + write_u32(prefix, mem, ", ", buf, maxlen); 447 + } 448 + 449 + static void write_index_config(struct index_config *config, char **buf, 450 + unsigned int *maxlen) 451 + { 452 + write_string("index : ", "{ ", NULL, buf, maxlen); 453 + /* index mem size */ 454 + write_index_memory(config->mem, buf, maxlen); 455 + /* whether the index is sparse or not */ 456 + write_bool("isSparse : ", config->sparse, ", ", buf, maxlen); 457 + write_string(NULL, "}", ", ", buf, maxlen); 458 + } 459 + 460 + int vdo_write_config(struct vdo *vdo, char **buf, unsigned int *maxlen) 461 + { 462 + struct vdo_config *config = &vdo->states.vdo.config; 463 + 464 + write_string(NULL, "{ ", NULL, buf, maxlen); 465 + /* version */ 466 + write_u32("version : ", 1, ", ", buf, maxlen); 467 + /* physical size */ 468 + write_block_count_t("physicalSize : ", config->physical_blocks * VDO_BLOCK_SIZE, ", ", 469 + buf, maxlen); 470 + /* logical size */ 471 + write_block_count_t("logicalSize : ", config->logical_blocks * VDO_BLOCK_SIZE, ", ", 472 + buf, maxlen); 473 + /* slab size */ 474 + write_block_count_t("slabSize : ", config->slab_size, ", ", buf, maxlen); 475 + /* index config */ 476 + write_index_config(&vdo->geometry.index_config, buf, maxlen); 477 + write_string(NULL, "}", NULL, buf, maxlen); 432 478 return VDO_SUCCESS; 433 479 }
+1
drivers/md/dm-vdo/message-stats.h
··· 8 8 9 9 #include "types.h" 10 10 11 + int vdo_write_config(struct vdo *vdo, char **buf, unsigned int *maxlen); 11 12 int vdo_write_stats(struct vdo *vdo, char *buf, unsigned int maxlen); 12 13 13 14 #endif /* VDO_MESSAGE_STATS_H */
+22 -19
drivers/md/dm-vdo/repair.c
··· 1202 1202 * @journal: The journal to use. 1203 1203 * @header: The unpacked block header to check. 1204 1204 * @sequence: The expected sequence number. 1205 - * @type: The expected metadata type. 1206 1205 * 1207 1206 * Return: True if the block matches. 1208 1207 */ 1209 1208 static bool __must_check is_exact_recovery_journal_block(const struct recovery_journal *journal, 1210 1209 const struct recovery_block_header *header, 1211 - sequence_number_t sequence, 1212 - enum vdo_metadata_type type) 1210 + sequence_number_t sequence) 1213 1211 { 1214 - return ((header->metadata_type == type) && 1215 - (header->sequence_number == sequence) && 1212 + return ((header->sequence_number == sequence) && 1216 1213 (is_valid_recovery_journal_block(journal, header, true))); 1217 1214 } 1218 1215 ··· 1368 1371 get_recovery_journal_block_header(journal, repair->journal_data, 1369 1372 sequence); 1370 1373 1371 - if (!is_exact_recovery_journal_block(journal, &header, sequence, format)) { 1374 + if (!is_exact_recovery_journal_block(journal, &header, sequence) || 1375 + (header.metadata_type != format)) { 1372 1376 /* This block is invalid, so skip it. */ 1373 1377 return; 1374 1378 } ··· 1555 1557 sequence_number_t i, head; 1556 1558 bool found_entries = false; 1557 1559 struct recovery_journal *journal = repair->completion.vdo->recovery_journal; 1560 + struct recovery_block_header header; 1561 + enum vdo_metadata_type expected_format; 1558 1562 1559 1563 head = min(repair->block_map_head, repair->slab_journal_head); 1564 + header = get_recovery_journal_block_header(journal, repair->journal_data, head); 1565 + expected_format = header.metadata_type; 1560 1566 for (i = head; i <= repair->highest_tail; i++) { 1561 - struct recovery_block_header header; 1562 1567 journal_entry_count_t block_entries; 1563 1568 u8 j; 1564 1569 ··· 1573 1572 }; 1574 1573 1575 1574 header = get_recovery_journal_block_header(journal, repair->journal_data, i); 1576 - if (header.metadata_type == VDO_METADATA_RECOVERY_JOURNAL) { 1577 - /* This is an old format block, so we need to upgrade */ 1578 - vdo_log_error_strerror(VDO_UNSUPPORTED_VERSION, 1579 - "Recovery journal is in the old format, a read-only rebuild is required."); 1580 - vdo_enter_read_only_mode(repair->completion.vdo, 1581 - VDO_UNSUPPORTED_VERSION); 1582 - return VDO_UNSUPPORTED_VERSION; 1583 - } 1584 - 1585 - if (!is_exact_recovery_journal_block(journal, &header, i, 1586 - VDO_METADATA_RECOVERY_JOURNAL_2)) { 1575 + if (!is_exact_recovery_journal_block(journal, &header, i)) { 1587 1576 /* A bad block header was found so this must be the end of the journal. */ 1588 1577 break; 1578 + } else if (header.metadata_type != expected_format) { 1579 + /* There is a mix of old and new format blocks, so we need to rebuild. */ 1580 + vdo_log_error_strerror(VDO_CORRUPT_JOURNAL, 1581 + "Recovery journal is in an invalid format, a read-only rebuild is required."); 1582 + vdo_enter_read_only_mode(repair->completion.vdo, VDO_CORRUPT_JOURNAL); 1583 + return VDO_CORRUPT_JOURNAL; 1589 1584 } 1590 1585 1591 1586 block_entries = header.entry_count; ··· 1617 1620 break; 1618 1621 } 1619 1622 1620 - if (!found_entries) 1623 + if (!found_entries) { 1621 1624 return validate_heads(repair); 1625 + } else if (expected_format == VDO_METADATA_RECOVERY_JOURNAL) { 1626 + /* All journal blocks have the old format, so we need to upgrade. */ 1627 + vdo_log_error_strerror(VDO_UNSUPPORTED_VERSION, 1628 + "Recovery journal is in the old format. Downgrade and complete recovery, then upgrade with a clean volume"); 1629 + return VDO_UNSUPPORTED_VERSION; 1630 + } 1622 1631 1623 1632 /* Set the tail to the last valid tail block, if there is one. */ 1624 1633 if (repair->tail_recovery_point.sector_count == 0)
+1 -1
drivers/md/dm-vdo/status-codes.c
··· 28 28 { "VDO_LOCK_ERROR", "A lock is held incorrectly" }, 29 29 { "VDO_READ_ONLY", "The device is in read-only mode" }, 30 30 { "VDO_SHUTTING_DOWN", "The device is shutting down" }, 31 - { "VDO_CORRUPT_JOURNAL", "Recovery journal entries corrupted" }, 31 + { "VDO_CORRUPT_JOURNAL", "Recovery journal corrupted" }, 32 32 { "VDO_TOO_MANY_SLABS", "Exceeds maximum number of slabs supported" }, 33 33 { "VDO_INVALID_FRAGMENT", "Compressed block fragment is invalid" }, 34 34 { "VDO_RETRY_AFTER_REBUILD", "Retry operation after rebuilding finishes" },
+1 -1
drivers/md/dm-vdo/status-codes.h
··· 52 52 VDO_READ_ONLY, 53 53 /* the VDO is shutting down */ 54 54 VDO_SHUTTING_DOWN, 55 - /* the recovery journal has corrupt entries */ 55 + /* the recovery journal has corrupt entries or corrupt metadata */ 56 56 VDO_CORRUPT_JOURNAL, 57 57 /* exceeds maximum number of slabs supported */ 58 58 VDO_TOO_MANY_SLABS,
+21 -2
drivers/md/dm-verity-target.c
··· 273 273 if (v->mode == DM_VERITY_MODE_LOGGING) 274 274 return 0; 275 275 276 - if (v->mode == DM_VERITY_MODE_RESTART) 277 - kernel_restart("dm-verity device corrupted"); 276 + if (v->mode == DM_VERITY_MODE_RESTART) { 277 + pr_emerg("dm-verity device corrupted\n"); 278 + emergency_restart(); 279 + } 278 280 279 281 if (v->mode == DM_VERITY_MODE_PANIC) 280 282 panic("dm-verity device corrupted"); ··· 598 596 599 597 if (!static_branch_unlikely(&use_bh_wq_enabled) || !io->in_bh) 600 598 verity_fec_finish_io(io); 599 + 600 + if (unlikely(status != BLK_STS_OK) && 601 + unlikely(!(bio->bi_opf & REQ_RAHEAD)) && 602 + !verity_is_system_shutting_down()) { 603 + if (v->mode == DM_VERITY_MODE_RESTART || 604 + v->mode == DM_VERITY_MODE_PANIC) 605 + DMERR_LIMIT("%s has error: %s", v->data_dev->name, 606 + blk_status_to_str(status)); 607 + 608 + if (v->mode == DM_VERITY_MODE_RESTART) { 609 + pr_emerg("dm-verity device corrupted\n"); 610 + emergency_restart(); 611 + } 612 + 613 + if (v->mode == DM_VERITY_MODE_PANIC) 614 + panic("dm-verity device corrupted"); 615 + } 601 616 602 617 bio_endio(bio); 603 618 }
+1 -1
drivers/md/dm-verity-verify-sig.c
··· 127 127 #endif 128 128 VERIFYING_UNSPECIFIED_SIGNATURE, NULL, NULL); 129 129 #ifdef CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING 130 - if (ret == -ENOKEY) 130 + if (ret == -ENOKEY || ret == -EKEYREJECTED) 131 131 ret = verify_pkcs7_signature(root_hash, root_hash_len, sig_data, 132 132 sig_len, 133 133 VERIFY_USE_PLATFORM_KEYRING,
+8 -3
drivers/md/dm.c
··· 2030 2030 struct dm_table *map; 2031 2031 2032 2032 map = dm_get_live_table(md, &srcu_idx); 2033 + if (unlikely(!map)) { 2034 + DMERR_LIMIT("%s: mapping table unavailable, erroring io", 2035 + dm_device_name(md)); 2036 + bio_io_error(bio); 2037 + goto out; 2038 + } 2033 2039 2034 - /* If suspended, or map not yet available, queue this IO for later */ 2035 - if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) || 2036 - unlikely(!map)) { 2040 + /* If suspended, queue this IO for later */ 2041 + if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags))) { 2037 2042 if (bio->bi_opf & REQ_NOWAIT) 2038 2043 bio_wouldblock_error(bio); 2039 2044 else if (bio->bi_opf & REQ_RAHEAD)
-5
drivers/md/dm.h
··· 109 109 int dm_blk_report_zones(struct gendisk *disk, sector_t sector, 110 110 unsigned int nr_zones, report_zones_cb cb, void *data); 111 111 bool dm_is_zone_write(struct mapped_device *md, struct bio *bio); 112 - int dm_zone_map_bio(struct dm_target_io *io); 113 112 int dm_zone_get_reset_bitmap(struct mapped_device *md, struct dm_table *t, 114 113 sector_t sector, unsigned int nr_zones, 115 114 unsigned long *need_reset); ··· 117 118 static inline bool dm_is_zone_write(struct mapped_device *md, struct bio *bio) 118 119 { 119 120 return false; 120 - } 121 - static inline int dm_zone_map_bio(struct dm_target_io *tio) 122 - { 123 - return DM_MAPIO_KILL; 124 121 } 125 122 #endif 126 123
-1
include/linux/device-mapper.h
··· 524 524 int dm_noflush_suspending(struct dm_target *ti); 525 525 void dm_accept_partial_bio(struct bio *bio, unsigned int n_sectors); 526 526 void dm_submit_bio_remap(struct bio *clone, struct bio *tgt_clone); 527 - union map_info *dm_get_rq_mapinfo(struct request *rq); 528 527 529 528 #ifdef CONFIG_BLK_DEV_ZONED 530 529 struct dm_report_zones_args {