@@ -278,6 +278,8 @@ struct dm_integrity_c {
278
278
279
279
atomic64_t number_of_mismatches ;
280
280
281
+ mempool_t recheck_pool ;
282
+
281
283
struct notifier_block reboot_notifier ;
282
284
};
283
285
@@ -1689,6 +1691,79 @@ static void integrity_sector_checksum(struct dm_integrity_c *ic, sector_t sector
1689
1691
get_random_bytes (result , ic -> tag_size );
1690
1692
}
1691
1693
1694
+ static void integrity_recheck (struct dm_integrity_io * dio )
1695
+ {
1696
+ struct bio * bio = dm_bio_from_per_bio_data (dio , sizeof (struct dm_integrity_io ));
1697
+ struct dm_integrity_c * ic = dio -> ic ;
1698
+ struct bvec_iter iter ;
1699
+ struct bio_vec bv ;
1700
+ sector_t sector , logical_sector , area , offset ;
1701
+ char checksum_onstack [max_t (size_t , HASH_MAX_DIGESTSIZE , MAX_TAG_SIZE )];
1702
+ struct page * page ;
1703
+ void * buffer ;
1704
+
1705
+ get_area_and_offset (ic , dio -> range .logical_sector , & area , & offset );
1706
+ dio -> metadata_block = get_metadata_sector_and_offset (ic , area , offset ,
1707
+ & dio -> metadata_offset );
1708
+ sector = get_data_sector (ic , area , offset );
1709
+ logical_sector = dio -> range .logical_sector ;
1710
+
1711
+ page = mempool_alloc (& ic -> recheck_pool , GFP_NOIO );
1712
+ buffer = page_to_virt (page );
1713
+
1714
+ __bio_for_each_segment (bv , bio , iter , dio -> bio_details .bi_iter ) {
1715
+ unsigned pos = 0 ;
1716
+
1717
+ do {
1718
+ char * mem ;
1719
+ int r ;
1720
+ struct dm_io_request io_req ;
1721
+ struct dm_io_region io_loc ;
1722
+ io_req .bi_opf = REQ_OP_READ ;
1723
+ io_req .mem .type = DM_IO_KMEM ;
1724
+ io_req .mem .ptr .addr = buffer ;
1725
+ io_req .notify .fn = NULL ;
1726
+ io_req .client = ic -> io ;
1727
+ io_loc .bdev = ic -> dev -> bdev ;
1728
+ io_loc .sector = sector ;
1729
+ io_loc .count = ic -> sectors_per_block ;
1730
+
1731
+ r = dm_io (& io_req , 1 , & io_loc , NULL );
1732
+ if (unlikely (r )) {
1733
+ dio -> bi_status = errno_to_blk_status (r );
1734
+ goto free_ret ;
1735
+ }
1736
+
1737
+ integrity_sector_checksum (ic , logical_sector , buffer ,
1738
+ checksum_onstack );
1739
+ r = dm_integrity_rw_tag (ic , checksum_onstack , & dio -> metadata_block ,
1740
+ & dio -> metadata_offset , ic -> tag_size , TAG_CMP );
1741
+ if (r ) {
1742
+ if (r > 0 ) {
1743
+ DMERR_LIMIT ("%pg: Checksum failed at sector 0x%llx" ,
1744
+ bio -> bi_bdev , logical_sector );
1745
+ atomic64_inc (& ic -> number_of_mismatches );
1746
+ dm_audit_log_bio (DM_MSG_PREFIX , "integrity-checksum" ,
1747
+ bio , logical_sector , 0 );
1748
+ r = - EILSEQ ;
1749
+ }
1750
+ dio -> bi_status = errno_to_blk_status (r );
1751
+ goto free_ret ;
1752
+ }
1753
+
1754
+ mem = bvec_kmap_local (& bv );
1755
+ memcpy (mem + pos , buffer , ic -> sectors_per_block << SECTOR_SHIFT );
1756
+ kunmap_local (mem );
1757
+
1758
+ pos += ic -> sectors_per_block << SECTOR_SHIFT ;
1759
+ sector += ic -> sectors_per_block ;
1760
+ logical_sector += ic -> sectors_per_block ;
1761
+ } while (pos < bv .bv_len );
1762
+ }
1763
+ free_ret :
1764
+ mempool_free (page , & ic -> recheck_pool );
1765
+ }
1766
+
1692
1767
static void integrity_metadata (struct work_struct * w )
1693
1768
{
1694
1769
struct dm_integrity_io * dio = container_of (w , struct dm_integrity_io , work );
@@ -1776,15 +1851,8 @@ static void integrity_metadata(struct work_struct *w)
1776
1851
checksums_ptr - checksums , dio -> op == REQ_OP_READ ? TAG_CMP : TAG_WRITE );
1777
1852
if (unlikely (r )) {
1778
1853
if (r > 0 ) {
1779
- sector_t s ;
1780
-
1781
- s = sector - ((r + ic -> tag_size - 1 ) / ic -> tag_size );
1782
- DMERR_LIMIT ("%pg: Checksum failed at sector 0x%llx" ,
1783
- bio -> bi_bdev , s );
1784
- r = - EILSEQ ;
1785
- atomic64_inc (& ic -> number_of_mismatches );
1786
- dm_audit_log_bio (DM_MSG_PREFIX , "integrity-checksum" ,
1787
- bio , s , 0 );
1854
+ integrity_recheck (dio );
1855
+ goto skip_io ;
1788
1856
}
1789
1857
if (likely (checksums != checksums_onstack ))
1790
1858
kfree (checksums );
@@ -4261,6 +4329,12 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned int argc, char **argv
4261
4329
goto bad ;
4262
4330
}
4263
4331
4332
+ r = mempool_init_page_pool (& ic -> recheck_pool , 1 , 0 );
4333
+ if (r ) {
4334
+ ti -> error = "Cannot allocate mempool" ;
4335
+ goto bad ;
4336
+ }
4337
+
4264
4338
ic -> metadata_wq = alloc_workqueue ("dm-integrity-metadata" ,
4265
4339
WQ_MEM_RECLAIM , METADATA_WORKQUEUE_MAX_ACTIVE );
4266
4340
if (!ic -> metadata_wq ) {
@@ -4609,6 +4683,7 @@ static void dm_integrity_dtr(struct dm_target *ti)
4609
4683
kvfree (ic -> bbs );
4610
4684
if (ic -> bufio )
4611
4685
dm_bufio_client_destroy (ic -> bufio );
4686
+ mempool_exit (& ic -> recheck_pool );
4612
4687
mempool_exit (& ic -> journal_io_mempool );
4613
4688
if (ic -> io )
4614
4689
dm_io_client_destroy (ic -> io );
0 commit comments