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:
parent
27b5286792
commit
a454f7428f
3 changed files with 59 additions and 11 deletions
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue