|
@@ -214,7 +214,9 @@ xfs_scrub_parent_validate(
|
|
|
*/
|
|
|
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);
|
|
@@ -223,8 +225,10 @@ xfs_scrub_parent_validate(
|
|
|
|
|
|
/* 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
|
|
@@ -326,5 +330,13 @@ xfs_scrub_parent(
|
|
|
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;
|
|
|
}
|