Skip to content

Commit 22d2e48

Browse files
maharmstonekdave
authored andcommitted
btrfs: fix lockdep warnings on io_uring encoded reads
Lockdep doesn't like the fact that btrfs_uring_read_extent() returns to userspace still holding the inode lock, even though we release it once the I/O finishes. Add calls to rwsem_release() and rwsem_acquire_read() to work round this. Reported-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> 34310c4 ("btrfs: add io_uring command for encoded reads (ENCODED_READ ioctl)") Signed-off-by: Mark Harmstone <maharmstone@fb.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 7c4e39f commit 22d2e48

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

fs/btrfs/ioctl.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4752,6 +4752,9 @@ static void btrfs_uring_read_finished(struct io_uring_cmd *cmd, unsigned int iss
47524752
size_t page_offset;
47534753
ssize_t ret;
47544754

4755+
/* The inode lock has already been acquired in btrfs_uring_read_extent. */
4756+
btrfs_lockdep_inode_acquire(inode, i_rwsem);
4757+
47554758
if (priv->err) {
47564759
ret = priv->err;
47574760
goto out;
@@ -4860,6 +4863,13 @@ static int btrfs_uring_read_extent(struct kiocb *iocb, struct iov_iter *iter,
48604863
* and inode and freeing the allocations.
48614864
*/
48624865

4866+
/*
4867+
* We're returning to userspace with the inode lock held, and that's
4868+
* okay - it'll get unlocked in a worker thread. Call
4869+
* btrfs_lockdep_inode_release() to avoid confusing lockdep.
4870+
*/
4871+
btrfs_lockdep_inode_release(inode, i_rwsem);
4872+
48634873
return -EIOCBQUEUED;
48644874

48654875
out_fail:

fs/btrfs/locking.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,16 @@ enum btrfs_lockdep_trans_states {
128128
#define btrfs_lockdep_release(owner, lock) \
129129
rwsem_release(&owner->lock##_map, _THIS_IP_)
130130

131+
/*
132+
* Used to account for the fact that when doing io_uring encoded I/O, we can
133+
* return to userspace with the inode lock still held.
134+
*/
135+
#define btrfs_lockdep_inode_acquire(owner, lock) \
136+
rwsem_acquire_read(&owner->vfs_inode.lock.dep_map, 0, 0, _THIS_IP_)
137+
138+
#define btrfs_lockdep_inode_release(owner, lock) \
139+
rwsem_release(&owner->vfs_inode.lock.dep_map, _THIS_IP_)
140+
131141
/*
132142
* Macros for the transaction states wait events, similar to the generic wait
133143
* event macros.

0 commit comments

Comments
 (0)