@@ -319,27 +319,6 @@ static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev,
return 1;
}
- if (logical_block_size_sectors <= 1)
- return 0;
-
- if (start & (logical_block_size_sectors - 1)) {
- DMWARN("%s: start=%llu not aligned to h/w "
- "logical block size %u of %s",
- dm_device_name(ti->table->md),
- (unsigned long long)start,
- limits->logical_block_size, bdevname(bdev, b));
- return 1;
- }
-
- if (len & (logical_block_size_sectors - 1)) {
- DMWARN("%s: len=%llu not aligned to h/w "
- "logical block size %u of %s",
- dm_device_name(ti->table->md),
- (unsigned long long)len,
- limits->logical_block_size, bdevname(bdev, b));
- return 1;
- }
-
/*
* If the target is mapped to zoned block device(s), check
* that the zones are not partially mapped.
@@ -355,6 +334,15 @@ static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev,
return 1;
}
+ /*
+ * Note: The last zone of a zoned block device may be smaller
+ * than other zones. So for a target mapping the end of a
+ * zoned block device with such a zone, len would not be zone
+ * aligned. We do not allow such last smaller zone to be part
+ * of the mapping here to ensure that mappings with multiple
+ * devices do not end up with a smaller zone in the middle of
+ * the sector range.
+ */
if (len & (zone_sectors - 1)) {
DMWARN("%s: len=%llu not aligned to h/w zone size %u of %s",
dm_device_name(ti->table->md),
@@ -364,6 +352,27 @@ static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev,
}
}
+ if (logical_block_size_sectors <= 1)
+ return 0;
+
+ if (start & (logical_block_size_sectors - 1)) {
+ DMWARN("%s: start=%llu not aligned to h/w "
+ "logical block size %u of %s",
+ dm_device_name(ti->table->md),
+ (unsigned long long)start,
+ limits->logical_block_size, bdevname(bdev, b));
+ return 1;
+ }
+
+ if (len & (logical_block_size_sectors - 1)) {
+ DMWARN("%s: len=%llu not aligned to h/w "
+ "logical block size %u of %s",
+ dm_device_name(ti->table->md),
+ (unsigned long long)len,
+ limits->logical_block_size, bdevname(bdev, b));
+ return 1;
+ }
+
return 0;
}
In device_area_is_invalid(), check a device mapping zone alignment before checking the LBA size so that the check is also performed for devices with a single sector (512B) LBA size. Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com> --- drivers/md/dm-table.c | 51 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 21 deletions(-)