Skip to content

Commit 118ba36

Browse files
author
Mikulas Patocka
committed
dm-integrity: fix recalculation in bitmap mode
There's a logic quirk in the handling of suspend in the bitmap mode: This is the sequence of calls if we are reloading a dm-integrity table: * dm_integrity_ctr reads a superblock with the flag SB_FLAG_DIRTY_BITMAP set. * dm_integrity_postsuspend initializes a journal and clears the flag SB_FLAG_DIRTY_BITMAP. * dm_integrity_resume sees the superblock with SB_FLAG_DIRTY_BITMAP set - thus it interprets the journal as if it were a bitmap. This quirk causes recalculation problem if the user increases the size of the device in the bitmap mode. Fix this by reading a fresh copy on the superblock in dm_integrity_resume. This commit also fixes another logic quirk - the branch that sets bitmap bits if the device was extended should only be executed if the flag SB_FLAG_DIRTY_BITMAP is set. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Tested-by: Ondrej Kozina <okozina@redhat.com> Fixes: 468dfca ("dm integrity: add a bitmap mode") Cc: stable@vger.kernel.org
1 parent be9badc commit 118ba36

1 file changed

Lines changed: 13 additions & 0 deletions

File tree

drivers/md/dm-integrity.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3788,14 +3788,27 @@ static void dm_integrity_resume(struct dm_target *ti)
37883788
struct dm_integrity_c *ic = ti->private;
37893789
__u64 old_provided_data_sectors = le64_to_cpu(ic->sb->provided_data_sectors);
37903790
int r;
3791+
__le32 flags;
37913792

37923793
DEBUG_print("resume\n");
37933794

37943795
ic->wrote_to_journal = false;
37953796

3797+
flags = ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING);
3798+
r = sync_rw_sb(ic, REQ_OP_READ);
3799+
if (r)
3800+
dm_integrity_io_error(ic, "reading superblock", r);
3801+
if ((ic->sb->flags & flags) != flags) {
3802+
ic->sb->flags |= flags;
3803+
r = sync_rw_sb(ic, REQ_OP_WRITE | REQ_FUA);
3804+
if (unlikely(r))
3805+
dm_integrity_io_error(ic, "writing superblock", r);
3806+
}
3807+
37963808
if (ic->provided_data_sectors != old_provided_data_sectors) {
37973809
if (ic->provided_data_sectors > old_provided_data_sectors &&
37983810
ic->mode == 'B' &&
3811+
ic->sb->flags & cpu_to_le32(SB_FLAG_DIRTY_BITMAP) &&
37993812
ic->sb->log2_blocks_per_bitmap_bit == ic->log2_blocks_per_bitmap_bit) {
38003813
rw_journal_sectors(ic, REQ_OP_READ, 0,
38013814
ic->n_bitmap_blocks * (BITMAP_BLOCK_SIZE >> SECTOR_SHIFT), NULL);

0 commit comments

Comments
 (0)