summaryrefslogtreecommitdiff
path: root/fs/xfs/scrub/parent_repair.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/scrub/parent_repair.c')
-rw-r--r--fs/xfs/scrub/parent_repair.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/fs/xfs/scrub/parent_repair.c b/fs/xfs/scrub/parent_repair.c
index 73ba8bcb63c8..28ffcee4f9e5 100644
--- a/fs/xfs/scrub/parent_repair.c
+++ b/fs/xfs/scrub/parent_repair.c
@@ -128,6 +128,10 @@ xrep_findparent_walk_directory(
if (dp == sc->ip)
return 0;
+ /* Don't mix metadata and regular directory trees. */
+ if (xfs_is_metadata_inode(dp) ^ xfs_is_metadata_inode(sc->ip))
+ return 0;
+
/*
* If we can take the parent's lock then we're ready to scan.
*
@@ -230,12 +234,27 @@ xrep_parent_confirm(
};
int error;
+ /* The root directory always points to itself. */
+ if (sc->ip == sc->mp->m_rootip) {
+ *parent_ino = sc->mp->m_sb.sb_rootino;
+ return 0;
+ }
+
+ /* The metadata root directory always points to itself. */
+ if (sc->ip == sc->mp->m_metadirip) {
+ *parent_ino = sc->mp->m_sb.sb_metadirino;
+ return 0;
+ }
+
/*
- * The root directory always points to itself. Unlinked dirs can point
- * anywhere, so we point them at the root dir too.
+ * Unlinked dirs can point anywhere, so we point them at the root dir
+ * of whichever tree is appropriate.
*/
- if (sc->ip == sc->mp->m_rootip || VFS_I(sc->ip)->i_nlink == 0) {
- *parent_ino = sc->mp->m_sb.sb_rootino;
+ if (VFS_I(sc->ip)->i_nlink == 0) {
+ if (xfs_is_metadata_inode(sc->ip))
+ *parent_ino = sc->mp->m_sb.sb_metadirino;
+ else
+ *parent_ino = sc->mp->m_sb.sb_rootino;
return 0;
}