[PATCH] bdev: do not report a statx block size below the block size

From: Hengyu Liang

Date: Thu Nov 12 2026 - 13:08:26 EST


Commit 425fbcd62d2e ("bdev: use bdev_io_min() for statx block size")
made stat() report the minimum I/O size of a block device as
st_blksize, so that devices with a large minimum I/O size get large
enough I/O. Commit 777d0961ff95 ("fs: move the bdex_statx call to
vfs_getattr_nosec") did the same for fstat().

However, the minimum I/O size of most disks is 512 bytes, and
st_blksize was 4096 for them before. As of now, programs that size
their buffer by st_blksize, such as stdio, write to these disks 512
bytes at a time. Each write that covers only part of a block makes the
kernel read the block from the disk first.

The issue can be reproduced on a disk with 512-byte sectors with:

stat -c %o /dev/vda

Before commit 425fbcd62d2e ("bdev: use bdev_io_min() for statx block
size"), the result is:

4096

After that commit, the result is:

512

This patch will report the block size of the block device when it is
larger than the minimum I/O size.

Fixes: 425fbcd62d2e ("bdev: use bdev_io_min() for statx block size")
Signed-off-by: Hengyu Liang <hengyul@xxxxxxxxxx>
---
Application impact (Ubuntu 26.04 user space): "bzcat sd.img.bz2 >
/dev/vda" (bzip2 1.0.8, 64 MiB image, disk with 512-byte sectors). On
v6.14, it reads at most 688 sectors from the disk. On v6.15, it reads
about 108,000 sectors (53 MiB) while writing the image.

Tested on block-7.4: with this patch, stat reports 4096 again and bzcat
reads at most 2,104 sectors.

block/bdev.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/block/bdev.c b/block/bdev.c
index f20f91b3176e..c9a3d7832c42 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -1430,7 +1430,11 @@ void bdev_statx(const struct path *path, struct kstat *stat, u32 request_mask)
0);
}

- stat->blksize = bdev_io_min(bdev);
+ /*
+ * A buffered write that covers only part of a block has to read the
+ * block first, so do not report less than the block size.
+ */
+ stat->blksize = max(bdev_io_min(bdev), block_size(bdev));

blkdev_put_no_open(bdev);
}

base-commit: 8067050e7226844fb32062b5cea947e5897d3d7e
--
2.53.0