The "unstriped" device-mapper target incorrectly calculates the sector offset
on the mapped device when the target's origin is not zero.
Take for example this hypothetical concatenation of the members of a two-disk
RAID0:
linearized: 0 2097152 unstriped 2 128 0 /dev/md/raid0 0
linearized: 2097152 2097152 unstriped 2 128 1 /dev/md/raid0 0
The intent in this example is to create a single device named
/dev/mapper/linearized that comprises all of the chunks of the first disk of
the RAID0 set, followed by all of the chunks of the second disk of the RAID0
set.
This fails because dm-unstripe.c's map_to_core function does its computations
based on the sector number within the mapper device rather than the sector
number within the target. The bug turns invisible when the target's origin is
at sector zero of the mapper device, as is the common case. In the example
above, however, what happens is that the first half of the mapper device gets
mapped correctly to the first disk of the RAID0, but the second half of the
mapper device gets mapped past the end of the RAID0 device, and accesses to any
of those sectors return errors.
Here is a very simple (tested) patch that corrects the problem:
--- drivers/md/dm-unstripe.c~ 2025-11-28 22:33:48.000000000 -0500
+++ drivers/md/dm-unstripe.c 2026-01-18 12:48:52.378293579 -0500
@@ -117,7 +117,7 @@
static sector_t map_to_core(struct dm_target *ti, struct bio *bio)
{
struct unstripe_c *uc = ti->private;
- sector_t sector = bio->bi_iter.bi_sector;
+ sector_t sector = dm_target_offset(ti, bio->bi_iter.bi_sector);
sector_t tmp_sector = sector;
/* Shift us up to the right "row" on the stripe */