From: Darrick J. Wong Date: Mon, 1 Jun 2015 01:17:39 +0000 (+1000) Subject: xfs_repair: ensure .. is set sanely when rebuilding dir X-Git-Tag: v3.2.3-rc2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=01914f06a1827e5dcc8093d1e6228d3e4ff5dc60;p=thirdparty%2Fxfsprogs-dev.git xfs_repair: ensure .. is set sanely when rebuilding dir 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 Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- diff --git a/include/xfs_dir2.h b/include/xfs_dir2.h index 3900130be..2d41c5f90 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 1bad84c40..926715f3c 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 7a984bf5b..105bce4d3 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);