summaryrefslogtreecommitdiff
path: root/fs/xfs/scrub/dir_repair.c
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2021-01-05 17:45:18 -0800
committerDarrick J. Wong <djwong@kernel.org>2021-03-25 17:08:30 -0700
commit6fe04e9be9541e905a6dfd553a91bda4d7885d8f (patch)
tree3093eaee56f389e5a8b22dc7b8f14f73383e5aeb /fs/xfs/scrub/dir_repair.c
parent1cab245f01e970a95bd46338583596b9631288e0 (diff)
xfs: online repair of parent pointers
Teach the online repair code to fix directory '..' entries (aka directory parent pointers). Since this requires us to know how to scan every dirent in every directory on the filesystem, we can reuse the parent scanner components to validate (or find!) the correct parent entry when rebuilding directories too. Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs/scrub/dir_repair.c')
-rw-r--r--fs/xfs/scrub/dir_repair.c40
1 files changed, 6 insertions, 34 deletions
diff --git a/fs/xfs/scrub/dir_repair.c b/fs/xfs/scrub/dir_repair.c
index 7c971501043c..e6b66daae289 100644
--- a/fs/xfs/scrub/dir_repair.c
+++ b/fs/xfs/scrub/dir_repair.c
@@ -35,6 +35,7 @@
#include "scrub/repair.h"
#include "scrub/array.h"
#include "scrub/blob.h"
+#include "scrub/parent.h"
/*
* Directory Repair
@@ -1061,36 +1062,6 @@ xrep_dir_rebuild_tree(
}
/*
- * Make sure we return with a valid parent inode.
- *
- * If the directory salvaging step found a single '..' entry, check the alleged
- * parent for a dentry pointing to the directory. If this succeeds, we're
- * done. Otherwise, scan the entire filesystem for a parent.
- */
-STATIC int
-xrep_dir_validate_parent(
- struct xrep_dir *rd)
-{
- struct xfs_scrub *sc = rd->sc;
-
- /*
- * If we're the root directory, we are our own parent. If we're an
- * unlinked directory, the parent /won't/ have a link to us. Set the
- * parent directory to the root for both cases.
- */
- if (rd->sc->ip->i_ino == sc->mp->m_sb.sb_rootino ||
- VFS_I(rd->sc->ip)->i_nlink == 0) {
- rd->parent_ino = sc->mp->m_sb.sb_rootino;
- return 0;
- }
-
- if (!xfs_verify_dir_ino(sc->mp, rd->parent_ino))
- return -EFSCORRUPTED;
-
- return 0;
-}
-
-/*
* Repair the directory metadata.
*
* XXX: Directory entry buffers can be multiple fsblocks in size. The buffer
@@ -1166,11 +1137,13 @@ xrep_dir(
/*
* Validate the parent pointer that we observed while salvaging the
- * directory; or scan the filesystem to find one.
+ * directory; or scan the filesystem to find one. If we can't find
+ * one, we'll set a bogus parent and let the parent pointer repair
+ * fix it.
*/
- error = xrep_dir_validate_parent(&rd);
+ error = xrep_dir_parent_find(rd.sc, &rd.parent_ino);
if (error)
- goto out;
+ return error;
/* Now rebuild the directory information. */
return xrep_dir_rebuild_tree(&rd);
@@ -1179,6 +1152,5 @@ out_names:
xblob_destroy(rd.dir_names);
out_arr:
xfbma_destroy(rd.dir_entries);
-out:
return error;
}