[XFS] Prevent lockdep false positives when locking two inodes.

If we call xfs_lock_two_inodes() to grab both the iolock and the ilock,
then drop the ilocks on both inodes, then grab them again (as
xfs_swap_extents() does) then lockdep will report a locking order problem.
This is a false positive.

To avoid this, disallow xfs_lock_two_inodes() fom locking both inode locks
at once - force calers to make two separate calls. This means that nested
dropping and regaining of the ilocks will retain the same lockdep subclass
and so lockdep will not see anything wrong with this code.

SGI-PV: 986238

SGI-Modid: xfs-linux-melb:xfs-kern:31999a

Signed-off-by: David Chinner <david@fromorbit.com>
Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Peter Leckie <pleckie@sgi.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>

authored by David Chinner and committed by Lachlan McIlroy f9114eba b5b8c9ac

+16 -1
+8 -1
fs/xfs/xfs_dfrag.c
··· 149 149 150 150 sbp = &sxp->sx_stat; 151 151 152 - xfs_lock_two_inodes(ip, tip, lock_flags); 152 + /* 153 + * we have to do two separate lock calls here to keep lockdep 154 + * happy. If we try to get all the locks in one call, lock will 155 + * report false positives when we drop the ILOCK and regain them 156 + * below. 157 + */ 158 + xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL); 159 + xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL); 153 160 locked = 1; 154 161 155 162 /* Verify that both files have the same format */
+8
fs/xfs/xfs_vnodeops.c
··· 1838 1838 #endif 1839 1839 } 1840 1840 1841 + /* 1842 + * xfs_lock_two_inodes() can only be used to lock one type of lock 1843 + * at a time - the iolock or the ilock, but not both at once. If 1844 + * we lock both at once, lockdep will report false positives saying 1845 + * we have violated locking orders. 1846 + */ 1841 1847 void 1842 1848 xfs_lock_two_inodes( 1843 1849 xfs_inode_t *ip0, ··· 1854 1848 int attempts = 0; 1855 1849 xfs_log_item_t *lp; 1856 1850 1851 + if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL)) 1852 + ASSERT((lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)) == 0); 1857 1853 ASSERT(ip0->i_ino != ip1->i_ino); 1858 1854 1859 1855 if (ip0->i_ino > ip1->i_ino) {