diff mbox series

[06/12] xfs: refactor walking of per-AG RECLAIM inodes

Message ID 154630904767.16693.13857289605746264694.stgit@magnolia (mailing list archive)
State New, archived
Headers show
Series xfs: deferred inode inactivation | expand

Commit Message

Darrick J. Wong Jan. 1, 2019, 2:17 a.m. UTC
From: Darrick J. Wong <darrick.wong@oracle.com>

Refactor the code that walks reclaim-tagged inodes so that we can reuse
the same loop in a subsequent patch.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_icache.c |  170 +++++++++++++++++++++++++++++----------------------
 1 file changed, 97 insertions(+), 73 deletions(-)

Comments

Brian Foster Jan. 11, 2019, 7:06 p.m. UTC | #1
On Mon, Dec 31, 2018 at 06:17:27PM -0800, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Refactor the code that walks reclaim-tagged inodes so that we can reuse
> the same loop in a subsequent patch.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_icache.c |  170 +++++++++++++++++++++++++++++----------------------
>  1 file changed, 97 insertions(+), 73 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
> index 36d986087abb..7e031eb6f048 100644
> --- a/fs/xfs/xfs_icache.c
> +++ b/fs/xfs/xfs_icache.c
...
> @@ -1223,6 +1223,90 @@ xfs_reclaim_inode(
>  	return 0;
>  }
>  
> +/*
> + * Walk the RECLAIM tagged inodes in this AG looking for inodes to inactivate.
> + */
> +STATIC int
> +xfs_walk_ag_reclaim_inos(

Nit: how about xfs_reclaim_inodes_pag()? Hm, maybe we can rename
xfs_reclaim_inodes_ag() to something like __xfs_reclaim_inodes() as
well.

Brian

> +	struct xfs_perag	*pag,
> +	int			sync_flags,
> +	bool			(*grab_fn)(struct xfs_inode *ip,
> +					   int sync_flags),
> +	int			(*execute_fn)(struct xfs_inode *ip,
> +					      struct xfs_perag *pag,
> +					      int sync_flags),
> +	int			*nr_to_scan,
> +	bool			*done)
> +{
> +	struct xfs_mount	*mp = pag->pag_mount;
> +	unsigned long		first_index = 0;
> +	int			nr_found = 0;
> +	int			last_error = 0;
> +	int			error;
> +
> +	do {
> +		struct xfs_inode *batch[XFS_LOOKUP_BATCH];
> +		int	i;
> +
> +		rcu_read_lock();
> +		nr_found = radix_tree_gang_lookup_tag(&pag->pag_ici_root,
> +				(void **)batch, first_index, XFS_LOOKUP_BATCH,
> +				XFS_ICI_RECLAIM_TAG);
> +		if (!nr_found) {
> +			*done = true;
> +			rcu_read_unlock();
> +			break;
> +		}
> +
> +		/*
> +		 * Grab the inodes before we drop the lock. if we found
> +		 * nothing, nr == 0 and the loop will be skipped.
> +		 */
> +		for (i = 0; i < nr_found; i++) {
> +			struct xfs_inode *ip = batch[i];
> +
> +			if (*done || !grab_fn(ip, sync_flags))
> +				batch[i] = NULL;
> +
> +			/*
> +			 * Update the index for the next lookup. Catch
> +			 * overflows into the next AG range which can occur if
> +			 * we have inodes in the last block of the AG and we
> +			 * are currently pointing to the last inode.
> +			 *
> +			 * Because we may see inodes that are from the wrong AG
> +			 * due to RCU freeing and reallocation, only update the
> +			 * index if it lies in this AG. It was a race that lead
> +			 * us to see this inode, so another lookup from the
> +			 * same index will not find it again.
> +			 */
> +			if (XFS_INO_TO_AGNO(mp, ip->i_ino) != pag->pag_agno)
> +				continue;
> +			first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1);
> +			if (first_index < XFS_INO_TO_AGINO(mp, ip->i_ino))
> +				*done = true;
> +		}
> +
> +		/* unlock now we've grabbed the inodes. */
> +		rcu_read_unlock();
> +
> +		for (i = 0; i < nr_found; i++) {
> +			if (!batch[i])
> +				continue;
> +			error = execute_fn(batch[i], pag, sync_flags);
> +			if (error && last_error != -EFSCORRUPTED)
> +				last_error = error;
> +		}
> +
> +		*nr_to_scan -= XFS_LOOKUP_BATCH;
> +
> +		cond_resched();
> +
> +	} while (nr_found && !*done && *nr_to_scan > 0);
> +
> +	return last_error;
> +}
> +
>  /*
>   * Walk the AGs and reclaim the inodes in them. Even if the filesystem is
>   * corrupted, we still want to try to reclaim all the inodes. If we don't,
> @@ -1236,8 +1320,8 @@ xfs_reclaim_inodes_ag(
>  	int			*nr_to_scan)
>  {
>  	struct xfs_perag	*pag;
> -	int			error = 0;
>  	int			last_error = 0;
> +	int			error;
>  	xfs_agnumber_t		ag;
>  	int			trylock = flags & SYNC_TRYLOCK;
>  	int			skipped;
> @@ -1247,8 +1331,7 @@ xfs_reclaim_inodes_ag(
>  	skipped = 0;
>  	while ((pag = xfs_perag_get_tag(mp, ag, XFS_ICI_RECLAIM_TAG))) {
>  		unsigned long	first_index = 0;
> -		int		done = 0;
> -		int		nr_found = 0;
> +		bool		done = false;
>  
>  		ag = pag->pag_agno + 1;
>  
> @@ -1262,70 +1345,11 @@ xfs_reclaim_inodes_ag(
>  		} else
>  			mutex_lock(&pag->pag_ici_reclaim_lock);
>  
> -		do {
> -			struct xfs_inode *batch[XFS_LOOKUP_BATCH];
> -			int	i;
> -
> -			rcu_read_lock();
> -			nr_found = radix_tree_gang_lookup_tag(
> -					&pag->pag_ici_root,
> -					(void **)batch, first_index,
> -					XFS_LOOKUP_BATCH,
> -					XFS_ICI_RECLAIM_TAG);
> -			if (!nr_found) {
> -				done = 1;
> -				rcu_read_unlock();
> -				break;
> -			}
> -
> -			/*
> -			 * Grab the inodes before we drop the lock. if we found
> -			 * nothing, nr == 0 and the loop will be skipped.
> -			 */
> -			for (i = 0; i < nr_found; i++) {
> -				struct xfs_inode *ip = batch[i];
> -
> -				if (done || xfs_reclaim_inode_grab(ip, flags))
> -					batch[i] = NULL;
> -
> -				/*
> -				 * Update the index for the next lookup. Catch
> -				 * overflows into the next AG range which can
> -				 * occur if we have inodes in the last block of
> -				 * the AG and we are currently pointing to the
> -				 * last inode.
> -				 *
> -				 * Because we may see inodes that are from the
> -				 * wrong AG due to RCU freeing and
> -				 * reallocation, only update the index if it
> -				 * lies in this AG. It was a race that lead us
> -				 * to see this inode, so another lookup from
> -				 * the same index will not find it again.
> -				 */
> -				if (XFS_INO_TO_AGNO(mp, ip->i_ino) !=
> -								pag->pag_agno)
> -					continue;
> -				first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1);
> -				if (first_index < XFS_INO_TO_AGINO(mp, ip->i_ino))
> -					done = 1;
> -			}
> -
> -			/* unlock now we've grabbed the inodes. */
> -			rcu_read_unlock();
> -
> -			for (i = 0; i < nr_found; i++) {
> -				if (!batch[i])
> -					continue;
> -				error = xfs_reclaim_inode(batch[i], pag, flags);
> -				if (error && last_error != -EFSCORRUPTED)
> -					last_error = error;
> -			}
> -
> -			*nr_to_scan -= XFS_LOOKUP_BATCH;
> -
> -			cond_resched();
> -
> -		} while (nr_found && !done && *nr_to_scan > 0);
> +		error = xfs_walk_ag_reclaim_inos(pag, flags,
> +				xfs_reclaim_inode_grab, xfs_reclaim_inode,
> +				nr_to_scan, &done);
> +		if (error && last_error != -EFSCORRUPTED)
> +			last_error = error;
>  
>  		if (trylock && !done)
>  			pag->pag_ici_reclaim_cursor = first_index;
>
Darrick J. Wong Jan. 17, 2019, 5:43 p.m. UTC | #2
On Fri, Jan 11, 2019 at 02:06:06PM -0500, Brian Foster wrote:
> On Mon, Dec 31, 2018 at 06:17:27PM -0800, Darrick J. Wong wrote:
> > From: Darrick J. Wong <darrick.wong@oracle.com>
> > 
> > Refactor the code that walks reclaim-tagged inodes so that we can reuse
> > the same loop in a subsequent patch.
> > 
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > ---
> >  fs/xfs/xfs_icache.c |  170 +++++++++++++++++++++++++++++----------------------
> >  1 file changed, 97 insertions(+), 73 deletions(-)
> > 
> > 
> > diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
> > index 36d986087abb..7e031eb6f048 100644
> > --- a/fs/xfs/xfs_icache.c
> > +++ b/fs/xfs/xfs_icache.c
> ...
> > @@ -1223,6 +1223,90 @@ xfs_reclaim_inode(
> >  	return 0;
> >  }
> >  
> > +/*
> > + * Walk the RECLAIM tagged inodes in this AG looking for inodes to inactivate.
> > + */
> > +STATIC int
> > +xfs_walk_ag_reclaim_inos(
> 
> Nit: how about xfs_reclaim_inodes_pag()? Hm, maybe we can rename
> xfs_reclaim_inodes_ag() to something like __xfs_reclaim_inodes() as
> well.

Ok, will do.  This whole section might change dramatically if the incore
inode radix tree becomes an xarray, but we'll see.

--D

> Brian
> 
> > +	struct xfs_perag	*pag,
> > +	int			sync_flags,
> > +	bool			(*grab_fn)(struct xfs_inode *ip,
> > +					   int sync_flags),
> > +	int			(*execute_fn)(struct xfs_inode *ip,
> > +					      struct xfs_perag *pag,
> > +					      int sync_flags),
> > +	int			*nr_to_scan,
> > +	bool			*done)
> > +{
> > +	struct xfs_mount	*mp = pag->pag_mount;
> > +	unsigned long		first_index = 0;
> > +	int			nr_found = 0;
> > +	int			last_error = 0;
> > +	int			error;
> > +
> > +	do {
> > +		struct xfs_inode *batch[XFS_LOOKUP_BATCH];
> > +		int	i;
> > +
> > +		rcu_read_lock();
> > +		nr_found = radix_tree_gang_lookup_tag(&pag->pag_ici_root,
> > +				(void **)batch, first_index, XFS_LOOKUP_BATCH,
> > +				XFS_ICI_RECLAIM_TAG);
> > +		if (!nr_found) {
> > +			*done = true;
> > +			rcu_read_unlock();
> > +			break;
> > +		}
> > +
> > +		/*
> > +		 * Grab the inodes before we drop the lock. if we found
> > +		 * nothing, nr == 0 and the loop will be skipped.
> > +		 */
> > +		for (i = 0; i < nr_found; i++) {
> > +			struct xfs_inode *ip = batch[i];
> > +
> > +			if (*done || !grab_fn(ip, sync_flags))
> > +				batch[i] = NULL;
> > +
> > +			/*
> > +			 * Update the index for the next lookup. Catch
> > +			 * overflows into the next AG range which can occur if
> > +			 * we have inodes in the last block of the AG and we
> > +			 * are currently pointing to the last inode.
> > +			 *
> > +			 * Because we may see inodes that are from the wrong AG
> > +			 * due to RCU freeing and reallocation, only update the
> > +			 * index if it lies in this AG. It was a race that lead
> > +			 * us to see this inode, so another lookup from the
> > +			 * same index will not find it again.
> > +			 */
> > +			if (XFS_INO_TO_AGNO(mp, ip->i_ino) != pag->pag_agno)
> > +				continue;
> > +			first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1);
> > +			if (first_index < XFS_INO_TO_AGINO(mp, ip->i_ino))
> > +				*done = true;
> > +		}
> > +
> > +		/* unlock now we've grabbed the inodes. */
> > +		rcu_read_unlock();
> > +
> > +		for (i = 0; i < nr_found; i++) {
> > +			if (!batch[i])
> > +				continue;
> > +			error = execute_fn(batch[i], pag, sync_flags);
> > +			if (error && last_error != -EFSCORRUPTED)
> > +				last_error = error;
> > +		}
> > +
> > +		*nr_to_scan -= XFS_LOOKUP_BATCH;
> > +
> > +		cond_resched();
> > +
> > +	} while (nr_found && !*done && *nr_to_scan > 0);
> > +
> > +	return last_error;
> > +}
> > +
> >  /*
> >   * Walk the AGs and reclaim the inodes in them. Even if the filesystem is
> >   * corrupted, we still want to try to reclaim all the inodes. If we don't,
> > @@ -1236,8 +1320,8 @@ xfs_reclaim_inodes_ag(
> >  	int			*nr_to_scan)
> >  {
> >  	struct xfs_perag	*pag;
> > -	int			error = 0;
> >  	int			last_error = 0;
> > +	int			error;
> >  	xfs_agnumber_t		ag;
> >  	int			trylock = flags & SYNC_TRYLOCK;
> >  	int			skipped;
> > @@ -1247,8 +1331,7 @@ xfs_reclaim_inodes_ag(
> >  	skipped = 0;
> >  	while ((pag = xfs_perag_get_tag(mp, ag, XFS_ICI_RECLAIM_TAG))) {
> >  		unsigned long	first_index = 0;
> > -		int		done = 0;
> > -		int		nr_found = 0;
> > +		bool		done = false;
> >  
> >  		ag = pag->pag_agno + 1;
> >  
> > @@ -1262,70 +1345,11 @@ xfs_reclaim_inodes_ag(
> >  		} else
> >  			mutex_lock(&pag->pag_ici_reclaim_lock);
> >  
> > -		do {
> > -			struct xfs_inode *batch[XFS_LOOKUP_BATCH];
> > -			int	i;
> > -
> > -			rcu_read_lock();
> > -			nr_found = radix_tree_gang_lookup_tag(
> > -					&pag->pag_ici_root,
> > -					(void **)batch, first_index,
> > -					XFS_LOOKUP_BATCH,
> > -					XFS_ICI_RECLAIM_TAG);
> > -			if (!nr_found) {
> > -				done = 1;
> > -				rcu_read_unlock();
> > -				break;
> > -			}
> > -
> > -			/*
> > -			 * Grab the inodes before we drop the lock. if we found
> > -			 * nothing, nr == 0 and the loop will be skipped.
> > -			 */
> > -			for (i = 0; i < nr_found; i++) {
> > -				struct xfs_inode *ip = batch[i];
> > -
> > -				if (done || xfs_reclaim_inode_grab(ip, flags))
> > -					batch[i] = NULL;
> > -
> > -				/*
> > -				 * Update the index for the next lookup. Catch
> > -				 * overflows into the next AG range which can
> > -				 * occur if we have inodes in the last block of
> > -				 * the AG and we are currently pointing to the
> > -				 * last inode.
> > -				 *
> > -				 * Because we may see inodes that are from the
> > -				 * wrong AG due to RCU freeing and
> > -				 * reallocation, only update the index if it
> > -				 * lies in this AG. It was a race that lead us
> > -				 * to see this inode, so another lookup from
> > -				 * the same index will not find it again.
> > -				 */
> > -				if (XFS_INO_TO_AGNO(mp, ip->i_ino) !=
> > -								pag->pag_agno)
> > -					continue;
> > -				first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1);
> > -				if (first_index < XFS_INO_TO_AGINO(mp, ip->i_ino))
> > -					done = 1;
> > -			}
> > -
> > -			/* unlock now we've grabbed the inodes. */
> > -			rcu_read_unlock();
> > -
> > -			for (i = 0; i < nr_found; i++) {
> > -				if (!batch[i])
> > -					continue;
> > -				error = xfs_reclaim_inode(batch[i], pag, flags);
> > -				if (error && last_error != -EFSCORRUPTED)
> > -					last_error = error;
> > -			}
> > -
> > -			*nr_to_scan -= XFS_LOOKUP_BATCH;
> > -
> > -			cond_resched();
> > -
> > -		} while (nr_found && !done && *nr_to_scan > 0);
> > +		error = xfs_walk_ag_reclaim_inos(pag, flags,
> > +				xfs_reclaim_inode_grab, xfs_reclaim_inode,
> > +				nr_to_scan, &done);
> > +		if (error && last_error != -EFSCORRUPTED)
> > +			last_error = error;
> >  
> >  		if (trylock && !done)
> >  			pag->pag_ici_reclaim_cursor = first_index;
> >
diff mbox series

Patch

diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 36d986087abb..7e031eb6f048 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1004,9 +1004,9 @@  xfs_inode_ag_iterator_tag(
 
 /*
  * Grab the inode for reclaim exclusively.
- * Return 0 if we grabbed it, non-zero otherwise.
+ * Return true if we grabbed it, false otherwise.
  */
-STATIC int
+STATIC bool
 xfs_reclaim_inode_grab(
 	struct xfs_inode	*ip,
 	int			flags)
@@ -1015,7 +1015,7 @@  xfs_reclaim_inode_grab(
 
 	/* quick check for stale RCU freed inode */
 	if (!ip->i_ino)
-		return 1;
+		return false;
 
 	/*
 	 * If we are asked for non-blocking operation, do unlocked checks to
@@ -1024,7 +1024,7 @@  xfs_reclaim_inode_grab(
 	 */
 	if ((flags & SYNC_TRYLOCK) &&
 	    __xfs_iflags_test(ip, XFS_IFLOCK | XFS_IRECLAIM))
-		return 1;
+		return false;
 
 	/*
 	 * The radix tree lock here protects a thread in xfs_iget from racing
@@ -1041,11 +1041,11 @@  xfs_reclaim_inode_grab(
 	    __xfs_iflags_test(ip, XFS_IRECLAIM)) {
 		/* not a reclaim candidate. */
 		spin_unlock(&ip->i_flags_lock);
-		return 1;
+		return false;
 	}
 	__xfs_iflags_set(ip, XFS_IRECLAIM);
 	spin_unlock(&ip->i_flags_lock);
-	return 0;
+	return true;
 }
 
 /*
@@ -1223,6 +1223,90 @@  xfs_reclaim_inode(
 	return 0;
 }
 
+/*
+ * Walk the RECLAIM tagged inodes in this AG looking for inodes to inactivate.
+ */
+STATIC int
+xfs_walk_ag_reclaim_inos(
+	struct xfs_perag	*pag,
+	int			sync_flags,
+	bool			(*grab_fn)(struct xfs_inode *ip,
+					   int sync_flags),
+	int			(*execute_fn)(struct xfs_inode *ip,
+					      struct xfs_perag *pag,
+					      int sync_flags),
+	int			*nr_to_scan,
+	bool			*done)
+{
+	struct xfs_mount	*mp = pag->pag_mount;
+	unsigned long		first_index = 0;
+	int			nr_found = 0;
+	int			last_error = 0;
+	int			error;
+
+	do {
+		struct xfs_inode *batch[XFS_LOOKUP_BATCH];
+		int	i;
+
+		rcu_read_lock();
+		nr_found = radix_tree_gang_lookup_tag(&pag->pag_ici_root,
+				(void **)batch, first_index, XFS_LOOKUP_BATCH,
+				XFS_ICI_RECLAIM_TAG);
+		if (!nr_found) {
+			*done = true;
+			rcu_read_unlock();
+			break;
+		}
+
+		/*
+		 * Grab the inodes before we drop the lock. if we found
+		 * nothing, nr == 0 and the loop will be skipped.
+		 */
+		for (i = 0; i < nr_found; i++) {
+			struct xfs_inode *ip = batch[i];
+
+			if (*done || !grab_fn(ip, sync_flags))
+				batch[i] = NULL;
+
+			/*
+			 * Update the index for the next lookup. Catch
+			 * overflows into the next AG range which can occur if
+			 * we have inodes in the last block of the AG and we
+			 * are currently pointing to the last inode.
+			 *
+			 * Because we may see inodes that are from the wrong AG
+			 * due to RCU freeing and reallocation, only update the
+			 * index if it lies in this AG. It was a race that lead
+			 * us to see this inode, so another lookup from the
+			 * same index will not find it again.
+			 */
+			if (XFS_INO_TO_AGNO(mp, ip->i_ino) != pag->pag_agno)
+				continue;
+			first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1);
+			if (first_index < XFS_INO_TO_AGINO(mp, ip->i_ino))
+				*done = true;
+		}
+
+		/* unlock now we've grabbed the inodes. */
+		rcu_read_unlock();
+
+		for (i = 0; i < nr_found; i++) {
+			if (!batch[i])
+				continue;
+			error = execute_fn(batch[i], pag, sync_flags);
+			if (error && last_error != -EFSCORRUPTED)
+				last_error = error;
+		}
+
+		*nr_to_scan -= XFS_LOOKUP_BATCH;
+
+		cond_resched();
+
+	} while (nr_found && !*done && *nr_to_scan > 0);
+
+	return last_error;
+}
+
 /*
  * Walk the AGs and reclaim the inodes in them. Even if the filesystem is
  * corrupted, we still want to try to reclaim all the inodes. If we don't,
@@ -1236,8 +1320,8 @@  xfs_reclaim_inodes_ag(
 	int			*nr_to_scan)
 {
 	struct xfs_perag	*pag;
-	int			error = 0;
 	int			last_error = 0;
+	int			error;
 	xfs_agnumber_t		ag;
 	int			trylock = flags & SYNC_TRYLOCK;
 	int			skipped;
@@ -1247,8 +1331,7 @@  xfs_reclaim_inodes_ag(
 	skipped = 0;
 	while ((pag = xfs_perag_get_tag(mp, ag, XFS_ICI_RECLAIM_TAG))) {
 		unsigned long	first_index = 0;
-		int		done = 0;
-		int		nr_found = 0;
+		bool		done = false;
 
 		ag = pag->pag_agno + 1;
 
@@ -1262,70 +1345,11 @@  xfs_reclaim_inodes_ag(
 		} else
 			mutex_lock(&pag->pag_ici_reclaim_lock);
 
-		do {
-			struct xfs_inode *batch[XFS_LOOKUP_BATCH];
-			int	i;
-
-			rcu_read_lock();
-			nr_found = radix_tree_gang_lookup_tag(
-					&pag->pag_ici_root,
-					(void **)batch, first_index,
-					XFS_LOOKUP_BATCH,
-					XFS_ICI_RECLAIM_TAG);
-			if (!nr_found) {
-				done = 1;
-				rcu_read_unlock();
-				break;
-			}
-
-			/*
-			 * Grab the inodes before we drop the lock. if we found
-			 * nothing, nr == 0 and the loop will be skipped.
-			 */
-			for (i = 0; i < nr_found; i++) {
-				struct xfs_inode *ip = batch[i];
-
-				if (done || xfs_reclaim_inode_grab(ip, flags))
-					batch[i] = NULL;
-
-				/*
-				 * Update the index for the next lookup. Catch
-				 * overflows into the next AG range which can
-				 * occur if we have inodes in the last block of
-				 * the AG and we are currently pointing to the
-				 * last inode.
-				 *
-				 * Because we may see inodes that are from the
-				 * wrong AG due to RCU freeing and
-				 * reallocation, only update the index if it
-				 * lies in this AG. It was a race that lead us
-				 * to see this inode, so another lookup from
-				 * the same index will not find it again.
-				 */
-				if (XFS_INO_TO_AGNO(mp, ip->i_ino) !=
-								pag->pag_agno)
-					continue;
-				first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1);
-				if (first_index < XFS_INO_TO_AGINO(mp, ip->i_ino))
-					done = 1;
-			}
-
-			/* unlock now we've grabbed the inodes. */
-			rcu_read_unlock();
-
-			for (i = 0; i < nr_found; i++) {
-				if (!batch[i])
-					continue;
-				error = xfs_reclaim_inode(batch[i], pag, flags);
-				if (error && last_error != -EFSCORRUPTED)
-					last_error = error;
-			}
-
-			*nr_to_scan -= XFS_LOOKUP_BATCH;
-
-			cond_resched();
-
-		} while (nr_found && !done && *nr_to_scan > 0);
+		error = xfs_walk_ag_reclaim_inos(pag, flags,
+				xfs_reclaim_inode_grab, xfs_reclaim_inode,
+				nr_to_scan, &done);
+		if (error && last_error != -EFSCORRUPTED)
+			last_error = error;
 
 		if (trylock && !done)
 			pag->pag_ici_reclaim_cursor = first_index;