xfs: avoid ABBA deadlock when scrubbing parent pointers
[platform/kernel/linux-rpi.git] / fs / xfs / scrub / common.c
index 62b33c9..518bff2 100644 (file)
@@ -844,3 +844,25 @@ xfs_scrub_metadata_inode_forks(
 
        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;
+}