All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: djwong@kernel.org
Cc: linux-xfs@vger.kernel.org
Subject: [PATCH 3/5] xfs: automatic resource cleanup of for_each_perag*
Date: Thu, 05 Aug 2021 00:01:00 -0700	[thread overview]
Message-ID: <162814685996.2777088.11268635137040103857.stgit@magnolia> (raw)
In-Reply-To: <162814684332.2777088.14593133806068529811.stgit@magnolia>

From: Darrick J. Wong <djwong@kernel.org>

Jan Kara pointed me to a magic gcc attribute that schedules a finalizer
function to run against any automatic variable that's going out of
scope.  Provided nobody minds compiling XFS with gnu99 instead of c89,
we can use this capability to define a loop-scope iterator variable that
will trigger the automatic finalizer, which means that we don't have to
burden for_each_perag* callers with the necessity of manually putting
the perag structures when exiting the loop body.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 fs/xfs/Makefile           |    3 ++
 fs/xfs/libxfs/xfs_ag.h    |   66 +++++++++++++++++++++++++++++----------------
 fs/xfs/libxfs/xfs_sb.c    |   17 ++++++------
 fs/xfs/libxfs/xfs_types.c |    6 +---
 fs/xfs/scrub/bmap.c       |    8 +----
 fs/xfs/scrub/fscounters.c |   41 ++++++++++++----------------
 fs/xfs/xfs_extent_busy.c  |   11 +++-----
 fs/xfs/xfs_fsmap.c        |   25 ++++++-----------
 fs/xfs/xfs_fsops.c        |   12 +++-----
 fs/xfs/xfs_health.c       |    9 +++---
 fs/xfs/xfs_icache.c       |   27 ++++++------------
 fs/xfs/xfs_iwalk.c        |   41 +++++++++++-----------------
 fs/xfs/xfs_log_recover.c  |   21 ++++++--------
 fs/xfs/xfs_reflink.c      |   10 ++-----
 14 files changed, 135 insertions(+), 162 deletions(-)


diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 04611a1068b4..e482cb43743d 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -7,6 +7,9 @@
 ccflags-y += -I $(srctree)/$(src)		# needed for trace events
 ccflags-y += -I $(srctree)/$(src)/libxfs
 
+# Required for for_each_perag*
+ccflags-y += -std=gnu99
+
 obj-$(CONFIG_XFS_FS)		+= xfs.o
 
 # this one should be compiled first, as the tracing macros can easily blow up
diff --git a/fs/xfs/libxfs/xfs_ag.h b/fs/xfs/libxfs/xfs_ag.h
index 4c6f9045baca..5141e8936912 100644
--- a/fs/xfs/libxfs/xfs_ag.h
+++ b/fs/xfs/libxfs/xfs_ag.h
@@ -116,35 +116,53 @@ void xfs_perag_put(struct xfs_perag *pag);
 
 /*
  * Perag iteration APIs
- *
- * XXX: for_each_perag_range() usage really needs an iterator to clean up when
- * we terminate at end_agno because we may have taken a reference to the perag
- * beyond end_agno. Right now callers have to be careful to catch and clean that
- * up themselves. This is not necessary for the callers of for_each_perag() and
- * for_each_perag_from() because they terminate at sb_agcount where there are
- * no perag structures in tree beyond end_agno.
  */
-#define for_each_perag_range(mp, next_agno, end_agno, pag) \
-	for ((pag) = xfs_perag_get((mp), (next_agno)); \
-		(pag) != NULL && (next_agno) <= (end_agno); \
-		(next_agno) = (pag)->pag_agno + 1, \
-		xfs_perag_put(pag), \
-		(pag) = xfs_perag_get((mp), (next_agno)))
+struct xfs_perag_iter {
+	struct xfs_perag	*pag;
+	xfs_agnumber_t		__agno;
+};
 
-#define for_each_perag_from(mp, next_agno, pag) \
-	for_each_perag_range((mp), (next_agno), (mp)->m_sb.sb_agcount, (pag))
+static inline void
+xfs_perag_iter_cleanup(struct xfs_perag_iter *pagit)
+{
+	if (pagit->pag)
+		xfs_perag_put(pagit->pag);
+	pagit->pag = NULL;
+	pagit->__agno = NULLAGNUMBER;
+}
 
+#define XFS_PERAG_ITER_INIT(mp, name, first_agno)	\
+	struct xfs_perag_iter name \
+			__attribute__((__cleanup__(xfs_perag_iter_cleanup))) = \
+			{ .__agno = (first_agno), \
+			  .pag = xfs_perag_get((mp), (first_agno)), }
 
-#define for_each_perag(mp, agno, pag) \
-	(agno) = 0; \
-	for_each_perag_from((mp), (agno), (pag))
+#define XFS_PERAG_TAG_ITER_INIT(mp, name, first_agno, tag)	\
+	struct xfs_perag_iter name \
+			__attribute__((__cleanup__(xfs_perag_iter_cleanup))) = \
+			{ .__agno = (first_agno), \
+			  .pag = xfs_perag_get_tag((mp), (first_agno), (tag)), }
 
-#define for_each_perag_tag(mp, agno, pag, tag) \
-	for ((agno) = 0, (pag) = xfs_perag_get_tag((mp), 0, (tag)); \
-		(pag) != NULL; \
-		(agno) = (pag)->pag_agno + 1, \
-		xfs_perag_put(pag), \
-		(pag) = xfs_perag_get_tag((mp), (agno), (tag)))
+/* Perag iteration APIs */
+#define for_each_perag_range(mp, name, start_agno, end_agno) \
+	for (XFS_PERAG_ITER_INIT((mp), (name), (start_agno)); \
+		(name).pag != NULL && (name).__agno <= (end_agno); \
+		(name).__agno = (name).pag->pag_agno + 1, \
+		xfs_perag_put((name).pag), \
+		(name).pag = xfs_perag_get((mp), (name).__agno))
+
+#define for_each_perag_from(mp, name, start_agno) \
+	for_each_perag_range((mp), (name), (start_agno), (mp)->m_sb.sb_agcount)
+
+#define for_each_perag(mp, name) \
+	for_each_perag_from((mp), (name), 0)
+
+#define for_each_perag_tag(mp, name, tag) \
+	for (XFS_PERAG_TAG_ITER_INIT((mp), (name), 0, (tag)); \
+		(name).pag != NULL; \
+		(name).__agno = (name).pag->pag_agno + 1, \
+		xfs_perag_put((name).pag), \
+		(name).pag = xfs_perag_get_tag((mp), (name).__agno, (tag)))
 
 struct aghdr_init_data {
 	/* per ag data */
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index 04f5386446db..a0a07ebaf41b 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -856,18 +856,19 @@ int
 xfs_update_secondary_sbs(
 	struct xfs_mount	*mp)
 {
-	struct xfs_perag	*pag;
-	xfs_agnumber_t		agno = 1;
+	xfs_agnumber_t		last_agno = 0;
 	int			saved_error = 0;
 	int			error = 0;
 	LIST_HEAD		(buffer_list);
 
 	/* update secondary superblocks. */
-	for_each_perag_from(mp, agno, pag) {
+	for_each_perag_from(mp, iter, 1) {
 		struct xfs_buf		*bp;
 
+		last_agno = iter.pag->pag_agno;
+
 		error = xfs_buf_get(mp->m_ddev_targp,
-				 XFS_AG_DADDR(mp, pag->pag_agno, XFS_SB_DADDR),
+				 XFS_AG_DADDR(mp, last_agno, XFS_SB_DADDR),
 				 XFS_FSS_TO_BB(mp, 1), &bp);
 		/*
 		 * If we get an error reading or writing alternate superblocks,
@@ -879,7 +880,7 @@ xfs_update_secondary_sbs(
 		if (error) {
 			xfs_warn(mp,
 		"error allocating secondary superblock for ag %d",
-				pag->pag_agno);
+				last_agno);
 			if (!saved_error)
 				saved_error = error;
 			continue;
@@ -893,14 +894,14 @@ xfs_update_secondary_sbs(
 		xfs_buf_relse(bp);
 
 		/* don't hold too many buffers at once */
-		if (agno % 16)
+		if (last_agno % 16)
 			continue;
 
 		error = xfs_buf_delwri_submit(&buffer_list);
 		if (error) {
 			xfs_warn(mp,
 		"write error %d updating a secondary superblock near ag %d",
-				error, pag->pag_agno);
+				error, last_agno);
 			if (!saved_error)
 				saved_error = error;
 			continue;
@@ -910,7 +911,7 @@ xfs_update_secondary_sbs(
 	if (error) {
 		xfs_warn(mp,
 		"write error %d updating a secondary superblock near ag %d",
-			error, agno);
+			error, last_agno);
 	}
 
 	return saved_error ? saved_error : error;
diff --git a/fs/xfs/libxfs/xfs_types.c b/fs/xfs/libxfs/xfs_types.c
index e8f4abee7892..8654b46b7c60 100644
--- a/fs/xfs/libxfs/xfs_types.c
+++ b/fs/xfs/libxfs/xfs_types.c
@@ -223,16 +223,14 @@ xfs_icount_range(
 	unsigned long long	*max)
 {
 	unsigned long long	nr_inos = 0;
-	struct xfs_perag	*pag;
-	xfs_agnumber_t		agno;
 
 	/* root, rtbitmap, rtsum all live in the first chunk */
 	*min = XFS_INODES_PER_CHUNK;
 
-	for_each_perag(mp, agno, pag) {
+	for_each_perag(mp, iter) {
 		xfs_agino_t	first, last;
 
-		xfs_agino_range(mp, agno, &first, &last);
+		xfs_agino_range(mp, iter.pag->pag_agno, &first, &last);
 		nr_inos += last - first + 1;
 	}
 	*max = nr_inos;
diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c
index 1d146c9d9de1..14e952d116f4 100644
--- a/fs/xfs/scrub/bmap.c
+++ b/fs/xfs/scrub/bmap.c
@@ -576,8 +576,6 @@ xchk_bmap_check_rmaps(
 	int			whichfork)
 {
 	struct xfs_ifork	*ifp = XFS_IFORK_PTR(sc->ip, whichfork);
-	struct xfs_perag	*pag;
-	xfs_agnumber_t		agno;
 	bool			zero_size;
 	int			error;
 
@@ -609,15 +607,13 @@ xchk_bmap_check_rmaps(
 	    (zero_size || ifp->if_nextents > 0))
 		return 0;
 
-	for_each_perag(sc->mp, agno, pag) {
-		error = xchk_bmap_check_ag_rmaps(sc, whichfork, pag);
+	for_each_perag(sc->mp, iter) {
+		error = xchk_bmap_check_ag_rmaps(sc, whichfork, iter.pag);
 		if (error)
 			break;
 		if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
 			break;
 	}
-	if (pag)
-		xfs_perag_put(pag);
 	return error;
 }
 
diff --git a/fs/xfs/scrub/fscounters.c b/fs/xfs/scrub/fscounters.c
index fd7941e04ae1..e03577af63d9 100644
--- a/fs/xfs/scrub/fscounters.c
+++ b/fs/xfs/scrub/fscounters.c
@@ -67,21 +67,21 @@ xchk_fscount_warmup(
 	struct xfs_mount	*mp = sc->mp;
 	struct xfs_buf		*agi_bp = NULL;
 	struct xfs_buf		*agf_bp = NULL;
-	struct xfs_perag	*pag = NULL;
-	xfs_agnumber_t		agno;
 	int			error = 0;
 
-	for_each_perag(mp, agno, pag) {
+	for_each_perag(mp, iter) {
 		if (xchk_should_terminate(sc, &error))
 			break;
-		if (pag->pagi_init && pag->pagf_init)
+		if (iter.pag->pagi_init && iter.pag->pagf_init)
 			continue;
 
 		/* Lock both AG headers. */
-		error = xfs_ialloc_read_agi(mp, sc->tp, agno, &agi_bp);
+		error = xfs_ialloc_read_agi(mp, sc->tp, iter.pag->pag_agno,
+				&agi_bp);
 		if (error)
 			break;
-		error = xfs_alloc_read_agf(mp, sc->tp, agno, 0, &agf_bp);
+		error = xfs_alloc_read_agf(mp, sc->tp, iter.pag->pag_agno, 0,
+				&agf_bp);
 		if (error)
 			break;
 
@@ -89,7 +89,7 @@ xchk_fscount_warmup(
 		 * These are supposed to be initialized by the header read
 		 * function.
 		 */
-		if (!pag->pagi_init || !pag->pagf_init) {
+		if (!iter.pag->pagi_init || !iter.pag->pagf_init) {
 			error = -EFSCORRUPTED;
 			break;
 		}
@@ -104,8 +104,6 @@ xchk_fscount_warmup(
 		xfs_buf_relse(agf_bp);
 	if (agi_bp)
 		xfs_buf_relse(agi_bp);
-	if (pag)
-		xfs_perag_put(pag);
 	return error;
 }
 
@@ -179,9 +177,7 @@ xchk_fscount_aggregate_agcounts(
 	struct xchk_fscounters	*fsc)
 {
 	struct xfs_mount	*mp = sc->mp;
-	struct xfs_perag	*pag;
 	uint64_t		delayed;
-	xfs_agnumber_t		agno;
 	int			tries = 8;
 	int			error = 0;
 
@@ -190,27 +186,28 @@ xchk_fscount_aggregate_agcounts(
 	fsc->ifree = 0;
 	fsc->fdblocks = 0;
 
-	for_each_perag(mp, agno, pag) {
+	for_each_perag(mp, iter) {
 		if (xchk_should_terminate(sc, &error))
 			break;
 
 		/* This somehow got unset since the warmup? */
-		if (!pag->pagi_init || !pag->pagf_init) {
+		if (!iter.pag->pagi_init || !iter.pag->pagf_init) {
 			error = -EFSCORRUPTED;
 			break;
 		}
 
 		/* Count all the inodes */
-		fsc->icount += pag->pagi_count;
-		fsc->ifree += pag->pagi_freecount;
+		fsc->icount += iter.pag->pagi_count;
+		fsc->ifree += iter.pag->pagi_freecount;
 
 		/* Add up the free/freelist/bnobt/cntbt blocks */
-		fsc->fdblocks += pag->pagf_freeblks;
-		fsc->fdblocks += pag->pagf_flcount;
+		fsc->fdblocks += iter.pag->pagf_freeblks;
+		fsc->fdblocks += iter.pag->pagf_flcount;
 		if (xfs_sb_version_haslazysbcount(&sc->mp->m_sb)) {
-			fsc->fdblocks += pag->pagf_btreeblks;
+			fsc->fdblocks += iter.pag->pagf_btreeblks;
 		} else {
-			error = xchk_fscount_btreeblks(sc, fsc, agno);
+			error = xchk_fscount_btreeblks(sc, fsc,
+					iter.pag->pag_agno);
 			if (error)
 				break;
 		}
@@ -219,12 +216,10 @@ xchk_fscount_aggregate_agcounts(
 		 * Per-AG reservations are taken out of the incore counters,
 		 * so they must be left out of the free blocks computation.
 		 */
-		fsc->fdblocks -= pag->pag_meta_resv.ar_reserved;
-		fsc->fdblocks -= pag->pag_rmapbt_resv.ar_orig_reserved;
+		fsc->fdblocks -= iter.pag->pag_meta_resv.ar_reserved;
+		fsc->fdblocks -= iter.pag->pag_rmapbt_resv.ar_orig_reserved;
 
 	}
-	if (pag)
-		xfs_perag_put(pag);
 	if (error)
 		return error;
 
diff --git a/fs/xfs/xfs_extent_busy.c b/fs/xfs/xfs_extent_busy.c
index ad22a003f959..fe85df915707 100644
--- a/fs/xfs/xfs_extent_busy.c
+++ b/fs/xfs/xfs_extent_busy.c
@@ -593,18 +593,17 @@ void
 xfs_extent_busy_wait_all(
 	struct xfs_mount	*mp)
 {
-	struct xfs_perag	*pag;
 	DEFINE_WAIT		(wait);
-	xfs_agnumber_t		agno;
 
-	for_each_perag(mp, agno, pag) {
+	for_each_perag(mp, iter) {
 		do {
-			prepare_to_wait(&pag->pagb_wait, &wait, TASK_KILLABLE);
-			if  (RB_EMPTY_ROOT(&pag->pagb_tree))
+			prepare_to_wait(&iter.pag->pagb_wait, &wait,
+					TASK_KILLABLE);
+			if  (RB_EMPTY_ROOT(&iter.pag->pagb_tree))
 				break;
 			schedule();
 		} while (1);
-		finish_wait(&pag->pagb_wait, &wait);
+		finish_wait(&iter.pag->pagb_wait, &wait);
 	}
 }
 
diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c
index 7d0b09c1366e..cdf44db29973 100644
--- a/fs/xfs/xfs_fsmap.c
+++ b/fs/xfs/xfs_fsmap.c
@@ -573,7 +573,6 @@ __xfs_getfsmap_datadev(
 	void				*priv)
 {
 	struct xfs_mount		*mp = tp->t_mountp;
-	struct xfs_perag		*pag;
 	struct xfs_btree_cur		*bt_cur = NULL;
 	xfs_fsblock_t			start_fsb;
 	xfs_fsblock_t			end_fsb;
@@ -612,13 +611,13 @@ __xfs_getfsmap_datadev(
 	start_ag = XFS_FSB_TO_AGNO(mp, start_fsb);
 	end_ag = XFS_FSB_TO_AGNO(mp, end_fsb);
 
-	for_each_perag_range(mp, start_ag, end_ag, pag) {
+	for_each_perag_range(mp, iter, start_ag, end_ag) {
 		/*
 		 * Set the AG high key from the fsmap high key if this
 		 * is the last AG that we're querying.
 		 */
-		info->pag = pag;
-		if (pag->pag_agno == end_ag) {
+		info->pag = iter.pag;
+		if (iter.pag->pag_agno == end_ag) {
 			info->high.rm_startblock = XFS_FSB_TO_AGBNO(mp,
 					end_fsb);
 			info->high.rm_offset = XFS_BB_TO_FSBT(mp,
@@ -636,14 +635,14 @@ __xfs_getfsmap_datadev(
 			info->agf_bp = NULL;
 		}
 
-		error = xfs_alloc_read_agf(mp, tp, pag->pag_agno, 0,
+		error = xfs_alloc_read_agf(mp, tp, iter.pag->pag_agno, 0,
 				&info->agf_bp);
 		if (error)
 			break;
 
-		trace_xfs_fsmap_low_key(mp, info->dev, pag->pag_agno,
+		trace_xfs_fsmap_low_key(mp, info->dev, iter.pag->pag_agno,
 				&info->low);
-		trace_xfs_fsmap_high_key(mp, info->dev, pag->pag_agno,
+		trace_xfs_fsmap_high_key(mp, info->dev, iter.pag->pag_agno,
 				&info->high);
 
 		error = query_fn(tp, info, &bt_cur, priv);
@@ -654,7 +653,7 @@ __xfs_getfsmap_datadev(
 		 * Set the AG low key to the start of the AG prior to
 		 * moving on to the next AG.
 		 */
-		if (pag->pag_agno == start_ag) {
+		if (iter.pag->pag_agno == start_ag) {
 			info->low.rm_startblock = 0;
 			info->low.rm_owner = 0;
 			info->low.rm_offset = 0;
@@ -666,7 +665,7 @@ __xfs_getfsmap_datadev(
 		 * before we drop the reference to the perag when the loop
 		 * terminates.
 		 */
-		if (pag->pag_agno == end_ag) {
+		if (iter.pag->pag_agno == end_ag) {
 			info->last = true;
 			error = query_fn(tp, info, &bt_cur, priv);
 			if (error)
@@ -682,13 +681,7 @@ __xfs_getfsmap_datadev(
 		xfs_trans_brelse(tp, info->agf_bp);
 		info->agf_bp = NULL;
 	}
-	if (info->pag) {
-		xfs_perag_put(info->pag);
-		info->pag = NULL;
-	} else if (pag) {
-		/* loop termination case */
-		xfs_perag_put(pag);
-	}
+	info->pag = NULL;
 
 	return error;
 }
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 6ed29b158312..31f585a525e8 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -570,14 +570,12 @@ int
 xfs_fs_reserve_ag_blocks(
 	struct xfs_mount	*mp)
 {
-	xfs_agnumber_t		agno;
-	struct xfs_perag	*pag;
 	int			error = 0;
 	int			err2;
 
 	mp->m_finobt_nores = false;
-	for_each_perag(mp, agno, pag) {
-		err2 = xfs_ag_resv_init(pag, NULL);
+	for_each_perag(mp, iter) {
+		err2 = xfs_ag_resv_init(iter.pag, NULL);
 		if (err2 && !error)
 			error = err2;
 	}
@@ -598,13 +596,11 @@ int
 xfs_fs_unreserve_ag_blocks(
 	struct xfs_mount	*mp)
 {
-	xfs_agnumber_t		agno;
-	struct xfs_perag	*pag;
 	int			error = 0;
 	int			err2;
 
-	for_each_perag(mp, agno, pag) {
-		err2 = xfs_ag_resv_free(pag);
+	for_each_perag(mp, iter) {
+		err2 = xfs_ag_resv_free(iter.pag);
 		if (err2 && !error)
 			error = err2;
 	}
diff --git a/fs/xfs/xfs_health.c b/fs/xfs/xfs_health.c
index eb10eacabc8f..715a987b8204 100644
--- a/fs/xfs/xfs_health.c
+++ b/fs/xfs/xfs_health.c
@@ -24,8 +24,6 @@ void
 xfs_health_unmount(
 	struct xfs_mount	*mp)
 {
-	struct xfs_perag	*pag;
-	xfs_agnumber_t		agno;
 	unsigned int		sick = 0;
 	unsigned int		checked = 0;
 	bool			warn = false;
@@ -34,10 +32,11 @@ xfs_health_unmount(
 		return;
 
 	/* Measure AG corruption levels. */
-	for_each_perag(mp, agno, pag) {
-		xfs_ag_measure_sickness(pag, &sick, &checked);
+	for_each_perag(mp, iter) {
+		xfs_ag_measure_sickness(iter.pag, &sick, &checked);
 		if (sick) {
-			trace_xfs_ag_unfixed_corruption(mp, agno, sick);
+			trace_xfs_ag_unfixed_corruption(mp, iter.pag->pag_agno,
+					sick);
 			warn = true;
 		}
 	}
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 6741e27603ad..1d4006df4066 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1368,14 +1368,11 @@ void
 xfs_blockgc_stop(
 	struct xfs_mount	*mp)
 {
-	struct xfs_perag	*pag;
-	xfs_agnumber_t		agno;
-
 	if (!xfs_clear_blockgc_enabled(mp))
 		return;
 
-	for_each_perag(mp, agno, pag)
-		cancel_delayed_work_sync(&pag->pag_blockgc_work);
+	for_each_perag(mp, iter)
+		cancel_delayed_work_sync(&iter.pag->pag_blockgc_work);
 	trace_xfs_blockgc_stop(mp, __return_address);
 }
 
@@ -1384,15 +1381,12 @@ void
 xfs_blockgc_start(
 	struct xfs_mount	*mp)
 {
-	struct xfs_perag	*pag;
-	xfs_agnumber_t		agno;
-
 	if (xfs_set_blockgc_enabled(mp))
 		return;
 
 	trace_xfs_blockgc_start(mp, __return_address);
-	for_each_perag_tag(mp, agno, pag, XFS_ICI_BLOCKGC_TAG)
-		xfs_blockgc_queue(pag);
+	for_each_perag_tag(mp, iter, XFS_ICI_BLOCKGC_TAG)
+		xfs_blockgc_queue(iter.pag);
 }
 
 /* Don't try to run block gc on an inode that's in any of these states. */
@@ -1515,9 +1509,6 @@ void
 xfs_blockgc_flush_all(
 	struct xfs_mount	*mp)
 {
-	struct xfs_perag	*pag;
-	xfs_agnumber_t		agno;
-
 	trace_xfs_blockgc_flush_all(mp, __return_address);
 
 	/*
@@ -1525,12 +1516,12 @@ xfs_blockgc_flush_all(
 	 * wasn't queued, it will not be requeued.  Then flush whatever's
 	 * left.
 	 */
-	for_each_perag_tag(mp, agno, pag, XFS_ICI_BLOCKGC_TAG)
-		mod_delayed_work(pag->pag_mount->m_blockgc_wq,
-				&pag->pag_blockgc_work, 0);
+	for_each_perag_tag(mp, iter, XFS_ICI_BLOCKGC_TAG)
+		mod_delayed_work(mp->m_blockgc_wq, &iter.pag->pag_blockgc_work,
+				0);
 
-	for_each_perag_tag(mp, agno, pag, XFS_ICI_BLOCKGC_TAG)
-		flush_delayed_work(&pag->pag_blockgc_work);
+	for_each_perag_tag(mp, iter, XFS_ICI_BLOCKGC_TAG)
+		flush_delayed_work(&iter.pag->pag_blockgc_work);
 
 	xfs_inodegc_flush(mp);
 }
diff --git a/fs/xfs/xfs_iwalk.c b/fs/xfs/xfs_iwalk.c
index 7558486f4937..0c06a59aec79 100644
--- a/fs/xfs/xfs_iwalk.c
+++ b/fs/xfs/xfs_iwalk.c
@@ -568,30 +568,27 @@ xfs_iwalk(
 		.pwork		= XFS_PWORK_SINGLE_THREADED,
 		.lastino	= NULLFSINO,
 	};
-	struct xfs_perag	*pag;
-	xfs_agnumber_t		agno = XFS_INO_TO_AGNO(mp, startino);
+	xfs_agnumber_t		start_agno = XFS_INO_TO_AGNO(mp, startino);
 	int			error;
 
-	ASSERT(agno < mp->m_sb.sb_agcount);
+	ASSERT(start_agno < mp->m_sb.sb_agcount);
 	ASSERT(!(flags & ~XFS_IWALK_FLAGS_ALL));
 
 	error = xfs_iwalk_alloc(&iwag);
 	if (error)
 		return error;
 
-	for_each_perag_from(mp, agno, pag) {
-		iwag.pag = pag;
+	for_each_perag_from(mp, iter, start_agno) {
+		iwag.pag = iter.pag;
 		error = xfs_iwalk_ag(&iwag);
 		if (error)
 			break;
-		iwag.startino = XFS_AGINO_TO_INO(mp, agno + 1, 0);
+		iwag.startino = XFS_AGINO_TO_INO(mp, iter.pag->pag_agno + 1, 0);
 		if (flags & XFS_INOBT_WALK_SAME_AG)
 			break;
 		iwag.pag = NULL;
 	}
 
-	if (iwag.pag)
-		xfs_perag_put(pag);
 	xfs_iwalk_free(&iwag);
 	return error;
 }
@@ -646,18 +643,17 @@ xfs_iwalk_threaded(
 	void			*data)
 {
 	struct xfs_pwork_ctl	pctl;
-	struct xfs_perag	*pag;
-	xfs_agnumber_t		agno = XFS_INO_TO_AGNO(mp, startino);
+	xfs_agnumber_t		start_agno = XFS_INO_TO_AGNO(mp, startino);
 	int			error;
 
-	ASSERT(agno < mp->m_sb.sb_agcount);
+	ASSERT(start_agno < mp->m_sb.sb_agcount);
 	ASSERT(!(flags & ~XFS_IWALK_FLAGS_ALL));
 
 	error = xfs_pwork_init(mp, &pctl, xfs_iwalk_ag_work, "xfs_iwalk");
 	if (error)
 		return error;
 
-	for_each_perag_from(mp, agno, pag) {
+	for_each_perag_from(mp, iter, start_agno) {
 		struct xfs_iwalk_ag	*iwag;
 
 		if (xfs_pwork_ctl_want_abort(&pctl))
@@ -670,20 +666,18 @@ xfs_iwalk_threaded(
 		 * perag is being handed off to async work, so take another
 		 * reference for the async work to release.
 		 */
-		atomic_inc(&pag->pag_ref);
-		iwag->pag = pag;
+		atomic_inc(&iter.pag->pag_ref);
+		iwag->pag = iter.pag;
 		iwag->iwalk_fn = iwalk_fn;
 		iwag->data = data;
 		iwag->startino = startino;
 		iwag->sz_recs = xfs_iwalk_prefetch(inode_records);
 		iwag->lastino = NULLFSINO;
 		xfs_pwork_queue(&pctl, &iwag->pwork);
-		startino = XFS_AGINO_TO_INO(mp, pag->pag_agno + 1, 0);
+		startino = XFS_AGINO_TO_INO(mp, iter.pag->pag_agno + 1, 0);
 		if (flags & XFS_INOBT_WALK_SAME_AG)
 			break;
 	}
-	if (pag)
-		xfs_perag_put(pag);
 	if (polled)
 		xfs_pwork_poll(&pctl);
 	return xfs_pwork_destroy(&pctl);
@@ -753,30 +747,27 @@ xfs_inobt_walk(
 		.pwork		= XFS_PWORK_SINGLE_THREADED,
 		.lastino	= NULLFSINO,
 	};
-	struct xfs_perag	*pag;
-	xfs_agnumber_t		agno = XFS_INO_TO_AGNO(mp, startino);
+	xfs_agnumber_t		start_agno = XFS_INO_TO_AGNO(mp, startino);
 	int			error;
 
-	ASSERT(agno < mp->m_sb.sb_agcount);
+	ASSERT(start_agno < mp->m_sb.sb_agcount);
 	ASSERT(!(flags & ~XFS_INOBT_WALK_FLAGS_ALL));
 
 	error = xfs_iwalk_alloc(&iwag);
 	if (error)
 		return error;
 
-	for_each_perag_from(mp, agno, pag) {
-		iwag.pag = pag;
+	for_each_perag_from(mp, iter, start_agno) {
+		iwag.pag = iter.pag;
 		error = xfs_iwalk_ag(&iwag);
 		if (error)
 			break;
-		iwag.startino = XFS_AGINO_TO_INO(mp, pag->pag_agno + 1, 0);
+		iwag.startino = XFS_AGINO_TO_INO(mp, iter.pag->pag_agno + 1, 0);
 		if (flags & XFS_INOBT_WALK_SAME_AG)
 			break;
 		iwag.pag = NULL;
 	}
 
-	if (iwag.pag)
-		xfs_perag_put(pag);
 	xfs_iwalk_free(&iwag);
 	return error;
 }
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index a98d2429d795..d51c03dbb01b 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2745,16 +2745,14 @@ xlog_recover_process_iunlinks(
 	struct xlog	*log)
 {
 	struct xfs_mount	*mp = log->l_mp;
-	struct xfs_perag	*pag;
-	xfs_agnumber_t		agno;
 	struct xfs_agi		*agi;
 	struct xfs_buf		*agibp;
 	xfs_agino_t		agino;
 	int			bucket;
 	int			error;
 
-	for_each_perag(mp, agno, pag) {
-		error = xfs_read_agi(mp, NULL, pag->pag_agno, &agibp);
+	for_each_perag(mp, iter) {
+		error = xfs_read_agi(mp, NULL, iter.pag->pag_agno, &agibp);
 		if (error) {
 			/*
 			 * AGI is b0rked. Don't process it.
@@ -2780,7 +2778,8 @@ xlog_recover_process_iunlinks(
 			agino = be32_to_cpu(agi->agi_unlinked[bucket]);
 			while (agino != NULLAGINO) {
 				agino = xlog_recover_process_one_iunlink(mp,
-						pag->pag_agno, agino, bucket);
+						iter.pag->pag_agno, agino,
+						bucket);
 				cond_resched();
 			}
 		}
@@ -3503,10 +3502,8 @@ xlog_recover_check_summary(
 	struct xlog		*log)
 {
 	struct xfs_mount	*mp = log->l_mp;
-	struct xfs_perag	*pag;
 	struct xfs_buf		*agfbp;
 	struct xfs_buf		*agibp;
-	xfs_agnumber_t		agno;
 	uint64_t		freeblks;
 	uint64_t		itotal;
 	uint64_t		ifree;
@@ -3517,11 +3514,11 @@ xlog_recover_check_summary(
 	freeblks = 0LL;
 	itotal = 0LL;
 	ifree = 0LL;
-	for_each_perag(mp, agno, pag) {
-		error = xfs_read_agf(mp, NULL, pag->pag_agno, 0, &agfbp);
+	for_each_perag(mp, iter) {
+		error = xfs_read_agf(mp, NULL, iter.pag->pag_agno, 0, &agfbp);
 		if (error) {
 			xfs_alert(mp, "%s agf read failed agno %d error %d",
-						__func__, pag->pag_agno, error);
+					__func__, iter.pag->pag_agno, error);
 		} else {
 			struct xfs_agf	*agfp = agfbp->b_addr;
 
@@ -3530,10 +3527,10 @@ xlog_recover_check_summary(
 			xfs_buf_relse(agfbp);
 		}
 
-		error = xfs_read_agi(mp, NULL, pag->pag_agno, &agibp);
+		error = xfs_read_agi(mp, NULL, iter.pag->pag_agno, &agibp);
 		if (error) {
 			xfs_alert(mp, "%s agi read failed agno %d error %d",
-						__func__, pag->pag_agno, error);
+					__func__, iter.pag->pag_agno, error);
 		} else {
 			struct xfs_agi	*agi = agibp->b_addr;
 
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index c256104772cb..bc19291c577d 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -755,19 +755,15 @@ int
 xfs_reflink_recover_cow(
 	struct xfs_mount	*mp)
 {
-	struct xfs_perag	*pag;
-	xfs_agnumber_t		agno;
 	int			error = 0;
 
 	if (!xfs_sb_version_hasreflink(&mp->m_sb))
 		return 0;
 
-	for_each_perag(mp, agno, pag) {
-		error = xfs_refcount_recover_cow_leftovers(mp, pag);
-		if (error) {
-			xfs_perag_put(pag);
+	for_each_perag(mp, iter) {
+		error = xfs_refcount_recover_cow_leftovers(mp, iter.pag);
+		if (error)
 			break;
-		}
 	}
 
 	return error;


  parent reply	other threads:[~2021-08-05  7:01 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-05  7:00 [PATCHSET 0/5] xfs: other stuff for 5.15 Darrick J. Wong
2021-08-05  7:00 ` [PATCH 1/5] xfs: fix silly whitespace problems with kernel libxfs Darrick J. Wong
2021-08-06  5:45   ` Chandan Babu R
2021-08-09 14:51   ` Christoph Hellwig
2021-08-05  7:00 ` [PATCH 2/5] xfs: drop experimental warnings for bigtime and inobtcount Darrick J. Wong
2021-08-06  5:51   ` Chandan Babu R
2021-08-09 14:53   ` Christoph Hellwig
2021-08-05  7:01 ` Darrick J. Wong [this message]
2021-08-06  7:15   ` [PATCH 3/5] xfs: automatic resource cleanup of for_each_perag* Chandan Babu R
2021-08-09 15:07   ` Christoph Hellwig
2021-08-05  7:01 ` [PATCH 4/5] xfs: grab active perag ref when reading AG headers Darrick J. Wong
2021-08-06 11:25   ` Chandan Babu R
2021-08-05  7:01 ` [PATCH 5/5] xfs: dump log intent items that cannot be recovered due to corruption Darrick J. Wong
2021-08-06 11:41   ` Chandan Babu R
2021-08-09 14:55   ` Christoph Hellwig

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=162814685996.2777088.11268635137040103857.stgit@magnolia \
    --to=djwong@kernel.org \
    --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.