mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-10-28 12:53:14 +01:00
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 <[email protected]>
Tested-by: Ondrej Kozina <[email protected]>
Fixes: 468dfca38b ("dm integrity: add a bitmap mode")
Cc: [email protected]
This commit is contained in:
1 parent
be9badced9
commit
118ba36e44
1 file changed
+13
@@ -3788,14 +3788,27 @@ static void dm_integrity_resume(struct dm_target *ti)
|
||||
struct dm_integrity_c *ic = ti->private;
|
||||
__u64 old_provided_data_sectors = le64_to_cpu(ic->sb->provided_data_sectors);
|
||||
int r;
|
||||
__le32 flags;
|
||||
|
||||
DEBUG_print("resume\n");
|
||||
|
||||
ic->wrote_to_journal = false;
|
||||
|
||||
flags = ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING);
|
||||
r = sync_rw_sb(ic, REQ_OP_READ);
|
||||
if (r)
|
||||
dm_integrity_io_error(ic, "reading superblock", r);
|
||||
if ((ic->sb->flags & flags) != flags) {
|
||||
ic->sb->flags |= flags;
|
||||
r = sync_rw_sb(ic, REQ_OP_WRITE | REQ_FUA);
|
||||
if (unlikely(r))
|
||||
dm_integrity_io_error(ic, "writing superblock", r);
|
||||
}
|
||||
|
||||
if (ic->provided_data_sectors != old_provided_data_sectors) {
|
||||
if (ic->provided_data_sectors > old_provided_data_sectors &&
|
||||
ic->mode == 'B' &&
|
||||
ic->sb->flags & cpu_to_le32(SB_FLAG_DIRTY_BITMAP) &&
|
||||
ic->sb->log2_blocks_per_bitmap_bit == ic->log2_blocks_per_bitmap_bit) {
|
||||
rw_journal_sectors(ic, REQ_OP_READ, 0,
|
||||
ic->n_bitmap_blocks * (BITMAP_BLOCK_SIZE >> SECTOR_SHIFT), NULL);
|
||||
|
||||
Reference in new issue
Block a user