dm integrity: fix recalculation when moving from journal mode to bitmap mode
[platform/kernel/linux-rpi.git] / drivers / md / dm-integrity.c
index dab4446..47a74d2 100644 (file)
@@ -2883,17 +2883,24 @@ static void dm_integrity_resume(struct dm_target *ti)
        } else {
                replay_journal(ic);
                if (ic->mode == 'B') {
-                       int mode;
                        ic->sb->flags |= cpu_to_le32(SB_FLAG_DIRTY_BITMAP);
                        ic->sb->log2_blocks_per_bitmap_bit = ic->log2_blocks_per_bitmap_bit;
                        r = sync_rw_sb(ic, REQ_OP_WRITE, REQ_FUA);
                        if (unlikely(r))
                                dm_integrity_io_error(ic, "writing superblock", r);
 
-                       mode = ic->recalculate_flag ? BITMAP_OP_SET : BITMAP_OP_CLEAR;
-                       block_bitmap_op(ic, ic->journal, 0, ic->provided_data_sectors, mode);
-                       block_bitmap_op(ic, ic->recalc_bitmap, 0, ic->provided_data_sectors, mode);
-                       block_bitmap_op(ic, ic->may_write_bitmap, 0, ic->provided_data_sectors, mode);
+                       block_bitmap_op(ic, ic->journal, 0, ic->provided_data_sectors, BITMAP_OP_CLEAR);
+                       block_bitmap_op(ic, ic->recalc_bitmap, 0, ic->provided_data_sectors, BITMAP_OP_CLEAR);
+                       block_bitmap_op(ic, ic->may_write_bitmap, 0, ic->provided_data_sectors, BITMAP_OP_CLEAR);
+                       if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING) &&
+                           le64_to_cpu(ic->sb->recalc_sector) < ic->provided_data_sectors) {
+                               block_bitmap_op(ic, ic->journal, le64_to_cpu(ic->sb->recalc_sector),
+                                               ic->provided_data_sectors - le64_to_cpu(ic->sb->recalc_sector), BITMAP_OP_SET);
+                               block_bitmap_op(ic, ic->recalc_bitmap, le64_to_cpu(ic->sb->recalc_sector),
+                                               ic->provided_data_sectors - le64_to_cpu(ic->sb->recalc_sector), BITMAP_OP_SET);
+                               block_bitmap_op(ic, ic->may_write_bitmap, le64_to_cpu(ic->sb->recalc_sector),
+                                               ic->provided_data_sectors - le64_to_cpu(ic->sb->recalc_sector), BITMAP_OP_SET);
+                       }
                        rw_journal_sectors(ic, REQ_OP_WRITE, REQ_FUA | REQ_SYNC, 0,
                                           ic->n_bitmap_blocks * (BITMAP_BLOCK_SIZE >> SECTOR_SHIFT), NULL);
                }