@@ -362,7 +362,8 @@ xchk_dirpath_set_outcome(
362362STATIC int
363363xchk_dirpath_step_up (
364364 struct xchk_dirtree * dl ,
365- struct xchk_dirpath * path )
365+ struct xchk_dirpath * path ,
366+ bool is_metadir )
366367{
367368 struct xfs_scrub * sc = dl -> sc ;
368369 struct xfs_inode * dp ;
@@ -435,6 +436,14 @@ xchk_dirpath_step_up(
435436 goto out_scanlock ;
436437 }
437438
439+ /* Parent must be in the same directory tree. */
440+ if (is_metadir != xfs_is_metadir_inode (dp )) {
441+ trace_xchk_dirpath_crosses_tree (dl -> sc , dp , path -> path_nr ,
442+ path -> nr_steps , & dl -> xname , & dl -> pptr_rec );
443+ error = - EFSCORRUPTED ;
444+ goto out_scanlock ;
445+ }
446+
438447 /*
439448 * If the extended attributes look as though they has been zapped by
440449 * the inode record repair code, we cannot scan for parent pointers.
@@ -508,6 +517,7 @@ xchk_dirpath_walk_upwards(
508517 struct xchk_dirpath * path )
509518{
510519 struct xfs_scrub * sc = dl -> sc ;
520+ bool is_metadir ;
511521 int error ;
512522
513523 ASSERT (sc -> ilock_flags & XFS_ILOCK_EXCL );
@@ -538,6 +548,7 @@ xchk_dirpath_walk_upwards(
538548 * ILOCK state is no longer tracked in the scrub context. Hence we
539549 * must drop @sc->ip's ILOCK during the walk.
540550 */
551+ is_metadir = xfs_is_metadir_inode (sc -> ip );
541552 mutex_unlock (& dl -> lock );
542553 xchk_iunlock (sc , XFS_ILOCK_EXCL );
543554
@@ -547,7 +558,7 @@ xchk_dirpath_walk_upwards(
547558 * If we see any kind of error here (including corruptions), the parent
548559 * pointer of @sc->ip is corrupt. Stop the whole scan.
549560 */
550- error = xchk_dirpath_step_up (dl , path );
561+ error = xchk_dirpath_step_up (dl , path , is_metadir );
551562 if (error ) {
552563 xchk_ilock (sc , XFS_ILOCK_EXCL );
553564 mutex_lock (& dl -> lock );
@@ -560,7 +571,7 @@ xchk_dirpath_walk_upwards(
560571 * *somewhere* in the path, but we don't need to stop scanning.
561572 */
562573 while (!error && path -> outcome == XCHK_DIRPATH_SCANNING )
563- error = xchk_dirpath_step_up (dl , path );
574+ error = xchk_dirpath_step_up (dl , path , is_metadir );
564575
565576 /* Retake the locks we had, mark paths, etc. */
566577 xchk_ilock (sc , XFS_ILOCK_EXCL );
0 commit comments