diff mbox series

[07/43] xfs: preserve RT reservations across remounts

Message ID 20250206064511.2323878-8-hch@lst.de (mailing list archive)
State Not Applicable, archived
Headers show
Series [01/43] xfs: factor out a xfs_rt_check_size helper | expand

Commit Message

Christoph Hellwig Feb. 6, 2025, 6:44 a.m. UTC
From: Hans Holmberg <hans.holmberg@wdc.com>

Introduce a reservation setting for rt devices so that zoned GC
reservations are preserved over remount ro/rw cycles.

Signed-off-by: Hans Holmberg <hans.holmberg@wdc.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_mount.c | 30 ++++++++++++++++++++++--------
 fs/xfs/xfs_mount.h |  3 ++-
 fs/xfs/xfs_super.c |  2 +-
 3 files changed, 25 insertions(+), 10 deletions(-)

Comments

Darrick J. Wong Feb. 6, 2025, 8:14 p.m. UTC | #1
On Thu, Feb 06, 2025 at 07:44:23AM +0100, Christoph Hellwig wrote:
> From: Hans Holmberg <hans.holmberg@wdc.com>
> 
> Introduce a reservation setting for rt devices so that zoned GC
> reservations are preserved over remount ro/rw cycles.
> 
> Signed-off-by: Hans Holmberg <hans.holmberg@wdc.com>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Looks fine,
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>

--D

> ---
>  fs/xfs/xfs_mount.c | 30 ++++++++++++++++++++++--------
>  fs/xfs/xfs_mount.h |  3 ++-
>  fs/xfs/xfs_super.c |  2 +-
>  3 files changed, 25 insertions(+), 10 deletions(-)
> 
> diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
> index b81a03b3133d..26793d4f2707 100644
> --- a/fs/xfs/xfs_mount.c
> +++ b/fs/xfs/xfs_mount.c
> @@ -464,11 +464,21 @@ xfs_mount_reset_sbqflags(
>  	return xfs_sync_sb(mp, false);
>  }
>  
> +static const char *const xfs_free_pool_name[] = {
> +	[XC_FREE_BLOCKS]	= "free blocks",
> +	[XC_FREE_RTEXTENTS]	= "free rt extents",
> +};
> +
>  uint64_t
> -xfs_default_resblks(xfs_mount_t *mp)
> +xfs_default_resblks(
> +	struct xfs_mount	*mp,
> +	enum xfs_free_counter	ctr)
>  {
>  	uint64_t resblks;
>  
> +	if (ctr == XC_FREE_RTEXTENTS)
> +		return 0;
> +
>  	/*
>  	 * We default to 5% or 8192 fsbs of space reserved, whichever is
>  	 * smaller.  This is intended to cover concurrent allocation
> @@ -681,6 +691,7 @@ xfs_mountfs(
>  	uint			quotamount = 0;
>  	uint			quotaflags = 0;
>  	int			error = 0;
> +	int			i;
>  
>  	xfs_sb_mount_common(mp, sbp);
>  
> @@ -1049,18 +1060,21 @@ xfs_mountfs(
>  	 * privileged transactions. This is needed so that transaction
>  	 * space required for critical operations can dip into this pool
>  	 * when at ENOSPC. This is needed for operations like create with
> -	 * attr, unwritten extent conversion at ENOSPC, etc. Data allocations
> -	 * are not allowed to use this reserved space.
> +	 * attr, unwritten extent conversion at ENOSPC, garbage collection
> +	 * etc. Data allocations are not allowed to use this reserved space.
>  	 *
>  	 * This may drive us straight to ENOSPC on mount, but that implies
>  	 * we were already there on the last unmount. Warn if this occurs.
>  	 */
>  	if (!xfs_is_readonly(mp)) {
> -		error = xfs_reserve_blocks(mp, XC_FREE_BLOCKS,
> -				xfs_default_resblks(mp));
> -		if (error)
> -			xfs_warn(mp,
> -	"Unable to allocate reserve blocks. Continuing without reserve pool.");
> +		for (i = 0; i < XC_FREE_NR; i++) {
> +			error = xfs_reserve_blocks(mp, i,
> +					xfs_default_resblks(mp, i));
> +			if (error)
> +				xfs_warn(mp,
> +"Unable to allocate reserve blocks. Continuing without reserve pool for %s.",
> +					xfs_free_pool_name[i]);
> +		}
>  
>  		/* Reserve AG blocks for future btree expansion. */
>  		error = xfs_fs_reserve_ag_blocks(mp);
> diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
> index 300ffefb2abd..2d0e34e517b1 100644
> --- a/fs/xfs/xfs_mount.h
> +++ b/fs/xfs/xfs_mount.h
> @@ -647,7 +647,8 @@ xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d)
>  }
>  
>  extern void	xfs_uuid_table_free(void);
> -extern uint64_t xfs_default_resblks(xfs_mount_t *mp);
> +uint64_t	xfs_default_resblks(struct xfs_mount *mp,
> +			enum xfs_free_counter ctr);
>  extern int	xfs_mountfs(xfs_mount_t *mp);
>  extern void	xfs_unmountfs(xfs_mount_t *);
>  
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index f0b0d8320c51..5c9a2a0826ff 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -947,7 +947,7 @@ xfs_restore_resvblks(
>  			resblks = mp->m_resblks[i].save;
>  			mp->m_resblks[i].save = 0;
>  		} else
> -			resblks = xfs_default_resblks(mp);
> +			resblks = xfs_default_resblks(mp, i);
>  		xfs_reserve_blocks(mp, i, resblks);
>  	}
>  }
> -- 
> 2.45.2
> 
>
diff mbox series

Patch

diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index b81a03b3133d..26793d4f2707 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -464,11 +464,21 @@  xfs_mount_reset_sbqflags(
 	return xfs_sync_sb(mp, false);
 }
 
+static const char *const xfs_free_pool_name[] = {
+	[XC_FREE_BLOCKS]	= "free blocks",
+	[XC_FREE_RTEXTENTS]	= "free rt extents",
+};
+
 uint64_t
-xfs_default_resblks(xfs_mount_t *mp)
+xfs_default_resblks(
+	struct xfs_mount	*mp,
+	enum xfs_free_counter	ctr)
 {
 	uint64_t resblks;
 
+	if (ctr == XC_FREE_RTEXTENTS)
+		return 0;
+
 	/*
 	 * We default to 5% or 8192 fsbs of space reserved, whichever is
 	 * smaller.  This is intended to cover concurrent allocation
@@ -681,6 +691,7 @@  xfs_mountfs(
 	uint			quotamount = 0;
 	uint			quotaflags = 0;
 	int			error = 0;
+	int			i;
 
 	xfs_sb_mount_common(mp, sbp);
 
@@ -1049,18 +1060,21 @@  xfs_mountfs(
 	 * privileged transactions. This is needed so that transaction
 	 * space required for critical operations can dip into this pool
 	 * when at ENOSPC. This is needed for operations like create with
-	 * attr, unwritten extent conversion at ENOSPC, etc. Data allocations
-	 * are not allowed to use this reserved space.
+	 * attr, unwritten extent conversion at ENOSPC, garbage collection
+	 * etc. Data allocations are not allowed to use this reserved space.
 	 *
 	 * This may drive us straight to ENOSPC on mount, but that implies
 	 * we were already there on the last unmount. Warn if this occurs.
 	 */
 	if (!xfs_is_readonly(mp)) {
-		error = xfs_reserve_blocks(mp, XC_FREE_BLOCKS,
-				xfs_default_resblks(mp));
-		if (error)
-			xfs_warn(mp,
-	"Unable to allocate reserve blocks. Continuing without reserve pool.");
+		for (i = 0; i < XC_FREE_NR; i++) {
+			error = xfs_reserve_blocks(mp, i,
+					xfs_default_resblks(mp, i));
+			if (error)
+				xfs_warn(mp,
+"Unable to allocate reserve blocks. Continuing without reserve pool for %s.",
+					xfs_free_pool_name[i]);
+		}
 
 		/* Reserve AG blocks for future btree expansion. */
 		error = xfs_fs_reserve_ag_blocks(mp);
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 300ffefb2abd..2d0e34e517b1 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -647,7 +647,8 @@  xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d)
 }
 
 extern void	xfs_uuid_table_free(void);
-extern uint64_t xfs_default_resblks(xfs_mount_t *mp);
+uint64_t	xfs_default_resblks(struct xfs_mount *mp,
+			enum xfs_free_counter ctr);
 extern int	xfs_mountfs(xfs_mount_t *mp);
 extern void	xfs_unmountfs(xfs_mount_t *);
 
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index f0b0d8320c51..5c9a2a0826ff 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -947,7 +947,7 @@  xfs_restore_resvblks(
 			resblks = mp->m_resblks[i].save;
 			mp->m_resblks[i].save = 0;
 		} else
-			resblks = xfs_default_resblks(mp);
+			resblks = xfs_default_resblks(mp, i);
 		xfs_reserve_blocks(mp, i, resblks);
 	}
 }