When xfs_icwalk_ag skips an inode because it was RCU freed from another AG, the slot for the inode in the batch array needs to be zeroed. We also really shouldn't try to grab the inode in that case (or at very least undo the grab), so move the call to xfs_icwalk_ag after this sanity check. Fixes: 1a3e8f3da09c ("xfs: convert inode cache lookups to use RCU locking") Signed-off-by: Christoph Hellwig <hch@xxxxxx> --- fs/xfs/xfs_icache.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index ae3c049fd3a216..3ee92d3d1770db 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1701,9 +1701,6 @@ xfs_icwalk_ag( for (i = 0; i < nr_found; i++) { struct xfs_inode *ip = batch[i]; - if (done || !xfs_icwalk_igrab(goal, ip, icw)) - batch[i] = NULL; - /* * Update the index for the next lookup. Catch * overflows into the next AG range which can occur if @@ -1716,8 +1713,14 @@ xfs_icwalk_ag( * 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) + if (XFS_INO_TO_AGNO(mp, ip->i_ino) != pag->pag_agno) { + batch[i] = NULL; continue; + } + + if (done || !xfs_icwalk_igrab(goal, ip, icw)) + batch[i] = NULL; + first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1); if (first_index < XFS_INO_TO_AGINO(mp, ip->i_ino)) done = true; -- 2.43.0