Commit 22d2e48e authored by Mark Harmstone's avatar Mark Harmstone Committed by David Sterba
Browse files

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: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
34310c44 ("btrfs: add io_uring command for encoded reads (ENCODED_READ ioctl)")
Signed-off-by: default avatarMark Harmstone <maharmstone@fb.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 7c4e39f9
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -4752,6 +4752,9 @@ static void btrfs_uring_read_finished(struct io_uring_cmd *cmd, unsigned int iss
	size_t page_offset;
	ssize_t ret;

	/* The inode lock has already been acquired in btrfs_uring_read_extent.  */
	btrfs_lockdep_inode_acquire(inode, i_rwsem);

	if (priv->err) {
		ret = priv->err;
		goto out;
@@ -4860,6 +4863,13 @@ static int btrfs_uring_read_extent(struct kiocb *iocb, struct iov_iter *iter,
	 * and inode and freeing the allocations.
	 */

	/*
	 * We're returning to userspace with the inode lock held, and that's
	 * okay - it'll get unlocked in a worker thread.  Call
	 * btrfs_lockdep_inode_release() to avoid confusing lockdep.
	 */
	btrfs_lockdep_inode_release(inode, i_rwsem);

	return -EIOCBQUEUED;

out_fail:
+10 −0
Original line number Diff line number Diff line
@@ -128,6 +128,16 @@ enum btrfs_lockdep_trans_states {
#define btrfs_lockdep_release(owner, lock)					\
	rwsem_release(&owner->lock##_map, _THIS_IP_)

/*
 * Used to account for the fact that when doing io_uring encoded I/O, we can
 * return to userspace with the inode lock still held.
 */
#define btrfs_lockdep_inode_acquire(owner, lock)				\
	rwsem_acquire_read(&owner->vfs_inode.lock.dep_map, 0, 0, _THIS_IP_)

#define btrfs_lockdep_inode_release(owner, lock)				\
	rwsem_release(&owner->vfs_inode.lock.dep_map, _THIS_IP_)

/*
 * Macros for the transaction states wait events, similar to the generic wait
 * event macros.