Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7a3be02b authored by David Chinner's avatar David Chinner Committed by Lachlan McIlroy
Browse files

[XFS] use the inode radix tree for reclaiming inodes



Use the reclaim tag to walk the radix tree and find the inodes under
reclaim. This was the only user of the deleted inode list.

SGI-PV: 988142

SGI-Modid: xfs-linux-melb:xfs-kern:32333a

Signed-off-by: default avatarDavid Chinner <david@fromorbit.com>
Signed-off-by: default avatarLachlan McIlroy <lachlan@sgi.com>
Signed-off-by: default avatarChristoph Hellwig <hch@infradead.org>
parent 396beb85
Loading
Loading
Loading
Loading
+71 −10
Original line number Diff line number Diff line
@@ -685,32 +685,93 @@ xfs_inode_clear_reclaim_tag(
	xfs_put_perag(mp, pag);
}

int
xfs_reclaim_inodes(

STATIC void
xfs_reclaim_inodes_ag(
	xfs_mount_t	*mp,
	int		ag,
	int		noblock,
	int		mode)
{
	xfs_inode_t	*ip, *n;
	xfs_inode_t	*ip = NULL;
	xfs_perag_t	*pag = &mp->m_perag[ag];
	int		nr_found;
	int		first_index;
	int		skipped;

restart:
	XFS_MOUNT_ILOCK(mp);
	list_for_each_entry_safe(ip, n, &mp->m_del_inodes, i_reclaim) {
	first_index = 0;
	skipped = 0;
	do {
		/*
		 * use a gang lookup to find the next inode in the tree
		 * as the tree is sparse and a gang lookup walks to find
		 * the number of objects requested.
		 */
		read_lock(&pag->pag_ici_lock);
		nr_found = radix_tree_gang_lookup_tag(&pag->pag_ici_root,
					(void**)&ip, first_index, 1,
					XFS_ICI_RECLAIM_TAG);

		if (!nr_found) {
			read_unlock(&pag->pag_ici_lock);
			break;
		}

		/* update the index for the next lookup */
		first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1);

		ASSERT(xfs_iflags_test(ip, (XFS_IRECLAIMABLE|XFS_IRECLAIM)));

		/* ignore if already under reclaim */
		if (xfs_iflags_test(ip, XFS_IRECLAIM)) {
			read_unlock(&pag->pag_ici_lock);
			continue;
		}

		if (noblock) {
			if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL) == 0)
			if (!xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) {
				read_unlock(&pag->pag_ici_lock);
				continue;
			}
			if (xfs_ipincount(ip) ||
			    !xfs_iflock_nowait(ip)) {
				xfs_iunlock(ip, XFS_ILOCK_EXCL);
				read_unlock(&pag->pag_ici_lock);
				continue;
			}
		}
		XFS_MOUNT_IUNLOCK(mp);
		read_unlock(&pag->pag_ici_lock);

		/*
		 * hmmm - this is an inode already in reclaim. Do
		 * we even bother catching it here?
		 */
		if (xfs_reclaim_inode(ip, noblock, mode))
			skipped++;
	} while (nr_found);

	if (skipped) {
		delay(1);
		goto restart;
	}
	XFS_MOUNT_IUNLOCK(mp);
	return;

}

int
xfs_reclaim_inodes(
	xfs_mount_t	*mp,
	int		 noblock,
	int		mode)
{
	int		i;

	for (i = 0; i < mp->m_sb.sb_agcount; i++) {
		if (!mp->m_perag[i].pag_ici_init)
			continue;
		xfs_reclaim_inodes_ag(mp, i, noblock, mode);
	}
	return 0;
}