@@ -1636,7 +1636,7 @@ static void integrity_end_io(struct bio *bio)
16361636}
16371637
16381638static 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+
17011710static 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