When we're rebuilding a directory, ensure that we reinitialize the
directory with a sane parent ('..') inode value. If we don't, the
error return from xfs_dir_init() is ignored, and the rebuild process
becomes confused and leaves the directory corrupt. If repair later
discovers that the rebuilt directory is an orphan, it'll try to attach
it to lost+found and abort on the corrupted directory. Also fix
ignoring the return value of xfs_dir_init().
Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
---
include/xfs_dir2.h | 2 ++
libxfs/xfs_dir2_priv.h | 1 -
repair/phase6.c | 9 +++++++--
3 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/include/xfs_dir2.h b/include/xfs_dir2.h
index 3900130..2d41c5f 100644
--- a/include/xfs_dir2.h
+++ b/include/xfs_dir2.h
@@ -100,6 +100,8 @@ extern void xfs_dir2_data_use_free(struct xfs_trans *tp,
struct xfs_buf *bp,
extern struct xfs_dir2_data_free *xfs_dir2_data_freefind(
struct xfs_dir2_data_hdr *hdr, struct xfs_dir2_data_unused
*dup);
+extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
+
extern const struct xfs_buf_ops xfs_dir3_block_buf_ops;
extern const struct xfs_buf_ops xfs_dir3_leafn_buf_ops;
extern const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops;
diff --git a/libxfs/xfs_dir2_priv.h b/libxfs/xfs_dir2_priv.h
index 1bad84c..926715f 100644
--- a/libxfs/xfs_dir2_priv.h
+++ b/libxfs/xfs_dir2_priv.h
@@ -21,7 +21,6 @@
struct dir_context;
/* xfs_dir2.c */
-extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
xfs_dir2_db_t *dbp);
extern int xfs_dir_cilookup_result(struct xfs_da_args *args,
diff --git a/repair/phase6.c b/repair/phase6.c
index efefb2b..145e497 100644
--- a/repair/phase6.c
+++ b/repair/phase6.c
@@ -1321,7 +1321,8 @@ longform_dir2_rebuild(
* for the libxfs_dir_init() call).
*/
pip.i_ino = get_inode_parent(irec, ino_offset);
- if (pip.i_ino == NULLFSINO)
+ if (pip.i_ino == NULLFSINO ||
+ xfs_dir_ino_validate(mp, pip.i_ino))
pip.i_ino = mp->m_sb.sb_rootino;
xfs_bmap_init(&flist, &firstblock);
@@ -1348,7 +1349,11 @@ longform_dir2_rebuild(
ASSERT(done);
- libxfs_dir_init(tp, ip, &pip);
+ error = libxfs_dir_init(tp, ip, &pip);
+ if (error) {
+ do_warn(_("xfs_dir_init failed -- error - %d\n"), error);
+ goto out_bmap_cancel;
+ }
error = libxfs_bmap_finish(&tp, &flist, &committed);
|