xfs: drop iolock from reclaim context to appease lockdep
authorBrian Foster <bfoster@redhat.com>
Tue, 11 Apr 2017 17:50:05 +0000 (10:50 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Wed, 12 Apr 2017 15:43:23 +0000 (08:43 -0700)
Lockdep complains about use of the iolock in inode reclaim context
because it doesn't understand that reclaim has the last reference to
the inode, and thus an iolock->reclaim->iolock deadlock is not
possible.

The iolock is technically not necessary in xfs_inactive() and was
only added to appease an assert in xfs_free_eofblocks(), which can
be called from other non-reclaim contexts. Therefore, just kill the
assert and drop the use of the iolock from reclaim context to quiet
lockdep.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
fs/xfs/xfs_bmap_util.c
fs/xfs/xfs_inode.c

index 4d1920e594b05b7bad8aeebff3e8ef6f07676767..de94798f1c1b2baa55d6e23fceb1329670400a36 100644 (file)
@@ -903,9 +903,9 @@ xfs_can_free_eofblocks(struct xfs_inode *ip, bool force)
 }
 
 /*
- * This is called by xfs_inactive to free any blocks beyond eof
- * when the link count isn't zero and by xfs_dm_punch_hole() when
- * punching a hole to EOF.
+ * This is called to free any blocks beyond eof. The caller must hold
+ * IOLOCK_EXCL unless we are in the inode reclaim path and have the only
+ * reference to the inode.
  */
 int
 xfs_free_eofblocks(
@@ -920,8 +920,6 @@ xfs_free_eofblocks(
        struct xfs_bmbt_irec    imap;
        struct xfs_mount        *mp = ip->i_mount;
 
-       ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
-
        /*
         * Figure out if there are any blocks beyond the end
         * of the file.  If not, then there is nothing to do.
index 7605d83965963566e1d6acef679591cf9787d161..ec9826c565009e5244682beae93c4efc5261b487 100644 (file)
@@ -1906,12 +1906,13 @@ xfs_inactive(
                 * force is true because we are evicting an inode from the
                 * cache. Post-eof blocks must be freed, lest we end up with
                 * broken free space accounting.
+                *
+                * Note: don't bother with iolock here since lockdep complains
+                * about acquiring it in reclaim context. We have the only
+                * reference to the inode at this point anyways.
                 */
-               if (xfs_can_free_eofblocks(ip, true)) {
-                       xfs_ilock(ip, XFS_IOLOCK_EXCL);
+               if (xfs_can_free_eofblocks(ip, true))
                        xfs_free_eofblocks(ip);
-                       xfs_iunlock(ip, XFS_IOLOCK_EXCL);
-               }
 
                return;
        }