]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
btrfs: fix lockdep warnings on io_uring encoded reads
authorMark Harmstone <maharmstone@fb.com>
Fri, 15 Nov 2024 15:49:17 +0000 (15:49 +0000)
committerDavid Sterba <dsterba@suse.com>
Fri, 29 Nov 2024 15:56:38 +0000 (16:56 +0100)
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>
34310c442e17 ("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>
fs/btrfs/ioctl.c
fs/btrfs/locking.h

index 1fdeb216bf6c5261cffe72adc00c97c739f4e167..f8680e7cc974f9fda3c5c19b9ff96352401526df 100644 (file)
@@ -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:
index 46c8be2afab1c690502587b8236756de288bbde5..35036b151bf5b090be340bb9a100e1e90e3d9d44 100644 (file)
@@ -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.