return error;
 }
 
+/*
+ * Grab the exclusive iolock for a data copy from src to dest, making
+ * sure to abide vfs locking order (lowest pointer value goes first) and
+ * breaking the pnfs layout leases on dest before proceeding.  The loop
+ * is needed because we cannot call the blocking break_layout() with the
+ * src iolock held, and therefore have to back out both locks.
+ */
+static int
+xfs_iolock_two_inodes_and_break_layout(
+       struct inode            *src,
+       struct inode            *dest)
+{
+       int                     error;
+
+retry:
+       if (src < dest) {
+               inode_lock(src);
+               inode_lock_nested(dest, I_MUTEX_NONDIR2);
+       } else {
+               /* src >= dest */
+               inode_lock(dest);
+       }
+
+       error = break_layout(dest, false);
+       if (error == -EWOULDBLOCK) {
+               inode_unlock(dest);
+               if (src < dest)
+                       inode_unlock(src);
+               error = break_layout(dest, true);
+               if (error)
+                       return error;
+               goto retry;
+       }
+       if (error) {
+               inode_unlock(dest);
+               if (src < dest)
+                       inode_unlock(src);
+               return error;
+       }
+       if (src > dest)
+               inode_lock_nested(src, I_MUTEX_NONDIR2);
+       return 0;
+}
+
 /*
  * Link a range of blocks from one file to another.
  */
                return -EIO;
 
        /* Lock both files against IO */
-       lock_two_nondirectories(inode_in, inode_out);
+       ret = xfs_iolock_two_inodes_and_break_layout(inode_in, inode_out);
+       if (ret)
+               return ret;
        if (same_inode)
                xfs_ilock(src, XFS_MMAPLOCK_EXCL);
        else