return error;
 }
+
+/*
+ * Try to lock an inode in violation of the usual locking order rules.  For
+ * example, trying to get the IOLOCK while in transaction context, or just
+ * plain breaking AG-order or inode-order inode locking rules.  Either way,
+ * the only way to avoid an ABBA deadlock is to use trylock and back off if
+ * we can't.
+ */
+int
+xfs_scrub_ilock_inverted(
+       struct xfs_inode        *ip,
+       uint                    lock_mode)
+{
+       int                     i;
+
+       for (i = 0; i < 20; i++) {
+               if (xfs_ilock_nowait(ip, lock_mode))
+                       return 0;
+               delay(1);
+       }
+       return -EDEADLOCK;
+}
 
 }
 
 int xfs_scrub_metadata_inode_forks(struct xfs_scrub_context *sc);
+int xfs_scrub_ilock_inverted(struct xfs_inode *ip, uint lock_mode);
 
 #endif /* __XFS_SCRUB_COMMON_H__ */
 
         */
        xfs_iunlock(sc->ip, sc->ilock_flags);
        sc->ilock_flags = 0;
-       xfs_ilock(dp, XFS_IOLOCK_SHARED);
+       error = xfs_scrub_ilock_inverted(dp, XFS_IOLOCK_SHARED);
+       if (error)
+               goto out_rele;
 
        /* Go looking for our dentry. */
        error = xfs_scrub_parent_count_parent_dentries(sc, dp, &nlink);
 
        /* Drop the parent lock, relock this inode. */
        xfs_iunlock(dp, XFS_IOLOCK_SHARED);
+       error = xfs_scrub_ilock_inverted(sc->ip, XFS_IOLOCK_EXCL);
+       if (error)
+               goto out_rele;
        sc->ilock_flags = XFS_IOLOCK_EXCL;
-       xfs_ilock(sc->ip, sc->ilock_flags);
 
        /*
         * If we're an unlinked directory, the parent /won't/ have a link
        if (try_again && tries == 20)
                xfs_scrub_set_incomplete(sc);
 out:
+       /*
+        * If we failed to lock the parent inode even after a retry, just mark
+        * this scrub incomplete and return.
+        */
+       if (sc->try_harder && error == -EDEADLOCK) {
+               error = 0;
+               xfs_scrub_set_incomplete(sc);
+       }
        return error;
 }