Writes of the md superblock are aligned to the logical blocks of the containing device, but no attempt is made to align them to physical block boundaries. This means that on a "512e" device (4k physical, 512 logical) every superblock update hits the 512-byte emulation and the possible associated performance penalty. Respect the physical block alignment when possible. Signed-off-by: Christopher Unkel <cunkel@xxxxxxxxxxxxxx> --- drivers/md/md.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/md/md.c b/drivers/md/md.c index 98bac4f304ae..2b42850acfb3 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1732,6 +1732,21 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_ && rdev->new_data_offset < sb_start + (rdev->sb_size/512)) return -EINVAL; + /* Respect physical block size if feasible. */ + bmask = queue_physical_block_size(rdev->bdev->bd_disk->queue)-1; + if (!((rdev->sb_start * 512) & bmask) && (rdev->sb_size & bmask)) { + int candidate_size = (rdev->sb_size | bmask) + 1; + + if (minor_version) { + int sectors = candidate_size / 512; + + if (rdev->data_offset >= sb_start + sectors + && rdev->new_data_offset >= sb_start + sectors) + rdev->sb_size = candidate_size; + } else if (bmask <= 4095) + rdev->sb_size = candidate_size; + } + if (sb->level == cpu_to_le32(LEVEL_MULTIPATH)) rdev->desc_nr = -1; else -- 2.17.1