Skip to content

Commit 2322488

Browse files
committed
Merge: dm: sync outstanding bugfixes to v6.15 from upstream
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/937 JIRA: https://issues.redhat.com/browse/RHEL-92762 Tested: lvm2-testsuite Upstream Status: kernel/git/torvalds/linux.git Pull in outstanding dm bugfiles from upstream Signed-off-by: Benjamin Marzinski <[email protected]> Approved-by: Matthew Sakai <[email protected]> Approved-by: Mikuláš Patočka <[email protected]> Approved-by: CKI KWF Bot <[email protected]> Merged-by: Julio Faracco <[email protected]>
2 parents 09a0a90 + 7f2ec19 commit 2322488

File tree

7 files changed

+153
-33
lines changed

7 files changed

+153
-33
lines changed

drivers/md/dm-bufio.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@
6868
#define LIST_DIRTY 1
6969
#define LIST_SIZE 2
7070

71+
#define SCAN_RESCHED_CYCLE 16
72+
7173
/*--------------------------------------------------------------*/
7274

7375
/*
@@ -2426,7 +2428,12 @@ static void __scan(struct dm_bufio_client *c)
24262428

24272429
atomic_long_dec(&c->need_shrink);
24282430
freed++;
2429-
cond_resched();
2431+
2432+
if (unlikely(freed % SCAN_RESCHED_CYCLE == 0)) {
2433+
dm_bufio_unlock(c);
2434+
cond_resched();
2435+
dm_bufio_lock(c);
2436+
}
24302437
}
24312438
}
24322439
}

drivers/md/dm-cache-target.c

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,12 @@ struct cache {
406406
mempool_t migration_pool;
407407

408408
struct bio_set bs;
409+
410+
/*
411+
* Cache_size entries. Set bits indicate blocks mapped beyond the
412+
* target length, which are marked for invalidation.
413+
*/
414+
unsigned long *invalid_bitset;
409415
};
410416

411417
struct per_bio_data {
@@ -1922,6 +1928,9 @@ static void __destroy(struct cache *cache)
19221928
if (cache->discard_bitset)
19231929
free_bitset(cache->discard_bitset);
19241930

1931+
if (cache->invalid_bitset)
1932+
free_bitset(cache->invalid_bitset);
1933+
19251934
if (cache->copier)
19261935
dm_kcopyd_client_destroy(cache->copier);
19271936

@@ -2510,6 +2519,13 @@ static int cache_create(struct cache_args *ca, struct cache **result)
25102519
}
25112520
clear_bitset(cache->discard_bitset, from_dblock(cache->discard_nr_blocks));
25122521

2522+
cache->invalid_bitset = alloc_bitset(from_cblock(cache->cache_size));
2523+
if (!cache->invalid_bitset) {
2524+
*error = "could not allocate bitset for invalid blocks";
2525+
goto bad;
2526+
}
2527+
clear_bitset(cache->invalid_bitset, from_cblock(cache->cache_size));
2528+
25132529
cache->copier = dm_kcopyd_client_create(&dm_kcopyd_throttle);
25142530
if (IS_ERR(cache->copier)) {
25152531
*error = "could not create kcopyd client";
@@ -2808,6 +2824,24 @@ static int load_mapping(void *context, dm_oblock_t oblock, dm_cblock_t cblock,
28082824
return policy_load_mapping(cache->policy, oblock, cblock, dirty, hint, hint_valid);
28092825
}
28102826

2827+
static int load_filtered_mapping(void *context, dm_oblock_t oblock, dm_cblock_t cblock,
2828+
bool dirty, uint32_t hint, bool hint_valid)
2829+
{
2830+
struct cache *cache = context;
2831+
2832+
if (from_oblock(oblock) >= from_oblock(cache->origin_blocks)) {
2833+
if (dirty) {
2834+
DMERR("%s: unable to shrink origin; cache block %u is dirty",
2835+
cache_device_name(cache), from_cblock(cblock));
2836+
return -EFBIG;
2837+
}
2838+
set_bit(from_cblock(cblock), cache->invalid_bitset);
2839+
return 0;
2840+
}
2841+
2842+
return load_mapping(context, oblock, cblock, dirty, hint, hint_valid);
2843+
}
2844+
28112845
/*
28122846
* The discard block size in the on disk metadata is not
28132847
* necessarily the same as we're currently using. So we have to
@@ -2899,6 +2933,27 @@ static dm_cblock_t get_cache_dev_size(struct cache *cache)
28992933
return to_cblock(size);
29002934
}
29012935

2936+
static bool can_resume(struct cache *cache)
2937+
{
2938+
/*
2939+
* Disallow retrying the resume operation for devices that failed the
2940+
* first resume attempt, as the failure leaves the policy object partially
2941+
* initialized. Retrying could trigger BUG_ON when loading cache mappings
2942+
* into the incomplete policy object.
2943+
*/
2944+
if (cache->sized && !cache->loaded_mappings) {
2945+
if (get_cache_mode(cache) != CM_WRITE)
2946+
DMERR("%s: unable to resume a failed-loaded cache, please check metadata.",
2947+
cache_device_name(cache));
2948+
else
2949+
DMERR("%s: unable to resume cache due to missing proper cache table reload",
2950+
cache_device_name(cache));
2951+
return false;
2952+
}
2953+
2954+
return true;
2955+
}
2956+
29022957
static bool can_resize(struct cache *cache, dm_cblock_t new_size)
29032958
{
29042959
if (from_cblock(new_size) > from_cblock(cache->cache_size)) {
@@ -2941,12 +2996,33 @@ static int resize_cache_dev(struct cache *cache, dm_cblock_t new_size)
29412996
return 0;
29422997
}
29432998

2999+
static int truncate_oblocks(struct cache *cache)
3000+
{
3001+
uint32_t nr_blocks = from_cblock(cache->cache_size);
3002+
uint32_t i;
3003+
int r;
3004+
3005+
for_each_set_bit(i, cache->invalid_bitset, nr_blocks) {
3006+
r = dm_cache_remove_mapping(cache->cmd, to_cblock(i));
3007+
if (r) {
3008+
DMERR_LIMIT("%s: invalidation failed; couldn't update on disk metadata",
3009+
cache_device_name(cache));
3010+
return r;
3011+
}
3012+
}
3013+
3014+
return 0;
3015+
}
3016+
29443017
static int cache_preresume(struct dm_target *ti)
29453018
{
29463019
int r = 0;
29473020
struct cache *cache = ti->private;
29483021
dm_cblock_t csize = get_cache_dev_size(cache);
29493022

3023+
if (!can_resume(cache))
3024+
return -EINVAL;
3025+
29503026
/*
29513027
* Check to see if the cache has resized.
29523028
*/
@@ -2962,11 +3038,25 @@ static int cache_preresume(struct dm_target *ti)
29623038
}
29633039

29643040
if (!cache->loaded_mappings) {
3041+
/*
3042+
* The fast device could have been resized since the last
3043+
* failed preresume attempt. To be safe we start by a blank
3044+
* bitset for cache blocks.
3045+
*/
3046+
clear_bitset(cache->invalid_bitset, from_cblock(cache->cache_size));
3047+
29653048
r = dm_cache_load_mappings(cache->cmd, cache->policy,
2966-
load_mapping, cache);
3049+
load_filtered_mapping, cache);
29673050
if (r) {
29683051
DMERR("%s: could not load cache mappings", cache_device_name(cache));
2969-
metadata_operation_failed(cache, "dm_cache_load_mappings", r);
3052+
if (r != -EFBIG)
3053+
metadata_operation_failed(cache, "dm_cache_load_mappings", r);
3054+
return r;
3055+
}
3056+
3057+
r = truncate_oblocks(cache);
3058+
if (r) {
3059+
metadata_operation_failed(cache, "dm_cache_remove_mapping", r);
29703060
return r;
29713061
}
29723062

@@ -3426,7 +3516,7 @@ static void cache_io_hints(struct dm_target *ti, struct queue_limits *limits)
34263516

34273517
static struct target_type cache_target = {
34283518
.name = "cache",
3429-
.version = {2, 2, 0},
3519+
.version = {2, 3, 0},
34303520
.module = THIS_MODULE,
34313521
.ctr = cache_ctr,
34323522
.dtr = cache_dtr,

drivers/md/dm-ebs-target.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,12 @@ static int ebs_map(struct dm_target *ti, struct bio *bio)
390390
return DM_MAPIO_REMAPPED;
391391
}
392392

393+
static void ebs_postsuspend(struct dm_target *ti)
394+
{
395+
struct ebs_c *ec = ti->private;
396+
dm_bufio_client_reset(ec->bufio);
397+
}
398+
393399
static void ebs_status(struct dm_target *ti, status_type_t type,
394400
unsigned int status_flags, char *result, unsigned int maxlen)
395401
{
@@ -447,6 +453,7 @@ static struct target_type ebs_target = {
447453
.ctr = ebs_ctr,
448454
.dtr = ebs_dtr,
449455
.map = ebs_map,
456+
.postsuspend = ebs_postsuspend,
450457
.status = ebs_status,
451458
.io_hints = ebs_io_hints,
452459
.prepare_ioctl = ebs_prepare_ioctl,

drivers/md/dm-integrity.c

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/reboot.h>
2222
#include <crypto/hash.h>
2323
#include <crypto/skcipher.h>
24+
#include <crypto/utils.h>
2425
#include <linux/async_tx.h>
2526
#include <linux/dm-bufio.h>
2627

@@ -516,7 +517,7 @@ static int sb_mac(struct dm_integrity_c *ic, bool wr)
516517
dm_integrity_io_error(ic, "crypto_shash_digest", r);
517518
return r;
518519
}
519-
if (memcmp(mac, actual_mac, mac_size)) {
520+
if (crypto_memneq(mac, actual_mac, mac_size)) {
520521
dm_integrity_io_error(ic, "superblock mac", -EILSEQ);
521522
dm_audit_log_target(DM_MSG_PREFIX, "mac-superblock", ic->ti, 0);
522523
return -EILSEQ;
@@ -859,7 +860,7 @@ static void rw_section_mac(struct dm_integrity_c *ic, unsigned int section, bool
859860
if (likely(wr))
860861
memcpy(&js->mac, result + (j * JOURNAL_MAC_PER_SECTOR), JOURNAL_MAC_PER_SECTOR);
861862
else {
862-
if (memcmp(&js->mac, result + (j * JOURNAL_MAC_PER_SECTOR), JOURNAL_MAC_PER_SECTOR)) {
863+
if (crypto_memneq(&js->mac, result + (j * JOURNAL_MAC_PER_SECTOR), JOURNAL_MAC_PER_SECTOR)) {
863864
dm_integrity_io_error(ic, "journal mac", -EILSEQ);
864865
dm_audit_log_target(DM_MSG_PREFIX, "mac-journal", ic->ti, 0);
865866
}
@@ -1401,10 +1402,9 @@ static bool find_newer_committed_node(struct dm_integrity_c *ic, struct journal_
14011402
static int dm_integrity_rw_tag(struct dm_integrity_c *ic, unsigned char *tag, sector_t *metadata_block,
14021403
unsigned int *metadata_offset, unsigned int total_size, int op)
14031404
{
1404-
#define MAY_BE_FILLER 1
1405-
#define MAY_BE_HASH 2
14061405
unsigned int hash_offset = 0;
1407-
unsigned int may_be = MAY_BE_HASH | (ic->discard ? MAY_BE_FILLER : 0);
1406+
unsigned char mismatch_hash = 0;
1407+
unsigned char mismatch_filler = !ic->discard;
14081408

14091409
do {
14101410
unsigned char *data, *dp;
@@ -1425,37 +1425,38 @@ static int dm_integrity_rw_tag(struct dm_integrity_c *ic, unsigned char *tag, se
14251425
if (op == TAG_READ) {
14261426
memcpy(tag, dp, to_copy);
14271427
} else if (op == TAG_WRITE) {
1428-
if (memcmp(dp, tag, to_copy)) {
1428+
if (crypto_memneq(dp, tag, to_copy)) {
14291429
memcpy(dp, tag, to_copy);
14301430
dm_bufio_mark_partial_buffer_dirty(b, *metadata_offset, *metadata_offset + to_copy);
14311431
}
14321432
} else {
14331433
/* e.g.: op == TAG_CMP */
14341434

14351435
if (likely(is_power_of_2(ic->tag_size))) {
1436-
if (unlikely(memcmp(dp, tag, to_copy)))
1437-
if (unlikely(!ic->discard) ||
1438-
unlikely(memchr_inv(dp, DISCARD_FILLER, to_copy) != NULL)) {
1439-
goto thorough_test;
1440-
}
1436+
if (unlikely(crypto_memneq(dp, tag, to_copy)))
1437+
goto thorough_test;
14411438
} else {
14421439
unsigned int i, ts;
14431440
thorough_test:
14441441
ts = total_size;
14451442

14461443
for (i = 0; i < to_copy; i++, ts--) {
1447-
if (unlikely(dp[i] != tag[i]))
1448-
may_be &= ~MAY_BE_HASH;
1449-
if (likely(dp[i] != DISCARD_FILLER))
1450-
may_be &= ~MAY_BE_FILLER;
1444+
/*
1445+
* Warning: the control flow must not be
1446+
* dependent on match/mismatch of
1447+
* individual bytes.
1448+
*/
1449+
mismatch_hash |= dp[i] ^ tag[i];
1450+
mismatch_filler |= dp[i] ^ DISCARD_FILLER;
14511451
hash_offset++;
14521452
if (unlikely(hash_offset == ic->tag_size)) {
1453-
if (unlikely(!may_be)) {
1453+
if (unlikely(mismatch_hash) && unlikely(mismatch_filler)) {
14541454
dm_bufio_release(b);
14551455
return ts;
14561456
}
14571457
hash_offset = 0;
1458-
may_be = MAY_BE_HASH | (ic->discard ? MAY_BE_FILLER : 0);
1458+
mismatch_hash = 0;
1459+
mismatch_filler = !ic->discard;
14591460
}
14601461
}
14611462
}
@@ -1476,8 +1477,6 @@ static int dm_integrity_rw_tag(struct dm_integrity_c *ic, unsigned char *tag, se
14761477
} while (unlikely(total_size));
14771478

14781479
return 0;
1479-
#undef MAY_BE_FILLER
1480-
#undef MAY_BE_HASH
14811480
}
14821481

14831482
struct flush_request {
@@ -2076,7 +2075,7 @@ static bool __journal_read_write(struct dm_integrity_io *dio, struct bio *bio,
20762075
char checksums_onstack[MAX_T(size_t, HASH_MAX_DIGESTSIZE, MAX_TAG_SIZE)];
20772076

20782077
integrity_sector_checksum(ic, logical_sector, mem + bv.bv_offset, checksums_onstack);
2079-
if (unlikely(memcmp(checksums_onstack, journal_entry_tag(ic, je), ic->tag_size))) {
2078+
if (unlikely(crypto_memneq(checksums_onstack, journal_entry_tag(ic, je), ic->tag_size))) {
20802079
DMERR_LIMIT("Checksum failed when reading from journal, at sector 0x%llx",
20812080
logical_sector);
20822081
dm_audit_log_bio(DM_MSG_PREFIX, "journal-checksum",
@@ -2595,7 +2594,7 @@ static void dm_integrity_inline_recheck(struct work_struct *w)
25952594
bio_put(outgoing_bio);
25962595

25972596
integrity_sector_checksum(ic, dio->bio_details.bi_iter.bi_sector, outgoing_data, digest);
2598-
if (unlikely(memcmp(digest, dio->integrity_payload, min(crypto_shash_digestsize(ic->internal_hash), ic->tag_size)))) {
2597+
if (unlikely(crypto_memneq(digest, dio->integrity_payload, min(crypto_shash_digestsize(ic->internal_hash), ic->tag_size)))) {
25992598
DMERR_LIMIT("%pg: Checksum failed at sector 0x%llx",
26002599
ic->dev->bdev, dio->bio_details.bi_iter.bi_sector);
26012600
atomic64_inc(&ic->number_of_mismatches);
@@ -2634,7 +2633,7 @@ static int dm_integrity_end_io(struct dm_target *ti, struct bio *bio, blk_status
26342633
char *mem = bvec_kmap_local(&bv);
26352634
//memset(mem, 0xff, ic->sectors_per_block << SECTOR_SHIFT);
26362635
integrity_sector_checksum(ic, dio->bio_details.bi_iter.bi_sector, mem, digest);
2637-
if (unlikely(memcmp(digest, dio->integrity_payload + pos,
2636+
if (unlikely(crypto_memneq(digest, dio->integrity_payload + pos,
26382637
min(crypto_shash_digestsize(ic->internal_hash), ic->tag_size)))) {
26392638
kunmap_local(mem);
26402639
dm_integrity_free_payload(dio);
@@ -2911,7 +2910,7 @@ static void do_journal_write(struct dm_integrity_c *ic, unsigned int write_start
29112910

29122911
integrity_sector_checksum(ic, sec + ((l - j) << ic->sb->log2_sectors_per_block),
29132912
(char *)access_journal_data(ic, i, l), test_tag);
2914-
if (unlikely(memcmp(test_tag, journal_entry_tag(ic, je2), ic->tag_size))) {
2913+
if (unlikely(crypto_memneq(test_tag, journal_entry_tag(ic, je2), ic->tag_size))) {
29152914
dm_integrity_io_error(ic, "tag mismatch when replaying journal", -EILSEQ);
29162915
dm_audit_log_target(DM_MSG_PREFIX, "integrity-replay-journal", ic->ti, 0);
29172916
}
@@ -5084,16 +5083,19 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned int argc, char **argv
50845083

50855084
ic->recalc_bitmap = dm_integrity_alloc_page_list(n_bitmap_pages);
50865085
if (!ic->recalc_bitmap) {
5086+
ti->error = "Could not allocate memory for bitmap";
50875087
r = -ENOMEM;
50885088
goto bad;
50895089
}
50905090
ic->may_write_bitmap = dm_integrity_alloc_page_list(n_bitmap_pages);
50915091
if (!ic->may_write_bitmap) {
5092+
ti->error = "Could not allocate memory for bitmap";
50925093
r = -ENOMEM;
50935094
goto bad;
50945095
}
50955096
ic->bbs = kvmalloc_array(ic->n_bitmap_blocks, sizeof(struct bitmap_block_status), GFP_KERNEL);
50965097
if (!ic->bbs) {
5098+
ti->error = "Could not allocate memory for bitmap";
50975099
r = -ENOMEM;
50985100
goto bad;
50995101
}
@@ -5174,7 +5176,7 @@ static void dm_integrity_dtr(struct dm_target *ti)
51745176
BUG_ON(!RB_EMPTY_ROOT(&ic->in_progress));
51755177
BUG_ON(!list_empty(&ic->wait_list));
51765178

5177-
if (ic->mode == 'B')
5179+
if (ic->mode == 'B' && ic->bitmap_flush_work.work.func)
51785180
cancel_delayed_work_sync(&ic->bitmap_flush_work);
51795181
if (ic->metadata_wq)
51805182
destroy_workqueue(ic->metadata_wq);

drivers/md/dm-table.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -523,8 +523,9 @@ static char **realloc_argv(unsigned int *size, char **old_argv)
523523
gfp = GFP_NOIO;
524524
}
525525
argv = kmalloc_array(new_size, sizeof(*argv), gfp);
526-
if (argv && old_argv) {
527-
memcpy(argv, old_argv, *size * sizeof(*argv));
526+
if (argv) {
527+
if (old_argv)
528+
memcpy(argv, old_argv, *size * sizeof(*argv));
528529
*size = new_size;
529530
}
530531

@@ -1177,7 +1178,7 @@ static int dm_keyslot_evict(struct blk_crypto_profile *profile,
11771178

11781179
t = dm_get_live_table(md, &srcu_idx);
11791180
if (!t)
1180-
return 0;
1181+
goto put_live_table;
11811182

11821183
for (unsigned int i = 0; i < t->num_targets; i++) {
11831184
struct dm_target *ti = dm_table_get_target(t, i);
@@ -1188,6 +1189,7 @@ static int dm_keyslot_evict(struct blk_crypto_profile *profile,
11881189
(void *)key);
11891190
}
11901191

1192+
put_live_table:
11911193
dm_put_live_table(md, srcu_idx);
11921194
return 0;
11931195
}

0 commit comments

Comments
 (0)