xfs
[Top] [All Lists]

[PATCH v4 2/8] xfs: support a tag-based inode_ag_iterator

To: xfs@xxxxxxxxxxx
Subject: [PATCH v4 2/8] xfs: support a tag-based inode_ag_iterator
From: Brian Foster <bfoster@xxxxxxxxxx>
Date: Thu, 27 Sep 2012 13:45:46 -0400
In-reply-to: <1348767952-24229-1-git-send-email-bfoster@xxxxxxxxxx>
References: <1348767952-24229-1-git-send-email-bfoster@xxxxxxxxxx>
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@xxxxxxxxxx>
---
 fs/xfs/xfs_qm_syscalls.c |    5 ++-
 fs/xfs/xfs_sync.c        |   61 +++++++++++++++++++++++++++++++++++++++-------
 fs/xfs/xfs_sync.h        |    7 ++++-
 3 files changed, 60 insertions(+), 13 deletions(-)

diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 858a3b1..848bd8e 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -845,7 +845,8 @@ STATIC int
 xfs_dqrele_inode(
        struct xfs_inode        *ip,
        struct xfs_perag        *pag,
-       int                     flags)
+       int                     flags,
+       void                    *args)
 {
        /* skip quota inodes */
        if (ip == ip->i_mount->m_quotainfo->qi_uquotaip ||
@@ -881,5 +882,5 @@ xfs_qm_dqrele_all_inodes(
        uint             flags)
 {
        ASSERT(mp->m_quotainfo);
-       xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags);
+       xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, NULL);
 }
diff --git a/fs/xfs/xfs_sync.c b/fs/xfs/xfs_sync.c
index 00c6224..0da93c9 100644
--- a/fs/xfs/xfs_sync.c
+++ b/fs/xfs/xfs_sync.c
@@ -101,8 +101,11 @@ xfs_inode_ag_walk(
        struct xfs_mount        *mp,
        struct xfs_perag        *pag,
        int                     (*execute)(struct xfs_inode *ip,
-                                          struct xfs_perag *pag, int flags),
-       int                     flags)
+                                          struct xfs_perag *pag, int flags,
+                                          void *args),
+       int                     flags,
+       void                    *args,
+       int                     tag)
 {
        uint32_t                first_index;
        int                     last_error = 0;
@@ -121,9 +124,17 @@ restart:
                int             i;
 
                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,
                                        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) {
                        rcu_read_unlock();
                        break;
@@ -164,7 +175,7 @@ restart:
                for (i = 0; i < nr_found; i++) {
                        if (!batch[i])
                                continue;
-                       error = execute(batch[i], pag, flags);
+                       error = execute(batch[i], pag, flags, args);
                        IRELE(batch[i]);
                        if (error == EAGAIN) {
                                skipped++;
@@ -193,8 +204,10 @@ int
 xfs_inode_ag_iterator(
        struct xfs_mount        *mp,
        int                     (*execute)(struct xfs_inode *ip,
-                                          struct xfs_perag *pag, int flags),
-       int                     flags)
+                                          struct xfs_perag *pag, int flags,
+                                          void *args),
+       int                     flags,
+       void                    *args)
 {
        struct xfs_perag        *pag;
        int                     error = 0;
@@ -204,7 +217,36 @@ xfs_inode_ag_iterator(
        ag = 0;
        while ((pag = xfs_perag_get(mp, ag))) {
                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);
                if (error) {
                        last_error = error;
@@ -219,7 +261,8 @@ STATIC int
 xfs_sync_inode_data(
        struct xfs_inode        *ip,
        struct xfs_perag        *pag,
-       int                     flags)
+       int                     flags,
+       void                    *args)
 {
        struct inode            *inode = VFS_I(ip);
        struct address_space *mapping = inode->i_mapping;
@@ -252,7 +295,7 @@ xfs_sync_data(
 
        ASSERT((flags & ~(SYNC_TRYLOCK|SYNC_WAIT)) == 0);
 
-       error = xfs_inode_ag_iterator(mp, xfs_sync_inode_data, flags);
+       error = xfs_inode_ag_iterator(mp, xfs_sync_inode_data, flags, NULL);
        if (error)
                return XFS_ERROR(error);
 
diff --git a/fs/xfs/xfs_sync.h b/fs/xfs/xfs_sync.h
index 4486491..463ea0a 100644
--- a/fs/xfs/xfs_sync.h
+++ b/fs/xfs/xfs_sync.h
@@ -48,7 +48,10 @@ void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip);
 
 int xfs_sync_inode_grab(struct xfs_inode *ip);
 int xfs_inode_ag_iterator(struct xfs_mount *mp,
-       int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags),
-       int flags);
+       int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, 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
-- 
1.7.7.6

<Prev in Thread] Current Thread [Next in Thread>