From: Darrick J. Wong <djwong@xxxxxxxxxx> A couple of patches from now we're going to reuse the path_walk code in a new xfs_db subcommand that tries to recover directory trees from old/damaged filesystems. Let's pass around an empty transaction to try too avoid livelocks on malicious/broken metadata. This is not completely foolproof, but it's quick enough for most purposes. Signed-off-by: "Darrick J. Wong" <djwong@xxxxxxxxxx> --- db/namei.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/db/namei.c b/db/namei.c index 00610a54af527e..22eae50f219fd0 100644 --- a/db/namei.c +++ b/db/namei.c @@ -87,15 +87,20 @@ path_navigate( xfs_ino_t rootino, struct dirpath *dirpath) { + struct xfs_trans *tp; struct xfs_inode *dp; xfs_ino_t ino = rootino; unsigned int i; int error; - error = -libxfs_iget(mp, NULL, ino, 0, &dp); + error = -libxfs_trans_alloc_empty(mp, &tp); if (error) return error; + error = -libxfs_iget(mp, tp, ino, 0, &dp); + if (error) + goto out_trans; + for (i = 0; i < dirpath->depth; i++) { struct xfs_name xname = { .name = (unsigned char *)dirpath->path[i], @@ -104,35 +109,37 @@ path_navigate( if (!S_ISDIR(VFS_I(dp)->i_mode)) { error = ENOTDIR; - goto rele; + goto out_rele; } - error = -libxfs_dir_lookup(NULL, dp, &xname, &ino, NULL); + error = -libxfs_dir_lookup(tp, dp, &xname, &ino, NULL); if (error) - goto rele; + goto out_rele; if (!xfs_verify_ino(mp, ino)) { error = EFSCORRUPTED; - goto rele; + goto out_rele; } libxfs_irele(dp); dp = NULL; - error = -libxfs_iget(mp, NULL, ino, 0, &dp); + error = -libxfs_iget(mp, tp, ino, 0, &dp); switch (error) { case EFSCORRUPTED: case EFSBADCRC: case 0: break; default: - return error; + goto out_trans; } } set_cur_inode(ino); -rele: +out_rele: if (dp) libxfs_irele(dp); +out_trans: + libxfs_trans_cancel(tp); return error; }