public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Dave Chinner <david@fromorbit.com>
To: "Darrick J. Wong" <darrick.wong@oracle.com>
Cc: linux-xfs@vger.kernel.org
Subject: Re: [PATCH 3/3] xfs: scrub should mark dir corrupt if entry points to unallocated inode
Date: Wed, 4 Mar 2020 09:39:07 +1100	[thread overview]
Message-ID: <20200303223907.GX10776@dread.disaster.area> (raw)
In-Reply-To: <158294096213.1730101.1870315264682758950.stgit@magnolia>

On Fri, Feb 28, 2020 at 05:49:22PM -0800, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> In xchk_dir_check_ftype, we should mark the directory corrupt if we try
> to _iget a directory entry's inode pointer and the inode btree says the
> inode is not allocated.  This involves changing the IGET call to force
> the inobt lookup to return EINVAL if the inode isn't allocated; and
> rearranging the code so that we always perform the iget.

There's also a bug fix in this that isn't mentioned...

> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/scrub/dir.c |   43 ++++++++++++++++++++++++++-----------------
>  1 file changed, 26 insertions(+), 17 deletions(-)
> 
> 
> diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
> index 54afa75c95d1..a775fbf49a0d 100644
> --- a/fs/xfs/scrub/dir.c
> +++ b/fs/xfs/scrub/dir.c
> @@ -39,9 +39,12 @@ struct xchk_dir_ctx {
>  	struct xfs_scrub	*sc;
>  };
>  
> -/* Check that an inode's mode matches a given DT_ type. */
> +/*
> + * Check that a directory entry's inode pointer directs us to an allocated
> + * inode and (if applicable) the inode mode matches the entry's DT_ type.
> + */
>  STATIC int
> -xchk_dir_check_ftype(
> +xchk_dir_check_iptr(
>  	struct xchk_dir_ctx	*sdc,
>  	xfs_fileoff_t		offset,
>  	xfs_ino_t		inum,
> @@ -52,13 +55,6 @@ xchk_dir_check_ftype(
>  	int			ino_dtype;
>  	int			error = 0;
>  
> -	if (!xfs_sb_version_hasftype(&mp->m_sb)) {
> -		if (dtype != DT_UNKNOWN && dtype != DT_DIR)
> -			xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK,
> -					offset);
> -		goto out;
> -	}
> -
>  	/*
>  	 * Grab the inode pointed to by the dirent.  We release the
>  	 * inode before we cancel the scrub transaction.  Since we're
> @@ -66,17 +62,30 @@ xchk_dir_check_ftype(
>  	 * eofblocks cleanup (which allocates what would be a nested
>  	 * transaction), we can't use DONTCACHE here because DONTCACHE
>  	 * inodes can trigger immediate inactive cleanup of the inode.
> +	 *
> +	 * We use UNTRUSTED here so that iget will return EINVAL if we have an
> +	 * inode pointer that points to an unallocated inode.

"We use UNTRUSTED here to force validation of the inode number
before we look it up. If it fails validation for any reason we will
get -EINVAL returned and that indicates a corrupt directory entry."

>  	 */
> -	error = xfs_iget(mp, sdc->sc->tp, inum, 0, 0, &ip);
> +	error = xfs_iget(mp, sdc->sc->tp, inum, XFS_IGET_UNTRUSTED, 0, &ip);
> +	if (error == -EINVAL) {
> +		xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset);
> +		return -EFSCORRUPTED;
> +	}
>  	if (!xchk_fblock_xref_process_error(sdc->sc, XFS_DATA_FORK, offset,
>  			&error))
>  		goto out;

Also:
	if (error == -EINVAL)
		error = -EFSCORRUPTED;


>  
> -	/* Convert mode to the DT_* values that dir_emit uses. */
> -	ino_dtype = xfs_dir3_get_dtype(mp,
> -			xfs_mode_to_ftype(VFS_I(ip)->i_mode));
> -	if (ino_dtype != dtype)
> -		xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset);
> +	if (xfs_sb_version_hasftype(&mp->m_sb)) {
> +		/* Convert mode to the DT_* values that dir_emit uses. */
> +		ino_dtype = xfs_dir3_get_dtype(mp,
> +				xfs_mode_to_ftype(VFS_I(ip)->i_mode));
> +		if (ino_dtype != dtype)
> +			xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset);
> +	} else {
> +		if (dtype != DT_UNKNOWN && dtype != DT_DIR)
> +			xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK,
> +					offset);
> +	}

What is this fixing? xfs_dir3_get_dtype() always returned DT_UNKNOWN
for !hasftype filesystems, so I'm guessing this fixes validation
against dtype == DT_DIR for "." and ".." entries, but didn't we
already check this in xchk_dir_actor() before it calls this
function?

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

  parent reply	other threads:[~2020-03-03 22:39 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-29  1:49 [PATCH 0/3] xfs: fix errors in attr/directory scrubbers Darrick J. Wong
2020-02-29  1:49 ` [PATCH 1/3] xfs: mark dir corrupt when lookup-by-hash fails Darrick J. Wong
2020-03-02 17:43   ` Allison Collins
2020-03-03 22:26   ` Dave Chinner
2020-03-03 22:57     ` Darrick J. Wong
2020-02-29  1:49 ` [PATCH 2/3] xfs: mark extended attr " Darrick J. Wong
2020-03-02 17:44   ` Allison Collins
2020-03-03 22:26   ` Dave Chinner
2020-03-03 22:58     ` Darrick J. Wong
2020-02-29  1:49 ` [PATCH 3/3] xfs: scrub should mark dir corrupt if entry points to unallocated inode Darrick J. Wong
2020-03-02 17:44   ` Allison Collins
2020-03-03 22:39   ` Dave Chinner [this message]
2020-03-03 23:06     ` Darrick J. Wong
  -- strict thread matches above, loose matches on Subject: below --
2020-03-11  0:48 [PATCH v2 0/3] xfs: fix errors in attr/directory scrubbers Darrick J. Wong
2020-03-11  0:48 ` [PATCH 3/3] xfs: scrub should mark dir corrupt if entry points to unallocated inode Darrick J. Wong
2020-03-11  5:55   ` Dave Chinner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200303223907.GX10776@dread.disaster.area \
    --to=david@fromorbit.com \
    --cc=darrick.wong@oracle.com \
    --cc=linux-xfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox