Skip to content

Commit e3de0a3

Browse files
author
Mikulas Patocka
committed
dm-integrity: add the "offset" argument
Make sure that the "data" argument passed to integrity_sector_checksum is always page-aligned and add an "offset" argument that specifies the offset from the start of the page. This will enable us to use the asynchronous hash interface later. Signed-off-by: Mikulas Patocka <[email protected]>
1 parent e7151e2 commit e3de0a3

File tree

1 file changed

+35
-14
lines changed

1 file changed

+35
-14
lines changed

drivers/md/dm-integrity.c

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1636,7 +1636,7 @@ static void integrity_end_io(struct bio *bio)
16361636
}
16371637

16381638
static void integrity_sector_checksum(struct dm_integrity_c *ic, sector_t sector,
1639-
const char *data, char *result)
1639+
const char *data, unsigned offset, char *result)
16401640
{
16411641
__le64 sector_le = cpu_to_le64(sector);
16421642
SHASH_DESC_ON_STACK(req, ic->internal_hash);
@@ -1665,7 +1665,7 @@ static void integrity_sector_checksum(struct dm_integrity_c *ic, sector_t sector
16651665
goto failed;
16661666
}
16671667

1668-
r = crypto_shash_update(req, data, ic->sectors_per_block << SECTOR_SHIFT);
1668+
r = crypto_shash_update(req, data + offset, ic->sectors_per_block << SECTOR_SHIFT);
16691669
if (unlikely(r < 0)) {
16701670
dm_integrity_io_error(ic, "crypto_shash_update", r);
16711671
goto failed;
@@ -1698,6 +1698,15 @@ static void integrity_kunmap(struct dm_integrity_c *ic, const void *ptr)
16981698
kunmap_local(ptr);
16991699
}
17001700

1701+
static void *integrity_identity(struct dm_integrity_c *ic, void *data)
1702+
{
1703+
#ifdef CONFIG_DEBUG_SG
1704+
BUG_ON(offset_in_page(data));
1705+
BUG_ON(!virt_addr_valid(data));
1706+
#endif
1707+
return data;
1708+
}
1709+
17011710
static noinline void integrity_recheck(struct dm_integrity_io *dio, char *checksum)
17021711
{
17031712
struct bio *bio = dm_bio_from_per_bio_data(dio, sizeof(struct dm_integrity_io));
@@ -1722,6 +1731,7 @@ static noinline void integrity_recheck(struct dm_integrity_io *dio, char *checks
17221731
sector_t alignment;
17231732
char *mem;
17241733
char *buffer = page_to_virt(page);
1734+
unsigned int buffer_offset;
17251735
int r;
17261736
struct dm_io_request io_req;
17271737
struct dm_io_region io_loc;
@@ -1739,7 +1749,7 @@ static noinline void integrity_recheck(struct dm_integrity_io *dio, char *checks
17391749
alignment &= -alignment;
17401750
io_loc.sector = round_down(io_loc.sector, alignment);
17411751
io_loc.count += sector - io_loc.sector;
1742-
buffer += (sector - io_loc.sector) << SECTOR_SHIFT;
1752+
buffer_offset = (sector - io_loc.sector) << SECTOR_SHIFT;
17431753
io_loc.count = round_up(io_loc.count, alignment);
17441754

17451755
r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT);
@@ -1748,7 +1758,7 @@ static noinline void integrity_recheck(struct dm_integrity_io *dio, char *checks
17481758
goto free_ret;
17491759
}
17501760

1751-
integrity_sector_checksum(ic, logical_sector, buffer, checksum);
1761+
integrity_sector_checksum(ic, logical_sector, integrity_identity(ic, buffer), buffer_offset, checksum);
17521762
r = dm_integrity_rw_tag(ic, checksum, &dio->metadata_block,
17531763
&dio->metadata_offset, ic->tag_size, TAG_CMP);
17541764
if (r) {
@@ -1765,7 +1775,7 @@ static noinline void integrity_recheck(struct dm_integrity_io *dio, char *checks
17651775
}
17661776

17671777
mem = bvec_kmap_local(&bv);
1768-
memcpy(mem + pos, buffer, ic->sectors_per_block << SECTOR_SHIFT);
1778+
memcpy(mem + pos, buffer + buffer_offset, ic->sectors_per_block << SECTOR_SHIFT);
17691779
kunmap_local(mem);
17701780

17711781
pos += ic->sectors_per_block << SECTOR_SHIFT;
@@ -1852,7 +1862,7 @@ static void integrity_metadata(struct work_struct *w)
18521862
pos = 0;
18531863
checksums_ptr = checksums;
18541864
do {
1855-
integrity_sector_checksum(ic, sector, mem + bv_copy.bv_offset + pos, checksums_ptr);
1865+
integrity_sector_checksum(ic, sector, mem, bv_copy.bv_offset + pos, checksums_ptr);
18561866
checksums_ptr += ic->tag_size;
18571867
sectors_to_process -= ic->sectors_per_block;
18581868
pos += ic->sectors_per_block << SECTOR_SHIFT;
@@ -2123,14 +2133,16 @@ static bool __journal_read_write(struct dm_integrity_io *dio, struct bio *bio,
21232133

21242134
if (ic->internal_hash) {
21252135
unsigned int digest_size = ic->internal_hash_digestsize;
2136+
void *js_page = integrity_identity(ic, (char *)js - offset_in_page(js));
2137+
unsigned js_offset = offset_in_page(js);
21262138

21272139
if (unlikely(digest_size > ic->tag_size)) {
21282140
char checksums_onstack[HASH_MAX_DIGESTSIZE];
21292141

2130-
integrity_sector_checksum(ic, logical_sector, (char *)js, checksums_onstack);
2142+
integrity_sector_checksum(ic, logical_sector, js_page, js_offset, checksums_onstack);
21312143
memcpy(journal_entry_tag(ic, je), checksums_onstack, ic->tag_size);
21322144
} else
2133-
integrity_sector_checksum(ic, logical_sector, (char *)js, journal_entry_tag(ic, je));
2145+
integrity_sector_checksum(ic, logical_sector, js_page, js_offset, journal_entry_tag(ic, je));
21342146
}
21352147

21362148
journal_entry_set_sector(je, logical_sector);
@@ -2506,7 +2518,7 @@ static int dm_integrity_map_inline(struct dm_integrity_io *dio, bool from_map)
25062518
const char *mem = integrity_kmap(ic, bv.bv_page);
25072519
if (ic->tag_size < ic->tuple_size)
25082520
memset(dio->integrity_payload + pos + ic->tag_size, 0, ic->tuple_size - ic->tuple_size);
2509-
integrity_sector_checksum(ic, dio->bio_details.bi_iter.bi_sector, mem + bv.bv_offset, dio->integrity_payload + pos);
2521+
integrity_sector_checksum(ic, dio->bio_details.bi_iter.bi_sector, mem, bv.bv_offset, dio->integrity_payload + pos);
25102522
integrity_kunmap(ic, mem);
25112523
pos += ic->tuple_size;
25122524
bio_advance_iter_single(bio, &dio->bio_details.bi_iter, ic->sectors_per_block << SECTOR_SHIFT);
@@ -2586,7 +2598,7 @@ static void dm_integrity_inline_recheck(struct work_struct *w)
25862598
}
25872599
bio_put(outgoing_bio);
25882600

2589-
integrity_sector_checksum(ic, dio->bio_details.bi_iter.bi_sector, outgoing_data, digest);
2601+
integrity_sector_checksum(ic, dio->bio_details.bi_iter.bi_sector, integrity_identity(ic, outgoing_data), 0, digest);
25902602
if (unlikely(crypto_memneq(digest, dio->integrity_payload, min(ic->internal_hash_digestsize, ic->tag_size)))) {
25912603
DMERR_LIMIT("%pg: Checksum failed at sector 0x%llx",
25922604
ic->dev->bdev, dio->bio_details.bi_iter.bi_sector);
@@ -2624,7 +2636,7 @@ static int dm_integrity_end_io(struct dm_target *ti, struct bio *bio, blk_status
26242636
char digest[HASH_MAX_DIGESTSIZE];
26252637
struct bio_vec bv = bio_iter_iovec(bio, dio->bio_details.bi_iter);
26262638
char *mem = integrity_kmap(ic, bv.bv_page);
2627-
integrity_sector_checksum(ic, dio->bio_details.bi_iter.bi_sector, mem + bv.bv_offset, digest);
2639+
integrity_sector_checksum(ic, dio->bio_details.bi_iter.bi_sector, mem, bv.bv_offset, digest);
26282640
if (unlikely(crypto_memneq(digest, dio->integrity_payload + pos,
26292641
min(ic->internal_hash_digestsize, ic->tag_size)))) {
26302642
integrity_kunmap(ic, mem);
@@ -2899,9 +2911,12 @@ static void do_journal_write(struct dm_integrity_c *ic, unsigned int write_start
28992911
#endif
29002912
ic->internal_hash) {
29012913
char test_tag[MAX_T(size_t, HASH_MAX_DIGESTSIZE, MAX_TAG_SIZE)];
2914+
struct journal_sector *js = access_journal_data(ic, i, l);
2915+
void *js_page = integrity_identity(ic, (char *)js - offset_in_page(js));
2916+
unsigned js_offset = offset_in_page(js);
29022917

29032918
integrity_sector_checksum(ic, sec + ((l - j) << ic->sb->log2_sectors_per_block),
2904-
(char *)access_journal_data(ic, i, l), test_tag);
2919+
js_page, js_offset, test_tag);
29052920
if (unlikely(crypto_memneq(test_tag, journal_entry_tag(ic, je2), ic->tag_size))) {
29062921
dm_integrity_io_error(ic, "tag mismatch when replaying journal", -EILSEQ);
29072922
dm_audit_log_target(DM_MSG_PREFIX, "integrity-replay-journal", ic->ti, 0);
@@ -3094,7 +3109,10 @@ static void integrity_recalc(struct work_struct *w)
30943109

30953110
t = recalc_tags;
30963111
for (i = 0; i < n_sectors; i += ic->sectors_per_block) {
3097-
integrity_sector_checksum(ic, logical_sector + i, recalc_buffer + (i << SECTOR_SHIFT), t);
3112+
void *ptr = recalc_buffer + (i << SECTOR_SHIFT);
3113+
void *ptr_page = integrity_identity(ic, (char *)ptr - offset_in_page(ptr));
3114+
unsigned ptr_offset = offset_in_page(ptr);
3115+
integrity_sector_checksum(ic, logical_sector + i, ptr_page, ptr_offset, t);
30983116
t += ic->tag_size;
30993117
}
31003118

@@ -3214,8 +3232,11 @@ static void integrity_recalc_inline(struct work_struct *w)
32143232

32153233
t = recalc_tags;
32163234
for (i = 0; i < range.n_sectors; i += ic->sectors_per_block) {
3235+
void *ptr = recalc_buffer + (i << SECTOR_SHIFT);
3236+
void *ptr_page = integrity_identity(ic, (char *)ptr - offset_in_page(ptr));
3237+
unsigned ptr_offset = offset_in_page(ptr);
32173238
memset(t, 0, ic->tuple_size);
3218-
integrity_sector_checksum(ic, range.logical_sector + i, recalc_buffer + (i << SECTOR_SHIFT), t);
3239+
integrity_sector_checksum(ic, range.logical_sector + i, ptr_page, ptr_offset, t);
32193240
t += ic->tuple_size;
32203241
}
32213242

0 commit comments

Comments
 (0)