[PATCH] block: remove inode lock for buffered write

From: Edward Adam Davis

Date: Thu Oct 29 2026 - 03:40:00 EST


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);
ret = direct_write_fallback(iocb, from, ret,
ret2);
need_sync = true;
--
2.43.0