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.

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 <mpatocka@redhat.com>

+35 -14
+35 -14
drivers/md/dm-integrity.c
··· 1636 1636 } 1637 1637 1638 1638 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) 1640 1640 { 1641 1641 __le64 sector_le = cpu_to_le64(sector); 1642 1642 SHASH_DESC_ON_STACK(req, ic->internal_hash); ··· 1665 1665 goto failed; 1666 1666 } 1667 1667 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); 1669 1669 if (unlikely(r < 0)) { 1670 1670 dm_integrity_io_error(ic, "crypto_shash_update", r); 1671 1671 goto failed; ··· 1698 1698 kunmap_local(ptr); 1699 1699 } 1700 1700 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 + 1701 1710 static noinline void integrity_recheck(struct dm_integrity_io *dio, char *checksum) 1702 1711 { 1703 1712 struct bio *bio = dm_bio_from_per_bio_data(dio, sizeof(struct dm_integrity_io)); ··· 1731 1722 sector_t alignment; 1732 1723 char *mem; 1733 1724 char *buffer = page_to_virt(page); 1725 + unsigned int buffer_offset; 1734 1726 int r; 1735 1727 struct dm_io_request io_req; 1736 1728 struct dm_io_region io_loc; ··· 1749 1739 alignment &= -alignment; 1750 1740 io_loc.sector = round_down(io_loc.sector, alignment); 1751 1741 io_loc.count += sector - io_loc.sector; 1752 - buffer += (sector - io_loc.sector) << SECTOR_SHIFT; 1742 + buffer_offset = (sector - io_loc.sector) << SECTOR_SHIFT; 1753 1743 io_loc.count = round_up(io_loc.count, alignment); 1754 1744 1755 1745 r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT); ··· 1758 1748 goto free_ret; 1759 1749 } 1760 1750 1761 - integrity_sector_checksum(ic, logical_sector, buffer, checksum); 1751 + integrity_sector_checksum(ic, logical_sector, integrity_identity(ic, buffer), buffer_offset, checksum); 1762 1752 r = dm_integrity_rw_tag(ic, checksum, &dio->metadata_block, 1763 1753 &dio->metadata_offset, ic->tag_size, TAG_CMP); 1764 1754 if (r) { ··· 1775 1765 } 1776 1766 1777 1767 mem = bvec_kmap_local(&bv); 1778 - memcpy(mem + pos, buffer, ic->sectors_per_block << SECTOR_SHIFT); 1768 + memcpy(mem + pos, buffer + buffer_offset, ic->sectors_per_block << SECTOR_SHIFT); 1779 1769 kunmap_local(mem); 1780 1770 1781 1771 pos += ic->sectors_per_block << SECTOR_SHIFT; ··· 1862 1852 pos = 0; 1863 1853 checksums_ptr = checksums; 1864 1854 do { 1865 - integrity_sector_checksum(ic, sector, mem + bv_copy.bv_offset + pos, checksums_ptr); 1855 + integrity_sector_checksum(ic, sector, mem, bv_copy.bv_offset + pos, checksums_ptr); 1866 1856 checksums_ptr += ic->tag_size; 1867 1857 sectors_to_process -= ic->sectors_per_block; 1868 1858 pos += ic->sectors_per_block << SECTOR_SHIFT; ··· 2133 2123 2134 2124 if (ic->internal_hash) { 2135 2125 unsigned int digest_size = ic->internal_hash_digestsize; 2126 + void *js_page = integrity_identity(ic, (char *)js - offset_in_page(js)); 2127 + unsigned js_offset = offset_in_page(js); 2136 2128 2137 2129 if (unlikely(digest_size > ic->tag_size)) { 2138 2130 char checksums_onstack[HASH_MAX_DIGESTSIZE]; 2139 2131 2140 - integrity_sector_checksum(ic, logical_sector, (char *)js, checksums_onstack); 2132 + integrity_sector_checksum(ic, logical_sector, js_page, js_offset, checksums_onstack); 2141 2133 memcpy(journal_entry_tag(ic, je), checksums_onstack, ic->tag_size); 2142 2134 } else 2143 - integrity_sector_checksum(ic, logical_sector, (char *)js, journal_entry_tag(ic, je)); 2135 + integrity_sector_checksum(ic, logical_sector, js_page, js_offset, journal_entry_tag(ic, je)); 2144 2136 } 2145 2137 2146 2138 journal_entry_set_sector(je, logical_sector); ··· 2518 2506 const char *mem = integrity_kmap(ic, bv.bv_page); 2519 2507 if (ic->tag_size < ic->tuple_size) 2520 2508 memset(dio->integrity_payload + pos + ic->tag_size, 0, ic->tuple_size - ic->tuple_size); 2521 - integrity_sector_checksum(ic, dio->bio_details.bi_iter.bi_sector, mem + bv.bv_offset, dio->integrity_payload + pos); 2509 + integrity_sector_checksum(ic, dio->bio_details.bi_iter.bi_sector, mem, bv.bv_offset, dio->integrity_payload + pos); 2522 2510 integrity_kunmap(ic, mem); 2523 2511 pos += ic->tuple_size; 2524 2512 bio_advance_iter_single(bio, &dio->bio_details.bi_iter, ic->sectors_per_block << SECTOR_SHIFT); ··· 2598 2586 } 2599 2587 bio_put(outgoing_bio); 2600 2588 2601 - integrity_sector_checksum(ic, dio->bio_details.bi_iter.bi_sector, outgoing_data, digest); 2589 + integrity_sector_checksum(ic, dio->bio_details.bi_iter.bi_sector, integrity_identity(ic, outgoing_data), 0, digest); 2602 2590 if (unlikely(crypto_memneq(digest, dio->integrity_payload, min(ic->internal_hash_digestsize, ic->tag_size)))) { 2603 2591 DMERR_LIMIT("%pg: Checksum failed at sector 0x%llx", 2604 2592 ic->dev->bdev, dio->bio_details.bi_iter.bi_sector); ··· 2636 2624 char digest[HASH_MAX_DIGESTSIZE]; 2637 2625 struct bio_vec bv = bio_iter_iovec(bio, dio->bio_details.bi_iter); 2638 2626 char *mem = integrity_kmap(ic, bv.bv_page); 2639 - integrity_sector_checksum(ic, dio->bio_details.bi_iter.bi_sector, mem + bv.bv_offset, digest); 2627 + integrity_sector_checksum(ic, dio->bio_details.bi_iter.bi_sector, mem, bv.bv_offset, digest); 2640 2628 if (unlikely(crypto_memneq(digest, dio->integrity_payload + pos, 2641 2629 min(ic->internal_hash_digestsize, ic->tag_size)))) { 2642 2630 integrity_kunmap(ic, mem); ··· 2911 2899 #endif 2912 2900 ic->internal_hash) { 2913 2901 char test_tag[MAX_T(size_t, HASH_MAX_DIGESTSIZE, MAX_TAG_SIZE)]; 2902 + struct journal_sector *js = access_journal_data(ic, i, l); 2903 + void *js_page = integrity_identity(ic, (char *)js - offset_in_page(js)); 2904 + unsigned js_offset = offset_in_page(js); 2914 2905 2915 2906 integrity_sector_checksum(ic, sec + ((l - j) << ic->sb->log2_sectors_per_block), 2916 - (char *)access_journal_data(ic, i, l), test_tag); 2907 + js_page, js_offset, test_tag); 2917 2908 if (unlikely(crypto_memneq(test_tag, journal_entry_tag(ic, je2), ic->tag_size))) { 2918 2909 dm_integrity_io_error(ic, "tag mismatch when replaying journal", -EILSEQ); 2919 2910 dm_audit_log_target(DM_MSG_PREFIX, "integrity-replay-journal", ic->ti, 0); ··· 3109 3094 3110 3095 t = recalc_tags; 3111 3096 for (i = 0; i < n_sectors; i += ic->sectors_per_block) { 3112 - integrity_sector_checksum(ic, logical_sector + i, recalc_buffer + (i << SECTOR_SHIFT), t); 3097 + void *ptr = recalc_buffer + (i << SECTOR_SHIFT); 3098 + void *ptr_page = integrity_identity(ic, (char *)ptr - offset_in_page(ptr)); 3099 + unsigned ptr_offset = offset_in_page(ptr); 3100 + integrity_sector_checksum(ic, logical_sector + i, ptr_page, ptr_offset, t); 3113 3101 t += ic->tag_size; 3114 3102 } 3115 3103 ··· 3232 3214 3233 3215 t = recalc_tags; 3234 3216 for (i = 0; i < range.n_sectors; i += ic->sectors_per_block) { 3217 + void *ptr = recalc_buffer + (i << SECTOR_SHIFT); 3218 + void *ptr_page = integrity_identity(ic, (char *)ptr - offset_in_page(ptr)); 3219 + unsigned ptr_offset = offset_in_page(ptr); 3235 3220 memset(t, 0, ic->tuple_size); 3236 - integrity_sector_checksum(ic, range.logical_sector + i, recalc_buffer + (i << SECTOR_SHIFT), t); 3221 + integrity_sector_checksum(ic, range.logical_sector + i, ptr_page, ptr_offset, t); 3237 3222 t += ic->tuple_size; 3238 3223 } 3239 3224