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 --- 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