Re: [PATCH v3 3/7] block: take i_rwsem for the splice read path
From: Shin'ichiro Kawasaki
Date: Thu Sep 17 2026 - 22:59:19 EST
On Sep 09, 2026 / 17:59, Tal Zussman wrote:
> def_blk_fops wires ->splice_read directly to filemap_splice_read(),
> which allocates folios based on mapping_min_folio_order() without any
> lock against set_blocksize(). A splice from a block device can race
> set_blocksize() raising the minimum folio order and insert a folio that
> is too small for the mapping. blkdev_read_iter() wraps filemap_read()
> in inode_lock_shared() for this reason, but the splice path was missed.
>
> Splicing from a block device while toggling the block size between 512
> bytes and 64K with BLKBSZSET hits this within seconds on a
> CONFIG_DEBUG_VM kernel:
>
> page dumped because: VM_BUG_ON_FOLIO(folio_order(folio) < mapping_min_folio_order(mapping))
> kernel BUG at mm/filemap.c:858!
> Oops: invalid opcode: 0000 [#1] SMP NOPTI
> RIP: 0010:__filemap_add_folio+0x51c/0x570
> Call Trace:
> filemap_add_folio+0x64/0x140
> page_cache_ra_order+0x1dd/0x3d0
> filemap_get_pages+0x153/0x760
> filemap_splice_read+0x13f/0x300
> splice_file_to_pipe+0xc0/0xd0
> do_splice+0x6a8/0x890
> __do_splice+0xb0/0x210
> __x64_sys_splice+0x80/0x100
> do_syscall_64+0x10e/0x520
> entry_SYSCALL_64_after_hwframe+0x77/0x7f
>
> Take inode_lock_shared() around filemap_splice_read(), like the read
> path does.
>
> Fixes: 3c20917120ce ("block/bdev: enable large folio support for large logical block sizes")
> Assisted-by: Claude:claude-fable-5
> Reviewed-by: Hannes Reinecke <hare@xxxxxxxxxx>
> Reviewed-by: Christoph Hellwig <hch@xxxxxx>
> Signed-off-by: Tal Zussman <tz2294@xxxxxxxxxxxx>
I confirmed that this patch avoid the hang triggered by the corresponding
blktests test case [*].
Tested-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@xxxxxxx>
[*] https://lore.kernel.org/linux-block/20260909-blkdev-fixes-tests-v1-2-1f8af8665d16@xxxxxxxxxxxx/