@@ -482,6 +482,63 @@ int verity_for_bv_block(struct dm_verity *v, struct dm_verity_io *io,
482482 return 0 ;
483483}
484484
485+ static int verity_recheck_copy (struct dm_verity * v , struct dm_verity_io * io ,
486+ u8 * data , size_t len )
487+ {
488+ memcpy (data , io -> recheck_buffer , len );
489+ io -> recheck_buffer += len ;
490+
491+ return 0 ;
492+ }
493+
494+ static int verity_recheck (struct dm_verity * v , struct dm_verity_io * io ,
495+ struct bvec_iter start , sector_t cur_block )
496+ {
497+ struct page * page ;
498+ void * buffer ;
499+ int r ;
500+ struct dm_io_request io_req ;
501+ struct dm_io_region io_loc ;
502+
503+ page = mempool_alloc (& v -> recheck_pool , GFP_NOIO );
504+ buffer = page_to_virt (page );
505+
506+ io_req .bi_opf = REQ_OP_READ ;
507+ io_req .mem .type = DM_IO_KMEM ;
508+ io_req .mem .ptr .addr = buffer ;
509+ io_req .notify .fn = NULL ;
510+ io_req .client = v -> io ;
511+ io_loc .bdev = v -> data_dev -> bdev ;
512+ io_loc .sector = cur_block << (v -> data_dev_block_bits - SECTOR_SHIFT );
513+ io_loc .count = 1 << (v -> data_dev_block_bits - SECTOR_SHIFT );
514+ r = dm_io (& io_req , 1 , & io_loc , NULL );
515+ if (unlikely (r ))
516+ goto free_ret ;
517+
518+ r = verity_hash (v , verity_io_hash_req (v , io ), buffer ,
519+ 1 << v -> data_dev_block_bits ,
520+ verity_io_real_digest (v , io ), true);
521+ if (unlikely (r ))
522+ goto free_ret ;
523+
524+ if (memcmp (verity_io_real_digest (v , io ),
525+ verity_io_want_digest (v , io ), v -> digest_size )) {
526+ r = - EIO ;
527+ goto free_ret ;
528+ }
529+
530+ io -> recheck_buffer = buffer ;
531+ r = verity_for_bv_block (v , io , & start , verity_recheck_copy );
532+ if (unlikely (r ))
533+ goto free_ret ;
534+
535+ r = 0 ;
536+ free_ret :
537+ mempool_free (page , & v -> recheck_pool );
538+
539+ return r ;
540+ }
541+
485542static int verity_bv_zero (struct dm_verity * v , struct dm_verity_io * io ,
486543 u8 * data , size_t len )
487544{
@@ -508,9 +565,7 @@ static int verity_verify_io(struct dm_verity_io *io)
508565{
509566 bool is_zero ;
510567 struct dm_verity * v = io -> v ;
511- #if defined(CONFIG_DM_VERITY_FEC )
512568 struct bvec_iter start ;
513- #endif
514569 struct bvec_iter iter_copy ;
515570 struct bvec_iter * iter ;
516571 struct crypto_wait wait ;
@@ -561,10 +616,7 @@ static int verity_verify_io(struct dm_verity_io *io)
561616 if (unlikely (r < 0 ))
562617 return r ;
563618
564- #if defined(CONFIG_DM_VERITY_FEC )
565- if (verity_fec_is_enabled (v ))
566- start = * iter ;
567- #endif
619+ start = * iter ;
568620 r = verity_for_io_block (v , io , iter , & wait );
569621 if (unlikely (r < 0 ))
570622 return r ;
@@ -586,6 +638,10 @@ static int verity_verify_io(struct dm_verity_io *io)
586638 * tasklet since it may sleep, so fallback to work-queue.
587639 */
588640 return - EAGAIN ;
641+ } else if (verity_recheck (v , io , start , cur_block ) == 0 ) {
642+ if (v -> validated_blocks )
643+ set_bit (cur_block , v -> validated_blocks );
644+ continue ;
589645#if defined(CONFIG_DM_VERITY_FEC )
590646 } else if (verity_fec_decode (v , io , DM_VERITY_BLOCK_TYPE_DATA ,
591647 cur_block , NULL , & start ) == 0 ) {
@@ -941,6 +997,10 @@ static void verity_dtr(struct dm_target *ti)
941997 if (v -> verify_wq )
942998 destroy_workqueue (v -> verify_wq );
943999
1000+ mempool_exit (& v -> recheck_pool );
1001+ if (v -> io )
1002+ dm_io_client_destroy (v -> io );
1003+
9441004 if (v -> bufio )
9451005 dm_bufio_client_destroy (v -> bufio );
9461006
@@ -1379,6 +1439,20 @@ static int verity_ctr(struct dm_target *ti, unsigned int argc, char **argv)
13791439 }
13801440 v -> hash_blocks = hash_position ;
13811441
1442+ r = mempool_init_page_pool (& v -> recheck_pool , 1 , 0 );
1443+ if (unlikely (r )) {
1444+ ti -> error = "Cannot allocate mempool" ;
1445+ goto bad ;
1446+ }
1447+
1448+ v -> io = dm_io_client_create ();
1449+ if (IS_ERR (v -> io )) {
1450+ r = PTR_ERR (v -> io );
1451+ v -> io = NULL ;
1452+ ti -> error = "Cannot allocate dm io" ;
1453+ goto bad ;
1454+ }
1455+
13821456 v -> bufio = dm_bufio_client_create (v -> hash_dev -> bdev ,
13831457 1 << v -> hash_dev_block_bits , 1 , sizeof (struct buffer_aux ),
13841458 dm_bufio_alloc_callback , NULL ,
0 commit comments