dm-era tracks writes in target-relative blocks, but the mapping path can
ignore the target offset when translating bios.  Tables with a non-zero
start sector can therefore map and account I/O against the wrong origin
sectors.

The result is inconsistent metadata for devices that are not mapped at
sector zero.

Apply the target offset consistently when mapping and tracking writes.

Assisted-by: Codex:gpt-5.5-cyber-preview
Signed-off-by: Samuel Moelius <[email protected]>
---
 drivers/md/dm-era-target.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/md/dm-era-target.c b/drivers/md/dm-era-target.c
index 05285c04ff2c..18aed0e2a508 100644
--- a/drivers/md/dm-era-target.c
+++ b/drivers/md/dm-era-target.c
@@ -1229,6 +1229,7 @@ static dm_block_t get_block(struct era *era, struct bio 
*bio)
 static void remap_to_origin(struct era *era, struct bio *bio)
 {
        bio_set_dev(bio, era->origin_dev->bdev);
+       bio->bi_iter.bi_sector = dm_target_offset(era->ti, 
bio->bi_iter.bi_sector);
 }
 
 /*
@@ -1560,7 +1561,7 @@ static void era_dtr(struct dm_target *ti)
 static int era_map(struct dm_target *ti, struct bio *bio)
 {
        struct era *era = ti->private;
-       dm_block_t block = get_block(era, bio);
+       dm_block_t block;
 
        /*
         * All bios get remapped to the origin device.  We do this now, but
@@ -1568,6 +1569,7 @@ static int era_map(struct dm_target *ti, struct bio *bio)
         * block is marked in this era.
         */
        remap_to_origin(era, bio);
+       block = get_block(era, bio);
 
        /*
         * REQ_PREFLUSH bios carry no data, so we're not interested in them.
-- 
2.43.0


Reply via email to