xfs: support a tag-based inode_ag_iterator

Genericize xfs_inode_ag_walk() to support an optional radix tree tag
and args argument for the execute function. Create a new wrapper
called xfs_inode_ag_iterator_tag() that performs a tag based walk
of perag's and inodes.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
This commit is contained in:
Brian Foster 2012-11-06 09:50:39 -05:00 committed by Ben Myers
parent 27b5286792
commit a454f7428f
3 changed files with 59 additions and 11 deletions

View file

@ -516,8 +516,11 @@ xfs_inode_ag_walk(
struct xfs_mount *mp, struct xfs_mount *mp,
struct xfs_perag *pag, struct xfs_perag *pag,
int (*execute)(struct xfs_inode *ip, int (*execute)(struct xfs_inode *ip,
struct xfs_perag *pag, int flags), struct xfs_perag *pag, int flags,
int flags) void *args),
int flags,
void *args,
int tag)
{ {
uint32_t first_index; uint32_t first_index;
int last_error = 0; int last_error = 0;
@ -536,9 +539,17 @@ xfs_inode_ag_walk(
int i; int i;
rcu_read_lock(); rcu_read_lock();
nr_found = radix_tree_gang_lookup(&pag->pag_ici_root,
if (tag == -1)
nr_found = radix_tree_gang_lookup(&pag->pag_ici_root,
(void **)batch, first_index, (void **)batch, first_index,
XFS_LOOKUP_BATCH); XFS_LOOKUP_BATCH);
else
nr_found = radix_tree_gang_lookup_tag(
&pag->pag_ici_root,
(void **) batch, first_index,
XFS_LOOKUP_BATCH, tag);
if (!nr_found) { if (!nr_found) {
rcu_read_unlock(); rcu_read_unlock();
break; break;
@ -579,7 +590,7 @@ xfs_inode_ag_walk(
for (i = 0; i < nr_found; i++) { for (i = 0; i < nr_found; i++) {
if (!batch[i]) if (!batch[i])
continue; continue;
error = execute(batch[i], pag, flags); error = execute(batch[i], pag, flags, args);
IRELE(batch[i]); IRELE(batch[i]);
if (error == EAGAIN) { if (error == EAGAIN) {
skipped++; skipped++;
@ -608,8 +619,10 @@ int
xfs_inode_ag_iterator( xfs_inode_ag_iterator(
struct xfs_mount *mp, struct xfs_mount *mp,
int (*execute)(struct xfs_inode *ip, int (*execute)(struct xfs_inode *ip,
struct xfs_perag *pag, int flags), struct xfs_perag *pag, int flags,
int flags) void *args),
int flags,
void *args)
{ {
struct xfs_perag *pag; struct xfs_perag *pag;
int error = 0; int error = 0;
@ -619,7 +632,36 @@ xfs_inode_ag_iterator(
ag = 0; ag = 0;
while ((pag = xfs_perag_get(mp, ag))) { while ((pag = xfs_perag_get(mp, ag))) {
ag = pag->pag_agno + 1; ag = pag->pag_agno + 1;
error = xfs_inode_ag_walk(mp, pag, execute, flags); error = xfs_inode_ag_walk(mp, pag, execute, flags, args, -1);
xfs_perag_put(pag);
if (error) {
last_error = error;
if (error == EFSCORRUPTED)
break;
}
}
return XFS_ERROR(last_error);
}
int
xfs_inode_ag_iterator_tag(
struct xfs_mount *mp,
int (*execute)(struct xfs_inode *ip,
struct xfs_perag *pag, int flags,
void *args),
int flags,
void *args,
int tag)
{
struct xfs_perag *pag;
int error = 0;
int last_error = 0;
xfs_agnumber_t ag;
ag = 0;
while ((pag = xfs_perag_get_tag(mp, ag, tag))) {
ag = pag->pag_agno + 1;
error = xfs_inode_ag_walk(mp, pag, execute, flags, args, tag);
xfs_perag_put(pag); xfs_perag_put(pag);
if (error) { if (error) {
last_error = error; last_error = error;

View file

@ -40,7 +40,12 @@ void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip);
int xfs_sync_inode_grab(struct xfs_inode *ip); int xfs_sync_inode_grab(struct xfs_inode *ip);
int xfs_inode_ag_iterator(struct xfs_mount *mp, int xfs_inode_ag_iterator(struct xfs_mount *mp,
int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags), int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag,
int flags); int flags, void *args),
int flags, void *args);
int xfs_inode_ag_iterator_tag(struct xfs_mount *mp,
int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag,
int flags, void *args),
int flags, void *args, int tag);
#endif #endif

View file

@ -846,7 +846,8 @@ STATIC int
xfs_dqrele_inode( xfs_dqrele_inode(
struct xfs_inode *ip, struct xfs_inode *ip,
struct xfs_perag *pag, struct xfs_perag *pag,
int flags) int flags,
void *args)
{ {
/* skip quota inodes */ /* skip quota inodes */
if (ip == ip->i_mount->m_quotainfo->qi_uquotaip || if (ip == ip->i_mount->m_quotainfo->qi_uquotaip ||
@ -882,5 +883,5 @@ xfs_qm_dqrele_all_inodes(
uint flags) uint flags)
{ {
ASSERT(mp->m_quotainfo); ASSERT(mp->m_quotainfo);
xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags); xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, NULL);
} }