[PATCH 1/3] md: align superblock writes to physical blocks

From: Christopher Unkel
Date: Thu Oct 22 2020 - 23:31:49 EST


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