@@ -1379,12 +1379,52 @@ static int dm_integrity_rw_tag(struct dm_integrity_c *ic, unsigned char *tag, se
13791379#undef MAY_BE_HASH
13801380}
13811381
1382- static void dm_integrity_flush_buffers (struct dm_integrity_c * ic )
1382+ struct flush_request {
1383+ struct dm_io_request io_req ;
1384+ struct dm_io_region io_reg ;
1385+ struct dm_integrity_c * ic ;
1386+ struct completion comp ;
1387+ };
1388+
1389+ static void flush_notify (unsigned long error , void * fr_ )
1390+ {
1391+ struct flush_request * fr = fr_ ;
1392+ if (unlikely (error != 0 ))
1393+ dm_integrity_io_error (fr -> ic , "flusing disk cache" , - EIO );
1394+ complete (& fr -> comp );
1395+ }
1396+
1397+ static void dm_integrity_flush_buffers (struct dm_integrity_c * ic , bool flush_data )
13831398{
13841399 int r ;
1400+
1401+ struct flush_request fr ;
1402+
1403+ if (!ic -> meta_dev )
1404+ flush_data = false;
1405+ if (flush_data ) {
1406+ fr .io_req .bi_op = REQ_OP_WRITE ,
1407+ fr .io_req .bi_op_flags = REQ_PREFLUSH | REQ_SYNC ,
1408+ fr .io_req .mem .type = DM_IO_KMEM ,
1409+ fr .io_req .mem .ptr .addr = NULL ,
1410+ fr .io_req .notify .fn = flush_notify ,
1411+ fr .io_req .notify .context = & fr ;
1412+ fr .io_req .client = dm_bufio_get_dm_io_client (ic -> bufio ),
1413+ fr .io_reg .bdev = ic -> dev -> bdev ,
1414+ fr .io_reg .sector = 0 ,
1415+ fr .io_reg .count = 0 ,
1416+ fr .ic = ic ;
1417+ init_completion (& fr .comp );
1418+ r = dm_io (& fr .io_req , 1 , & fr .io_reg , NULL );
1419+ BUG_ON (r );
1420+ }
1421+
13851422 r = dm_bufio_write_dirty_buffers (ic -> bufio );
13861423 if (unlikely (r ))
13871424 dm_integrity_io_error (ic , "writing tags" , r );
1425+
1426+ if (flush_data )
1427+ wait_for_completion (& fr .comp );
13881428}
13891429
13901430static void sleep_on_endio_wait (struct dm_integrity_c * ic )
@@ -2110,7 +2150,7 @@ static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map
21102150
21112151 if (unlikely (dio -> op == REQ_OP_DISCARD ) && likely (ic -> mode != 'D' )) {
21122152 integrity_metadata (& dio -> work );
2113- dm_integrity_flush_buffers (ic );
2153+ dm_integrity_flush_buffers (ic , false );
21142154
21152155 dio -> in_flight = (atomic_t )ATOMIC_INIT (1 );
21162156 dio -> completion = NULL ;
@@ -2195,7 +2235,7 @@ static void integrity_commit(struct work_struct *w)
21952235 flushes = bio_list_get (& ic -> flush_bio_list );
21962236 if (unlikely (ic -> mode != 'J' )) {
21972237 spin_unlock_irq (& ic -> endio_wait .lock );
2198- dm_integrity_flush_buffers (ic );
2238+ dm_integrity_flush_buffers (ic , true );
21992239 goto release_flush_bios ;
22002240 }
22012241
@@ -2409,7 +2449,7 @@ static void do_journal_write(struct dm_integrity_c *ic, unsigned write_start,
24092449 complete_journal_op (& comp );
24102450 wait_for_completion_io (& comp .comp );
24112451
2412- dm_integrity_flush_buffers (ic );
2452+ dm_integrity_flush_buffers (ic , true );
24132453}
24142454
24152455static void integrity_writer (struct work_struct * w )
@@ -2451,7 +2491,7 @@ static void recalc_write_super(struct dm_integrity_c *ic)
24512491{
24522492 int r ;
24532493
2454- dm_integrity_flush_buffers (ic );
2494+ dm_integrity_flush_buffers (ic , false );
24552495 if (dm_integrity_failed (ic ))
24562496 return ;
24572497
@@ -2654,7 +2694,7 @@ static void bitmap_flush_work(struct work_struct *work)
26542694 unsigned long limit ;
26552695 struct bio * bio ;
26562696
2657- dm_integrity_flush_buffers (ic );
2697+ dm_integrity_flush_buffers (ic , false );
26582698
26592699 range .logical_sector = 0 ;
26602700 range .n_sectors = ic -> provided_data_sectors ;
@@ -2663,9 +2703,7 @@ static void bitmap_flush_work(struct work_struct *work)
26632703 add_new_range_and_wait (ic , & range );
26642704 spin_unlock_irq (& ic -> endio_wait .lock );
26652705
2666- dm_integrity_flush_buffers (ic );
2667- if (ic -> meta_dev )
2668- blkdev_issue_flush (ic -> dev -> bdev , GFP_NOIO );
2706+ dm_integrity_flush_buffers (ic , true);
26692707
26702708 limit = ic -> provided_data_sectors ;
26712709 if (ic -> sb -> flags & cpu_to_le32 (SB_FLAG_RECALCULATING )) {
@@ -2934,11 +2972,11 @@ static void dm_integrity_postsuspend(struct dm_target *ti)
29342972 if (ic -> meta_dev )
29352973 queue_work (ic -> writer_wq , & ic -> writer_work );
29362974 drain_workqueue (ic -> writer_wq );
2937- dm_integrity_flush_buffers (ic );
2975+ dm_integrity_flush_buffers (ic , true );
29382976 }
29392977
29402978 if (ic -> mode == 'B' ) {
2941- dm_integrity_flush_buffers (ic );
2979+ dm_integrity_flush_buffers (ic , true );
29422980#if 1
29432981 /* set to 0 to test bitmap replay code */
29442982 init_journal (ic , 0 , ic -> journal_sections , 0 );
0 commit comments