@@ -251,8 +251,6 @@ struct dm_integrity_c {
251251
252252 struct workqueue_struct * recalc_wq ;
253253 struct work_struct recalc_work ;
254- u8 * recalc_buffer ;
255- u8 * recalc_tags ;
256254
257255 struct bio_list flush_bio_list ;
258256
@@ -2646,6 +2644,9 @@ static void recalc_write_super(struct dm_integrity_c *ic)
26462644static void integrity_recalc (struct work_struct * w )
26472645{
26482646 struct dm_integrity_c * ic = container_of (w , struct dm_integrity_c , recalc_work );
2647+ size_t recalc_tags_size ;
2648+ u8 * recalc_buffer = NULL ;
2649+ u8 * recalc_tags = NULL ;
26492650 struct dm_integrity_range range ;
26502651 struct dm_io_request io_req ;
26512652 struct dm_io_region io_loc ;
@@ -2658,6 +2659,20 @@ static void integrity_recalc(struct work_struct *w)
26582659 int r ;
26592660 unsigned int super_counter = 0 ;
26602661
2662+ recalc_buffer = __vmalloc (RECALC_SECTORS << SECTOR_SHIFT , GFP_NOIO );
2663+ if (!recalc_buffer ) {
2664+ DMCRIT ("out of memory for recalculate buffer - recalculation disabled" );
2665+ goto free_ret ;
2666+ }
2667+ recalc_tags_size = (RECALC_SECTORS >> ic -> sb -> log2_sectors_per_block ) * ic -> tag_size ;
2668+ if (crypto_shash_digestsize (ic -> internal_hash ) > ic -> tag_size )
2669+ recalc_tags_size += crypto_shash_digestsize (ic -> internal_hash ) - ic -> tag_size ;
2670+ recalc_tags = kvmalloc (recalc_tags_size , GFP_NOIO );
2671+ if (!recalc_tags ) {
2672+ DMCRIT ("out of memory for recalculate buffer - recalculation disabled" );
2673+ goto free_ret ;
2674+ }
2675+
26612676 DEBUG_print ("start recalculation... (position %llx)\n" , le64_to_cpu (ic -> sb -> recalc_sector ));
26622677
26632678 spin_lock_irq (& ic -> endio_wait .lock );
@@ -2720,7 +2735,7 @@ static void integrity_recalc(struct work_struct *w)
27202735
27212736 io_req .bi_opf = REQ_OP_READ ;
27222737 io_req .mem .type = DM_IO_VMA ;
2723- io_req .mem .ptr .addr = ic -> recalc_buffer ;
2738+ io_req .mem .ptr .addr = recalc_buffer ;
27242739 io_req .notify .fn = NULL ;
27252740 io_req .client = ic -> io ;
27262741 io_loc .bdev = ic -> dev -> bdev ;
@@ -2733,15 +2748,15 @@ static void integrity_recalc(struct work_struct *w)
27332748 goto err ;
27342749 }
27352750
2736- t = ic -> recalc_tags ;
2751+ t = recalc_tags ;
27372752 for (i = 0 ; i < n_sectors ; i += ic -> sectors_per_block ) {
2738- integrity_sector_checksum (ic , logical_sector + i , ic -> recalc_buffer + (i << SECTOR_SHIFT ), t );
2753+ integrity_sector_checksum (ic , logical_sector + i , recalc_buffer + (i << SECTOR_SHIFT ), t );
27392754 t += ic -> tag_size ;
27402755 }
27412756
27422757 metadata_block = get_metadata_sector_and_offset (ic , area , offset , & metadata_offset );
27432758
2744- r = dm_integrity_rw_tag (ic , ic -> recalc_tags , & metadata_block , & metadata_offset , t - ic -> recalc_tags , TAG_WRITE );
2759+ r = dm_integrity_rw_tag (ic , recalc_tags , & metadata_block , & metadata_offset , t - recalc_tags , TAG_WRITE );
27452760 if (unlikely (r )) {
27462761 dm_integrity_io_error (ic , "writing tags" , r );
27472762 goto err ;
@@ -2769,12 +2784,16 @@ static void integrity_recalc(struct work_struct *w)
27692784
27702785err :
27712786 remove_range (ic , & range );
2772- return ;
2787+ goto free_ret ;
27732788
27742789unlock_ret :
27752790 spin_unlock_irq (& ic -> endio_wait .lock );
27762791
27772792 recalc_write_super (ic );
2793+
2794+ free_ret :
2795+ vfree (recalc_buffer );
2796+ kvfree (recalc_tags );
27782797}
27792798
27802799static void bitmap_block_work (struct work_struct * w )
@@ -4439,30 +4458,13 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned int argc, char **argv
44394458 }
44404459
44414460 if (ic -> internal_hash ) {
4442- size_t recalc_tags_size ;
4443-
44444461 ic -> recalc_wq = alloc_workqueue ("dm-integrity-recalc" , WQ_MEM_RECLAIM , 1 );
44454462 if (!ic -> recalc_wq ) {
44464463 ti -> error = "Cannot allocate workqueue" ;
44474464 r = - ENOMEM ;
44484465 goto bad ;
44494466 }
44504467 INIT_WORK (& ic -> recalc_work , integrity_recalc );
4451- ic -> recalc_buffer = vmalloc (RECALC_SECTORS << SECTOR_SHIFT );
4452- if (!ic -> recalc_buffer ) {
4453- ti -> error = "Cannot allocate buffer for recalculating" ;
4454- r = - ENOMEM ;
4455- goto bad ;
4456- }
4457- recalc_tags_size = (RECALC_SECTORS >> ic -> sb -> log2_sectors_per_block ) * ic -> tag_size ;
4458- if (crypto_shash_digestsize (ic -> internal_hash ) > ic -> tag_size )
4459- recalc_tags_size += crypto_shash_digestsize (ic -> internal_hash ) - ic -> tag_size ;
4460- ic -> recalc_tags = kvmalloc (recalc_tags_size , GFP_KERNEL );
4461- if (!ic -> recalc_tags ) {
4462- ti -> error = "Cannot allocate tags for recalculating" ;
4463- r = - ENOMEM ;
4464- goto bad ;
4465- }
44664468 } else {
44674469 if (ic -> sb -> flags & cpu_to_le32 (SB_FLAG_RECALCULATING )) {
44684470 ti -> error = "Recalculate can only be specified with internal_hash" ;
@@ -4606,8 +4608,6 @@ static void dm_integrity_dtr(struct dm_target *ti)
46064608 destroy_workqueue (ic -> writer_wq );
46074609 if (ic -> recalc_wq )
46084610 destroy_workqueue (ic -> recalc_wq );
4609- vfree (ic -> recalc_buffer );
4610- kvfree (ic -> recalc_tags );
46114611 kvfree (ic -> bbs );
46124612 if (ic -> bufio )
46134613 dm_bufio_client_destroy (ic -> bufio );
0 commit comments