diff options
Diffstat (limited to 'fs/xfs/scrub/parent_repair.c')
-rw-r--r-- | fs/xfs/scrub/parent_repair.c | 27 |
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; } |