Re: [PATCH] block: remove inode lock for buffered write

From: Caleb Sander Mateos

Date: Thu Oct 29 2026 - 11:54:58 EST


On Thu, Oct 29, 2026 at 12:39 AM Edward Adam Davis <eadavis@xxxxxxxx> wrote:
>
> Commit 2fec4fd97cc3 ("block: take i_rwsem for the direct I/O write fallback")
> added shared inode locking around ordinary buffered writes, but commit
> 1b1be9ea4e34 move the lock to blkdev_buffered_write() and didn't remove the
> shared inode lock in blkdev_write_iter(), potentially hitting:
>
> WARNING: possible recursive locking detected
> --------------------------------------------
> syz.2.64/6167 is trying to acquire lock:
> ffff88802a5f1ee8 (&sb->s_type->i_mutex_key#9){++++}-{4:4}, at: blkdev_buffered_write block/fops.c:734 [inline]
> ffff88802a5f1ee8 (&sb->s_type->i_mutex_key#9){++++}-{4:4}, at: blkdev_write_iter+0xd12/0x11d0 block/fops.c:812
>
> but task is already holding lock:
> ffff88802a5f1ee8 (&sb->s_type->i_mutex_key#9){++++}-{4:4}, at: blkdev_write_iter+0xc5e/0x11d0 block/fops.c:811
>
> other info that might help us debug this:
> Possible unsafe locking scenario:
>
> CPU0
> ----
> lock(&sb->s_type->i_mutex_key#9);
> lock(&sb->s_type->i_mutex_key#9);
>
> *** DEADLOCK ***
>
> Call Trace:
> inode_lock_shared include/linux/fs.h:1039 [inline]
> blkdev_buffered_write block/fops.c:734 [inline]
> blkdev_write_iter+0xd12/0x11d0 block/fops.c:812
>
> Let's remove shared inode lock from blkdev_write_iter().
>
> Fixes: 1b1be9ea4e34 ("block: take the inode lock for buffered write fallback")
> Reported-by: syzbot+39e465d3f7a1555b0f96@xxxxxxxxxxxxxxxxxxxxxxxxx
> Closes: https://syzkaller.appspot.com/bug?extid=39e465d3f7a1555b0f96
> Tested-by: syzbot+39e465d3f7a1555b0f96@xxxxxxxxxxxxxxxxxxxxxxxxx
> Signed-off-by: Edward Adam Davis <eadavis@xxxxxxxx>
> ---
> block/fops.c | 2 --
> 1 file changed, 2 deletions(-)
>
> diff --git a/block/fops.c b/block/fops.c
> index 517b96c9d262..375ec2c15926 100644
> --- a/block/fops.c
> +++ b/block/fops.c
> @@ -808,9 +808,7 @@ static ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from)
> } else {
> ssize_t ret2;
>
> - inode_lock_shared(bd_inode);
> ret2 = blkdev_buffered_write(iocb, from);
> - inode_unlock_shared(bd_inode);

Already fixed by
https://lore.kernel.org/linux-block/20261022062513.77372-1-mzx199711@xxxxxxxxx/

Best,
Caleb

> ret = direct_write_fallback(iocb, from, ret,
> ret2);
> need_sync = true;
> --
> 2.43.0
>
>