Commit d9a94480 authored by Darrick J. Wong's avatar Darrick J. Wong

xfs: xfs_iget in the directory scrubber needs to use UNTRUSTED

In commit 4b80ac64, we tried to strengthen the directory scrubber by
using the iget call to detect directory entries that point to
unallocated inodes.  Unfortunately, that commit neglected to pass
XFS_IGET_UNTRUSTED to xfs_iget, so we don't check the inode btree first.
If the inode number points to something that isn't even an inode
cluster, iget will throw corruption errors and return -EFSCORRUPTED,
which means that we fail to mark the directory corrupt.

Fixes: 4b80ac64 ("xfs: scrub should mark a directory corrupt if any entries cannot be iget'd")
Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
parent 4c233b5c
...@@ -57,13 +57,15 @@ xchk_dir_check_ftype( ...@@ -57,13 +57,15 @@ xchk_dir_check_ftype(
* eofblocks cleanup (which allocates what would be a nested * eofblocks cleanup (which allocates what would be a nested
* transaction), we can't use DONTCACHE here because DONTCACHE * transaction), we can't use DONTCACHE here because DONTCACHE
* inodes can trigger immediate inactive cleanup of the inode. * inodes can trigger immediate inactive cleanup of the inode.
* Use UNTRUSTED here to check the allocation status of the inode in
* the inode btrees.
* *
* If _iget returns -EINVAL or -ENOENT then the child inode number is * If _iget returns -EINVAL or -ENOENT then the child inode number is
* garbage and the directory is corrupt. If the _iget returns * garbage and the directory is corrupt. If the _iget returns
* -EFSCORRUPTED or -EFSBADCRC then the child is corrupt which is a * -EFSCORRUPTED or -EFSBADCRC then the child is corrupt which is a
* cross referencing error. Any other error is an operational error. * cross referencing error. Any other error is an operational error.
*/ */
error = xfs_iget(mp, sc->tp, inum, 0, 0, &ip); error = xfs_iget(mp, sc->tp, inum, XFS_IGET_UNTRUSTED, 0, &ip);
if (error == -EINVAL || error == -ENOENT) { if (error == -EINVAL || error == -ENOENT) {
error = -EFSCORRUPTED; error = -EFSCORRUPTED;
xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error); xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment