]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
dm-bufio: align write boundary on physical block size
authorMikulas Patocka <mpatocka@redhat.com>
Mon, 20 Oct 2025 12:48:13 +0000 (14:48 +0200)
committerMikulas Patocka <mpatocka@redhat.com>
Wed, 10 Dec 2025 18:28:22 +0000 (19:28 +0100)
There may be devices with physical block size larger than 4k.

If dm-bufio sends I/O that is not aligned on physical block size,
performance is degraded.

The 4k minimum alignment limit is there because some SSDs report logical
and physical block size 512 despite having 4k internally - so dm-bufio
shouldn't send I/Os not aligned on 4k boundary, because they perform
badly (the SSD does read-modify-write for them).

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Reported-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
Cc: stable@vger.kernel.org
drivers/md/dm-bufio.c

index e6d28be11c5c6ce791405a733eea3ccc8f37a58a..5235f3e4924b7a132286690e6c48285a7d32c65c 100644 (file)
@@ -1374,7 +1374,7 @@ static void submit_io(struct dm_buffer *b, enum req_op op, unsigned short ioprio
 {
        unsigned int n_sectors;
        sector_t sector;
-       unsigned int offset, end;
+       unsigned int offset, end, align;
 
        b->end_io = end_io;
 
@@ -1388,9 +1388,11 @@ static void submit_io(struct dm_buffer *b, enum req_op op, unsigned short ioprio
                        b->c->write_callback(b);
                offset = b->write_start;
                end = b->write_end;
-               offset &= -DM_BUFIO_WRITE_ALIGN;
-               end += DM_BUFIO_WRITE_ALIGN - 1;
-               end &= -DM_BUFIO_WRITE_ALIGN;
+               align = max(DM_BUFIO_WRITE_ALIGN,
+                       bdev_physical_block_size(b->c->bdev));
+               offset &= -align;
+               end += align - 1;
+               end &= -align;
                if (unlikely(end > b->c->block_size))
                        end = b->c->block_size;