xfs
[Top] [All Lists]

Re: [PATCH 1/2] xfs: don't leak EFSBADCRC to userspace

To: Dave Chinner <david@xxxxxxxxxxxxx>, xfs@xxxxxxxxxxx
Subject: Re: [PATCH 1/2] xfs: don't leak EFSBADCRC to userspace
From: Eric Sandeen <sandeen@xxxxxxxxxxx>
Date: Mon, 03 Mar 2014 11:34:35 -0600
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1393825194-1719-2-git-send-email-david@xxxxxxxxxxxxx>
References: <1393825194-1719-1-git-send-email-david@xxxxxxxxxxxxx> <1393825194-1719-2-git-send-email-david@xxxxxxxxxxxxx>
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:24.0) Gecko/20100101 Thunderbird/24.3.0
On 3/2/14, 11:39 PM, Dave Chinner wrote:
> From: Dave Chinner <dchinner@xxxxxxxxxx>
> 
> While the verifier reoutines may return EFSBADCRC when a buffer ahs
> a bad CRC, we need to translate that to EFSCORRUPTED so that the
> higher layers treat the error appropriately and so we return a
> consistent error to userspace. This fixes a xfs/005 regression.

Can you say a little more about the philosophy here?

xfs/005 regresses because it expects "structure needs cleaning"

So if we instead return our (icky) CRC error code, we get something else.

But it is truly a different root cause.

So the goal is to NEVER leak EFSBADCRC to userspace?  Maybe a comment
above that error definition would help document that.

And I'm bit worried that we'll leak more in the future if things changed,
or if things got missed here.  Everything you have here looks fine, but
it's not obvious that every path has been caught; it seems a bit random.

I know we _just_ merged my "differentiator" patches, but I wonder if
it would be better to add XFS_BSTATE_BADCRC to b_state or some other 
field, and go back to always assigning EFSCORRUPTED.  What do you think?

When I wrote those I wasn't thinking about keeping it all internal
to the filesystem.

-Eric

> Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx>
> ---
>  fs/xfs/xfs_mount.c     |  3 +++
>  fs/xfs/xfs_symlink.c   |  4 ++++
>  fs/xfs/xfs_trans_buf.c | 11 +++++++++++
>  3 files changed, 18 insertions(+)
> 
> diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
> index f96c056..993cb19 100644
> --- a/fs/xfs/xfs_mount.c
> +++ b/fs/xfs/xfs_mount.c
> @@ -314,6 +314,9 @@ reread:
>               error = bp->b_error;
>               if (loud)
>                       xfs_warn(mp, "SB validate failed with error %d.", 
> error);
> +             /* bad CRC means corrupted metadata */
> +             if (error == EFSBADCRC)
> +                     error = EFSCORRUPTED;
>               goto release_buf;
>       }
>  
> diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c
> index 14e58f2..5fda189 100644
> --- a/fs/xfs/xfs_symlink.c
> +++ b/fs/xfs/xfs_symlink.c
> @@ -80,6 +80,10 @@ xfs_readlink_bmap(
>               if (error) {
>                       xfs_buf_ioerror_alert(bp, __func__);
>                       xfs_buf_relse(bp);
> +
> +                     /* bad CRC means corrupted metadata */
> +                     if (error == EFSBADCRC)
> +                             error = EFSCORRUPTED;
>                       goto out;
>               }
>               byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
> diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
> index 647b6f1..b8eef05 100644
> --- a/fs/xfs/xfs_trans_buf.c
> +++ b/fs/xfs/xfs_trans_buf.c
> @@ -275,6 +275,10 @@ xfs_trans_read_buf_map(
>                       XFS_BUF_UNDONE(bp);
>                       xfs_buf_stale(bp);
>                       xfs_buf_relse(bp);
> +
> +                     /* bad CRC means corrupted metadata */
> +                     if (error == EFSBADCRC)
> +                             error = EFSCORRUPTED;
>                       return error;
>               }
>  #ifdef DEBUG
> @@ -338,6 +342,9 @@ xfs_trans_read_buf_map(
>                               if (tp->t_flags & XFS_TRANS_DIRTY)
>                                       xfs_force_shutdown(tp->t_mountp,
>                                                       SHUTDOWN_META_IO_ERROR);
> +                             /* bad CRC means corrupted metadata */
> +                             if (error == EFSBADCRC)
> +                                     error = EFSCORRUPTED;
>                               return error;
>                       }
>               }
> @@ -375,6 +382,10 @@ xfs_trans_read_buf_map(
>               if (tp->t_flags & XFS_TRANS_DIRTY)
>                       xfs_force_shutdown(tp->t_mountp, 
> SHUTDOWN_META_IO_ERROR);
>               xfs_buf_relse(bp);
> +
> +             /* bad CRC means corrupted metadata */
> +             if (error == EFSBADCRC)
> +                     error = EFSCORRUPTED;
>               return error;
>       }
>  #ifdef DEBUG
> 

<Prev in Thread] Current Thread [Next in Thread>