diff mbox series

[RFC,3/4] xfs: introduce max_agcount

Message ID 20210414195240.1802221-4-hsiangkao@redhat.com (mailing list archive)
State New
Headers show
Series xfs: support shrinking empty AGs | expand

Commit Message

Gao Xiang April 14, 2021, 7:52 p.m. UTC
After shrinking, some inactive AGs won't be valid anymore except
that these perags are still here. Introduce a new m_maxagcount
mainly used for freeing all perags.

Signed-off-by: Gao Xiang <hsiangkao@redhat.com>
---
 fs/xfs/libxfs/xfs_alloc.c  | 2 +-
 fs/xfs/libxfs/xfs_bmap.c   | 8 ++++----
 fs/xfs/libxfs/xfs_ialloc.c | 2 +-
 fs/xfs/libxfs/xfs_sb.c     | 1 +
 fs/xfs/xfs_extent_busy.c   | 2 +-
 fs/xfs/xfs_mount.c         | 4 ++--
 fs/xfs/xfs_mount.h         | 1 +
 fs/xfs/xfs_trans.c         | 2 ++
 8 files changed, 13 insertions(+), 9 deletions(-)

Comments

Dave Chinner April 15, 2021, 3:59 a.m. UTC | #1
On Thu, Apr 15, 2021 at 03:52:39AM +0800, Gao Xiang wrote:
> After shrinking, some inactive AGs won't be valid anymore except
> that these perags are still here. Introduce a new m_maxagcount
> mainly used for freeing all perags.

With active/passive perag references, I don't think this is
necessary anymore. By the time we get to changing
mp->m_sb.sb_agblocks, we've already guaranteed that there is nothing
referencing the perag structures we are about to get rid of. And
if we do a lookup on a agno we've already removed, it'll fail anyway
because that perag can't be found in the radix tree....

Cheers,

Dave.
diff mbox series

Patch

diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index 60a8c134c00e..a493aaa955d7 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -3220,7 +3220,7 @@  xfs_alloc_vextent(
 		args->maxlen = agsize;
 	if (args->alignment == 0)
 		args->alignment = 1;
-	ASSERT(XFS_FSB_TO_AGNO(mp, args->fsbno) < mp->m_sb.sb_agcount);
+	ASSERT(XFS_FSB_TO_AGNO(mp, args->fsbno) < mp->m_maxagcount);
 	ASSERT(XFS_FSB_TO_AGBNO(mp, args->fsbno) < agsize);
 	ASSERT(args->minlen <= args->maxlen);
 	ASSERT(args->minlen <= agsize);
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 5574d345d066..abbb2a8aa0c0 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -350,7 +350,7 @@  xfs_bmap_check_leaf_extents(
 	bno = be64_to_cpu(*pp);
 
 	ASSERT(bno != NULLFSBLOCK);
-	ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
+	ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_maxagcount);
 	ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
 
 	/*
@@ -546,7 +546,7 @@  __xfs_bmap_add_free(
 	ASSERT(!isnullstartblock(bno));
 	agno = XFS_FSB_TO_AGNO(mp, bno);
 	agbno = XFS_FSB_TO_AGBNO(mp, bno);
-	ASSERT(agno < mp->m_sb.sb_agcount);
+	ASSERT(agno < mp->m_maxagcount);
 	ASSERT(agbno < mp->m_sb.sb_agblocks);
 	ASSERT(len < mp->m_sb.sb_agblocks);
 	ASSERT(agbno + len <= mp->m_sb.sb_agblocks);
@@ -3129,7 +3129,7 @@  xfs_bmap_adjacent(
 	(rt ? \
 		(x) < mp->m_sb.sb_rblocks : \
 		XFS_FSB_TO_AGNO(mp, x) == XFS_FSB_TO_AGNO(mp, y) && \
-		XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \
+		XFS_FSB_TO_AGNO(mp, x) < mp->m_maxagcount && \
 		XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks)
 
 	mp = ap->ip->i_mount;
@@ -3353,7 +3353,7 @@  xfs_bmap_btalloc_nullfb(
 		if (error)
 			return error;
 
-		if (++ag == mp->m_sb.sb_agcount)
+		if (++ag == mp->m_maxagcount)
 			ag = 0;
 		if (ag == startag)
 			break;
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
index 4df218eeb088..2b80dcb428bf 100644
--- a/fs/xfs/libxfs/xfs_ialloc.c
+++ b/fs/xfs/libxfs/xfs_ialloc.c
@@ -1852,7 +1852,7 @@  xfs_dialloc_select_ag(
 nextag:
 		up_read(&pag->pag_inactive_rwsem);
 		xfs_perag_put(pag);
-		if (++agno == mp->m_sb.sb_agcount)
+		if (++agno == mp->m_maxagcount)
 			agno = 0;
 		if (agno == start_agno)
 			return noroom ? -ENOSPC : 0;
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index 60e6d255e5e2..6062b799d1e0 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -807,6 +807,7 @@  xfs_sb_mount_common(
 	struct xfs_sb		*sbp)
 {
 	mp->m_agfrotor = mp->m_agirotor = 0;
+	mp->m_maxagcount = mp->m_sb.sb_agcount;
 	mp->m_maxagi = mp->m_sb.sb_agcount;
 	mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG;
 	mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
diff --git a/fs/xfs/xfs_extent_busy.c b/fs/xfs/xfs_extent_busy.c
index ef17c1f6db32..b6d9d6e6da90 100644
--- a/fs/xfs/xfs_extent_busy.c
+++ b/fs/xfs/xfs_extent_busy.c
@@ -608,7 +608,7 @@  xfs_extent_busy_wait_all(
 	DEFINE_WAIT		(wait);
 	xfs_agnumber_t		agno;
 
-	for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
+	for (agno = 0; agno < mp->m_maxagcount; agno++) {
 		struct xfs_perag *pag = xfs_perag_get(mp, agno);
 
 		do {
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index f86360514828..69a60b5f4a32 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -141,7 +141,7 @@  xfs_free_perag(
 	xfs_agnumber_t	agno;
 	struct xfs_perag *pag;
 
-	for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
+	for (agno = 0; agno < mp->m_maxagcount; agno++) {
 		spin_lock(&mp->m_perag_lock);
 		pag = radix_tree_delete(&mp->m_perag_tree, agno);
 		spin_unlock(&mp->m_perag_lock);
@@ -633,7 +633,7 @@  xfs_check_summary_counts(
 	    !xfs_fs_has_sickness(mp, XFS_SICK_FS_COUNTERS))
 		return 0;
 
-	return xfs_initialize_perag_data(mp, mp->m_sb.sb_agcount);
+	return xfs_initialize_perag_data(mp, mp->m_maxagcount);
 }
 
 /*
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 667dae0acaf9..6bc1cedd4cd5 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -192,6 +192,7 @@  typedef struct xfs_mount {
 	 */
 	struct work_struct	m_flush_inodes_work;
 
+	xfs_agnumber_t		m_maxagcount;
 	/*
 	 * Generation of the filesysyem layout.  This is incremented by each
 	 * growfs, and used by the pNFS server to ensure the client updates
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index bc25afc10245..1d37de86fc09 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -632,6 +632,8 @@  xfs_trans_unreserve_and_mod_sb(
 	mp->m_sb.sb_frextents += rtxdelta;
 	mp->m_sb.sb_dblocks += tp->t_dblocks_delta;
 	mp->m_sb.sb_agcount += tp->t_agcount_delta;
+	if (mp->m_sb.sb_agcount > mp->m_maxagcount)
+		mp->m_maxagcount = mp->m_sb.sb_agcount;
 	mp->m_sb.sb_imax_pct += tp->t_imaxpct_delta;
 	mp->m_sb.sb_rextsize += tp->t_rextsize_delta;
 	mp->m_sb.sb_rbmblocks += tp->t_rbmblocks_delta;