Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 201058
b: refs/heads/master
c: 16fd536
h: refs/heads/master
v: v3
  • Loading branch information
Dave Chinner authored and Dave Chinner committed Jul 19, 2010
1 parent 65656f4 commit c80dfc9
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 70e60ce71516c3a9e882edb70a09f696a05961db
refs/heads/master: 16fd5367370099b59d96e30bb7d9de8d419659f2
71 changes: 64 additions & 7 deletions trunk/fs/xfs/linux-2.6/xfs_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,41 @@ xfs_inode_ag_walk(
return last_error;
}

/*
* Select the next per-ag structure to iterate during the walk. The reclaim
* walk is optimised only to walk AGs with reclaimable inodes in them.
*/
static struct xfs_perag *
xfs_inode_ag_iter_next_pag(
struct xfs_mount *mp,
xfs_agnumber_t *first,
int tag)
{
struct xfs_perag *pag = NULL;

if (tag == XFS_ICI_RECLAIM_TAG) {
int found;
int ref;

spin_lock(&mp->m_perag_lock);
found = radix_tree_gang_lookup_tag(&mp->m_perag_tree,
(void **)&pag, *first, 1, tag);
if (found <= 0) {
spin_unlock(&mp->m_perag_lock);
return NULL;
}
*first = pag->pag_agno + 1;
/* open coded pag reference increment */
ref = atomic_inc_return(&pag->pag_ref);
spin_unlock(&mp->m_perag_lock);
trace_xfs_perag_get_reclaim(mp, pag->pag_agno, ref, _RET_IP_);
} else {
pag = xfs_perag_get(mp, *first);
(*first)++;
}
return pag;
}

int
xfs_inode_ag_iterator(
struct xfs_mount *mp,
Expand All @@ -154,16 +189,15 @@ xfs_inode_ag_iterator(
int exclusive,
int *nr_to_scan)
{
struct xfs_perag *pag;
int error = 0;
int last_error = 0;
xfs_agnumber_t ag;
int nr;

nr = nr_to_scan ? *nr_to_scan : INT_MAX;
for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) {
struct xfs_perag *pag;

pag = xfs_perag_get(mp, ag);
ag = 0;
while ((pag = xfs_inode_ag_iter_next_pag(mp, &ag, tag))) {
error = xfs_inode_ag_walk(mp, pag, execute, flags, tag,
exclusive, &nr);
xfs_perag_put(pag);
Expand Down Expand Up @@ -640,6 +674,17 @@ __xfs_inode_set_reclaim_tag(
radix_tree_tag_set(&pag->pag_ici_root,
XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino),
XFS_ICI_RECLAIM_TAG);

if (!pag->pag_ici_reclaimable) {
/* propagate the reclaim tag up into the perag radix tree */
spin_lock(&ip->i_mount->m_perag_lock);
radix_tree_tag_set(&ip->i_mount->m_perag_tree,
XFS_INO_TO_AGNO(ip->i_mount, ip->i_ino),
XFS_ICI_RECLAIM_TAG);
spin_unlock(&ip->i_mount->m_perag_lock);
trace_xfs_perag_set_reclaim(ip->i_mount, pag->pag_agno,
-1, _RET_IP_);
}
pag->pag_ici_reclaimable++;
}

Expand Down Expand Up @@ -674,6 +719,16 @@ __xfs_inode_clear_reclaim_tag(
radix_tree_tag_clear(&pag->pag_ici_root,
XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG);
pag->pag_ici_reclaimable--;
if (!pag->pag_ici_reclaimable) {
/* clear the reclaim tag from the perag radix tree */
spin_lock(&ip->i_mount->m_perag_lock);
radix_tree_tag_clear(&ip->i_mount->m_perag_tree,
XFS_INO_TO_AGNO(ip->i_mount, ip->i_ino),
XFS_ICI_RECLAIM_TAG);
spin_unlock(&ip->i_mount->m_perag_lock);
trace_xfs_perag_clear_reclaim(ip->i_mount, pag->pag_agno,
-1, _RET_IP_);
}
}

/*
Expand Down Expand Up @@ -838,7 +893,7 @@ xfs_reclaim_inode_shrink(
struct xfs_mount *mp;
struct xfs_perag *pag;
xfs_agnumber_t ag;
int reclaimable = 0;
int reclaimable;

mp = container_of(shrink, struct xfs_mount, m_inode_shrink);
if (nr_to_scan) {
Expand All @@ -852,8 +907,10 @@ xfs_reclaim_inode_shrink(
return -1;
}

for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) {
pag = xfs_perag_get(mp, ag);
reclaimable = 0;
ag = 0;
while ((pag = xfs_inode_ag_iter_next_pag(mp, &ag,
XFS_ICI_RECLAIM_TAG))) {
reclaimable += pag->pag_ici_reclaimable;
xfs_perag_put(pag);
}
Expand Down
3 changes: 3 additions & 0 deletions trunk/fs/xfs/linux-2.6/xfs_trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,10 @@ DEFINE_EVENT(xfs_perag_class, name, \
unsigned long caller_ip), \
TP_ARGS(mp, agno, refcount, caller_ip))
DEFINE_PERAG_REF_EVENT(xfs_perag_get);
DEFINE_PERAG_REF_EVENT(xfs_perag_get_reclaim);
DEFINE_PERAG_REF_EVENT(xfs_perag_put);
DEFINE_PERAG_REF_EVENT(xfs_perag_set_reclaim);
DEFINE_PERAG_REF_EVENT(xfs_perag_clear_reclaim);

TRACE_EVENT(xfs_attr_list_node_descend,
TP_PROTO(struct xfs_attr_list_context *ctx,
Expand Down

0 comments on commit c80dfc9

Please sign in to comment.