All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: Eric Sandeen <sandeen@redhat.com>
Cc: linux-xfs <linux-xfs@vger.kernel.org>
Subject: Re: [PATCH 2/6] xfs: pass xfs_dqblk to xfs_dquot_verify/xfs_dquot_repair
Date: Wed, 4 Apr 2018 20:52:41 -0700	[thread overview]
Message-ID: <20180405035241.GB7500@magnolia> (raw)
In-Reply-To: <c92cfdb8-88c2-0f5b-7383-e5208fef6f5e@redhat.com>

On Wed, Apr 04, 2018 at 01:54:26PM -0500, Eric Sandeen wrote:
> In order to validate the UUID in xfs_dquot_verify, we need
> the full xfs_qblk, not just the xfs_disk_dquot_t (which is

          ^^^^^^^^^ xfs_dqblk, right?

> a subset).
> 
> Do the same for xfs_dquot_repair, for the same reasons.
> Casting a xfs_disk_dquot to a xfs_qblk is risky if the source
> pointer wasn't a full xfs_dqblk, so enforce that by changing
> the arguments to these functions.
> 
> In xfs_qm_dqflush we move the memcpy up so that we have
> a full (and updated) xfs_dqblk to test.
> 
> Signed-off-by: Eric Sandeen <sandeen@redhat.com>
> ---
>  fs/xfs/libxfs/xfs_dquot_buf.c  | 23 +++++++++--------------
>  fs/xfs/libxfs/xfs_quota_defs.h |  4 ++--
>  fs/xfs/xfs_dquot.c             | 12 +++++++-----
>  fs/xfs/xfs_log_recover.c       |  6 ++++--
>  fs/xfs/xfs_qm.c                |  6 +++---
>  5 files changed, 25 insertions(+), 26 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_dquot_buf.c b/fs/xfs/libxfs/xfs_dquot_buf.c
> index a926058..f94e8c2 100644
> --- a/fs/xfs/libxfs/xfs_dquot_buf.c
> +++ b/fs/xfs/libxfs/xfs_dquot_buf.c
> @@ -44,11 +44,13 @@
>   */
>  xfs_failaddr_t
>  xfs_dquot_verify(
> -	struct xfs_mount *mp,
> -	xfs_disk_dquot_t *ddq,
> -	xfs_dqid_t	 id,
> -	uint		 type)	  /* used only when IO_dorepair is true */
> +	struct xfs_mount	*mp,
> +	struct xfs_dqblk	*dqb,
> +	xfs_dqid_t		id,
> +	uint			type)	  /* used only during quota rebuild */
>  {
> +	struct xfs_disk_dquot	*ddq = &dqb->dd_diskdq;
> +
>  	/*
>  	 * We can encounter an uninitialized dquot buffer for 2 reasons:
>  	 * 1. If we crash while deleting the quotainode(s), and those blks got
> @@ -104,13 +106,10 @@
>  int
>  xfs_dquot_repair(
>  	struct xfs_mount	*mp,
> -	struct xfs_disk_dquot	*ddq,
> +	struct xfs_dqblk	*d,
>  	xfs_dqid_t		id,
>  	uint			type)
>  {
> -	struct xfs_dqblk	*d = (struct xfs_dqblk *)ddq;
> -
> -
>  	/*
>  	 * Typically, a repair is only requested by quotacheck.
>  	 */
> @@ -192,14 +191,10 @@

Any way you can get your diff generator to add -p to spit out the
alleged function this chunk is supposed to land in?  It makes reviewing
patches somewhat easier for me. :)

>  	 * buffer so corruptions could point to the wrong dquot in this case.
>  	 */
>  	for (i = 0; i < ndquots; i++) {
> -		struct xfs_disk_dquot	*ddq;
> -
> -		ddq = &d[i].dd_diskdq;
> -
>  		if (i == 0)
> -			id = be32_to_cpu(ddq->d_id);
> +			id = be32_to_cpu(d[i].dd_diskdq.d_id);
>  
> -		fa = xfs_dquot_verify(mp, ddq, id + i, 0);
> +		fa = xfs_dquot_verify(mp, &d[i], id + i, 0);
>  		if (fa)
>  			return fa;
>  	}
> diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h
> index 8433656..424526a 100644
> --- a/fs/xfs/libxfs/xfs_quota_defs.h
> +++ b/fs/xfs/libxfs/xfs_quota_defs.h
> @@ -152,9 +152,9 @@
>  #define XFS_QMOPT_RESBLK_MASK	(XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS)
>  
>  extern xfs_failaddr_t xfs_dquot_verify(struct xfs_mount *mp,
> -		struct xfs_disk_dquot *ddq, xfs_dqid_t id, uint type);
> +		struct xfs_dqblk *dqb, xfs_dqid_t id, uint type);
>  extern int xfs_calc_dquots_per_chunk(unsigned int nbblks);
> -extern int xfs_dquot_repair(struct xfs_mount *mp, struct xfs_disk_dquot *ddq,
> +extern int xfs_dquot_repair(struct xfs_mount *mp, struct xfs_dqblk *dqb,
>  		xfs_dqid_t id, uint type);
>  
>  #endif	/* __XFS_QUOTA_H__ */
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 7e203f9..f7bed3c 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -955,6 +955,7 @@
>  {
>  	struct xfs_mount	*mp = dqp->q_mount;
>  	struct xfs_buf		*bp;
> +	struct xfs_dqblk	*dqb;
>  	struct xfs_disk_dquot	*ddqp;
>  	xfs_failaddr_t		fa;
>  	int			error;
> @@ -998,12 +999,16 @@
>  	/*
>  	 * Calculate the location of the dquot inside the buffer.
>  	 */
> -	ddqp = bp->b_addr + dqp->q_bufoffset;
> +	dqb = bp->b_addr + dqp->q_bufoffset;
> +	ddqp = &dqb->dd_diskdq;
> +
> +	/* This is the only portion of data that needs to persist */
> +	memcpy(ddqp, &dqp->q_core, sizeof(xfs_disk_dquot_t));
>  
>  	/*
>  	 * A simple sanity check in case we got a corrupted dquot..
>  	 */
> -	fa = xfs_dquot_verify(mp, &dqp->q_core, be32_to_cpu(ddqp->d_id), 0);
> +	fa = xfs_dquot_verify(mp, dqb, be32_to_cpu(ddqp->d_id), 0);
>  	if (fa) {
>  		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
>  				be32_to_cpu(ddqp->d_id), fa);
> @@ -1013,9 +1018,6 @@
>  		return -EIO;
>  	}
>  
> -	/* This is the only portion of data that needs to persist */
> -	memcpy(ddqp, &dqp->q_core, sizeof(xfs_disk_dquot_t));

About this memcpy() -- isn't the point of this function that we verify
the contents of the in-core q_core and only memcpy the contents into the
xfs_buf if it actually passes validation?  I guess the _dquot_verify
function needs the entire on-disk buffer so that it can validate the crc
and the uuid on a read, but we update the crc on dqflush and
(presumably) can set the uuid on write (quotacheck) or fail the dquot
read everywhere else, right?

Put another way, why not have xfs_dquot_buf_verify check the uuid?
xfs_dquot_repair seems to reset the uuid if it's garbage.

--D

> -
>  	/*
>  	 * Clear the dirty field and remember the flush lsn for later use.
>  	 */
> diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
> index 3b35feb..546df8e1 100644
> --- a/fs/xfs/xfs_log_recover.c
> +++ b/fs/xfs/xfs_log_recover.c
> @@ -3309,6 +3309,7 @@ struct xfs_buf_cancel {
>  {
>  	xfs_mount_t		*mp = log->l_mp;
>  	xfs_buf_t		*bp;
> +	struct xfs_dqblk	*dqb;
>  	struct xfs_disk_dquot	*ddq, *recddq;
>  	xfs_failaddr_t		fa;
>  	int			error;
> @@ -3322,7 +3323,8 @@ struct xfs_buf_cancel {
>  	if (mp->m_qflags == 0)
>  		return 0;
>  
> -	recddq = item->ri_buf[1].i_addr;
> +	dqb = item->ri_buf[1].i_addr;
> +	recddq = &dqb->dd_diskdq;
>  	if (recddq == NULL) {
>  		xfs_alert(log->l_mp, "NULL dquot in %s.", __func__);
>  		return -EIO;
> @@ -3353,7 +3355,7 @@ struct xfs_buf_cancel {
>  	 */
>  	dq_f = item->ri_buf[0].i_addr;
>  	ASSERT(dq_f);
> -	fa = xfs_dquot_verify(mp, recddq, dq_f->qlf_id, 0);
> +	fa = xfs_dquot_verify(mp, dqb, dq_f->qlf_id, 0);
>  	if (fa) {
>  		xfs_alert(mp, "corrupt dquot ID 0x%x in log at %pS",
>  				dq_f->qlf_id, fa);
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 64c22c32..b422382 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -859,7 +859,7 @@ struct xfs_qm_isolate {
>  	for (j = 0; j < mp->m_quotainfo->qi_dqperchunk; j++) {
>  		struct xfs_disk_dquot	*ddq;
>  
> -		ddq = (struct xfs_disk_dquot *)&dqb[j];
> +		ddq = &dqb[j].dd_diskdq;
>  
>  		/*
>  		 * Do a sanity check, and if needed, repair the dqblk. Don't
> @@ -867,9 +867,9 @@ struct xfs_qm_isolate {
>  		 * find uninitialised dquot blks. See comment in
>  		 * xfs_dquot_verify.
>  		 */
> -		fa = xfs_dquot_verify(mp, ddq, id + j, type);
> +		fa = xfs_dquot_verify(mp, &dqb[j], id + j, type);
>  		if (fa)
> -			xfs_dquot_repair(mp, ddq, id + j, type);
> +			xfs_dquot_repair(mp, &dqb[j], id + j, type);
>  
>  		/*
>  		 * Reset type in case we are reusing group quota file for
> -- 
> 1.8.3.1
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2018-04-05  3:52 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-04 18:47 [PATCH 0/6] xfs: quota fixes and enhancements Eric Sandeen
2018-04-04 18:49 ` [PATCH 1/6] xfs: remove unused flags arg from xfs_dquot_verify Eric Sandeen
2018-04-05  7:11   ` Christoph Hellwig
2018-05-01 16:13   ` Darrick J. Wong
2018-04-04 18:54 ` [PATCH 2/6] xfs: pass xfs_dqblk to xfs_dquot_verify/xfs_dquot_repair Eric Sandeen
2018-04-05  3:52   ` Darrick J. Wong [this message]
2018-04-05  4:13     ` Eric Sandeen
2018-04-05 22:40       ` Dave Chinner
2018-04-06  2:50         ` Eric Sandeen
2018-04-06  3:30           ` Dave Chinner
2018-04-11  3:28       ` Darrick J. Wong
2018-04-05  7:14   ` Christoph Hellwig
2018-05-01 16:25     ` Darrick J. Wong
2018-05-01 18:58   ` [PATCH 2/6 V2] " Eric Sandeen
2018-04-04 19:00 ` [PATCH 3/6] xfs: validate UUID and type in xfs_dquot_verify Eric Sandeen
2018-04-05  7:14   ` Christoph Hellwig
2018-05-01 16:13   ` Darrick J. Wong
2018-05-02 16:20     ` Darrick J. Wong
2018-04-04 19:06 ` [PATCH 4/6] xfs: quieter quota initialization with bad dquots Eric Sandeen
2018-04-05  7:14   ` Christoph Hellwig
2018-05-01 16:23   ` Darrick J. Wong
2018-04-04 19:10 ` [PATCH 5/6] xfs: factor out quota time limit initialization Eric Sandeen
2018-04-05  7:15   ` Christoph Hellwig
2018-04-05 12:36     ` Eric Sandeen
2018-04-05 22:49       ` Dave Chinner
2018-05-01 16:23   ` Darrick J. Wong
2018-05-01 19:00   ` [PATCH 5/6 V2] " Eric Sandeen
2018-04-04 19:12 ` [PATCH 6/6] xfs: delay quota timelimit init until after quotacheck Eric Sandeen
2018-04-05  7:16   ` Christoph Hellwig
2018-05-01 16:24   ` Darrick J. Wong
2018-04-07 22:00 ` [PATCH 0/6] xfs: quota fixes and enhancements Eric Sandeen
2018-04-08  1:37   ` Darrick J. Wong
2018-04-08  1:48     ` Eric Sandeen

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=20180405035241.GB7500@magnolia \
    --to=darrick.wong@oracle.com \
    --cc=linux-xfs@vger.kernel.org \
    --cc=sandeen@redhat.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.