All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: cem@kernel.org
Cc: linux-xfs@vger.kernel.org, david@fromorbit.com,
	dchinner@redhat.com, hch@lst.de
Subject: Re: [PATCH V2] xfs: Do not allow norecovery mount with quotacheck
Date: Fri, 31 Jan 2025 08:18:06 -0800	[thread overview]
Message-ID: <20250131161806.GU1611770@frogsfrogsfrogs> (raw)
In-Reply-To: <20250131100302.15430-1-cem@kernel.org>

On Fri, Jan 31, 2025 at 11:02:54AM +0100, cem@kernel.org wrote:
> From: Carlos Maiolino <cem@kernel.org>
> 
> Mounting a filesystem that requires quota state changing will generate a
> transaction.
> 
> We already check for a read-only device; we should do that for
> norecovery too.
> 
> A quotacheck on a norecovery mount, and with the right log size, will cause
> the mount process to hang on:
> 
> [<0>] xlog_grant_head_wait+0x5d/0x2a0 [xfs]
> [<0>] xlog_grant_head_check+0x112/0x180 [xfs]
> [<0>] xfs_log_reserve+0xe3/0x260 [xfs]
> [<0>] xfs_trans_reserve+0x179/0x250 [xfs]
> [<0>] xfs_trans_alloc+0x101/0x260 [xfs]
> [<0>] xfs_sync_sb+0x3f/0x80 [xfs]
> [<0>] xfs_qm_mount_quotas+0xe3/0x2f0 [xfs]
> [<0>] xfs_mountfs+0x7ad/0xc20 [xfs]
> [<0>] xfs_fs_fill_super+0x762/0xa50 [xfs]
> [<0>] get_tree_bdev_flags+0x131/0x1d0
> [<0>] vfs_get_tree+0x26/0xd0
> [<0>] vfs_cmd_create+0x59/0xe0
> [<0>] __do_sys_fsconfig+0x4e3/0x6b0
> [<0>] do_syscall_64+0x82/0x160
> [<0>] entry_SYSCALL_64_after_hwframe+0x76/0x7e
> 
> This is caused by a transaction running with bogus initialized head/tail
> 
> I initially hit this while running generic/050, with random log
> sizes, but I managed to reproduce it reliably here with the steps
> below:
> 
> mkfs.xfs -f -lsize=1025M -f -b size=4096 -m crc=1,reflink=1,rmapbt=1, -i
> sparse=1 /dev/vdb2 > /dev/null
> mount -o usrquota,grpquota,prjquota /dev/vdb2 /mnt
> xfs_io -x -c 'shutdown -f' /mnt
> umount /mnt
> mount -o ro,norecovery,usrquota,grpquota,prjquota  /dev/vdb2 /mnt
> 
> Last mount hangs up
> 
> As we add yet another validation if quota state is changing, this also
> add a new helper named xfs_qm_validate(), factoring the quota state
> changes out of xfs_qm_newmount() to reduce cluttering within it.
> 
> As per Darrick suggestion, add a new, different  warning message if
> metadir is enabled.
> 
> Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
> Signed-off-by: Carlos Maiolino <cem@kernel.org>
> ---
> 
> Changelog V1->V2:
> 	- Issue a different warn message in case metadir is enabled
> 	- Factour out quota state validator code to a new helper
> 	- Change patch subject to reduce length
> 
> 
>  fs/xfs/xfs_qm_bhv.c | 55 ++++++++++++++++++++++++++++++++-------------
>  1 file changed, 39 insertions(+), 16 deletions(-)
> 
> diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c
> index 37f1230e7584..a6a7870401c3 100644
> --- a/fs/xfs/xfs_qm_bhv.c
> +++ b/fs/xfs/xfs_qm_bhv.c
> @@ -78,6 +78,28 @@ xfs_qm_statvfs(
>  	}
>  }
>  
> +STATIC int
> +xfs_qm_validate(

This validates ... what exactly?

Oh, it validates that we can actually make the state change.

xfs_qm_validate_state_change(), perhaps ?

> +	xfs_mount_t	*mp,

Please don't introduce more typedef usage.

	struct xfs_mount	*mp,

> +	uint		uqd,
> +	uint		gqd,
> +	uint		pqd)
> +{
> +	int state;
> +
> +	/* Is quota state changing? */
> +	state = ((uqd && !XFS_IS_UQUOTA_ON(mp)) ||
> +		(!uqd &&  XFS_IS_UQUOTA_ON(mp)) ||
> +		 (gqd && !XFS_IS_GQUOTA_ON(mp)) ||
> +		(!gqd &&  XFS_IS_GQUOTA_ON(mp)) ||
> +		 (pqd && !XFS_IS_PQUOTA_ON(mp)) ||
> +		(!pqd &&  XFS_IS_PQUOTA_ON(mp)));
> +
> +	return  state &&
> +		(xfs_dev_is_read_only(mp, "changing quota state") ||
> +		xfs_has_norecovery(mp));
> +}
> +
>  int
>  xfs_qm_newmount(
>  	xfs_mount_t	*mp,
> @@ -97,24 +119,25 @@ xfs_qm_newmount(
>  	}
>  
>  	/*
> -	 * If the device itself is read-only, we can't allow
> -	 * the user to change the state of quota on the mount -
> -	 * this would generate a transaction on the ro device,
> -	 * which would lead to an I/O error and shutdown
> +	 * If the device itself is read-only and/or in norecovery
> +	 * mode, we can't allow the user to change the state of
> +	 * quota on the mount - this would generate a transaction
> +	 * on the ro device, which would lead to an I/O error and
> +	 * shutdown.
>  	 */
>  
> -	if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) ||
> -	    (!uquotaondisk &&  XFS_IS_UQUOTA_ON(mp)) ||
> -	     (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) ||
> -	    (!gquotaondisk &&  XFS_IS_GQUOTA_ON(mp)) ||
> -	     (pquotaondisk && !XFS_IS_PQUOTA_ON(mp)) ||
> -	    (!pquotaondisk &&  XFS_IS_PQUOTA_ON(mp)))  &&
> -	    xfs_dev_is_read_only(mp, "changing quota state")) {
> -		xfs_warn(mp, "please mount with%s%s%s%s.",
> -			(!quotaondisk ? "out quota" : ""),
> -			(uquotaondisk ? " usrquota" : ""),
> -			(gquotaondisk ? " grpquota" : ""),
> -			(pquotaondisk ? " prjquota" : ""));
> +	if (xfs_qm_validate(mp, uquotaondisk,
> +			    gquotaondisk, pquotaondisk)) {
> +
> +		if (xfs_has_metadir(mp))
> +			xfs_warn(mp,
> +			       "metadir enabled, please mount withouth quotas");

"metadir enabled, please mount without any quota mount options"

--D

> +		else
> +			xfs_warn(mp, "please mount with%s%s%s%s.",
> +				(!quotaondisk ? "out quota" : ""),
> +				(uquotaondisk ? " usrquota" : ""),
> +				(gquotaondisk ? " grpquota" : ""),
> +				(pquotaondisk ? " prjquota" : ""));
>  		return -EPERM;
>  	}
>  
> -- 
> 2.48.1
> 
> 

  reply	other threads:[~2025-01-31 16:18 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-31 10:02 [PATCH V2] xfs: Do not allow norecovery mount with quotacheck cem
2025-01-31 16:18 ` Darrick J. Wong [this message]
2025-01-31 16:27   ` Carlos Maiolino

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=20250131161806.GU1611770@frogsfrogsfrogs \
    --to=djwong@kernel.org \
    --cc=cem@kernel.org \
    --cc=david@fromorbit.com \
    --cc=dchinner@redhat.com \
    --cc=hch@lst.de \
    --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 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.