Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 213253
b: refs/heads/master
c: e176579
h: refs/heads/master
i:
  213251: 798cc70
v: v3
  • Loading branch information
Dave Chinner authored and Alex Elder committed Oct 18, 2010
1 parent 6739a6c commit a5aa1a4
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 12 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: bd32d25a7cf7242512e77e70bab63df4402ab91c
refs/heads/master: e176579e70118ed7cfdb60f963628fe0ca771f3d
6 changes: 3 additions & 3 deletions trunk/fs/xfs/linux-2.6/xfs_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,17 +150,17 @@ xfs_inode_ag_iter_next_pag(
int found;
int ref;

spin_lock(&mp->m_perag_lock);
rcu_read_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);
rcu_read_unlock();
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);
rcu_read_unlock();
trace_xfs_perag_get_reclaim(mp, pag->pag_agno, ref, _RET_IP_);
} else {
pag = xfs_perag_get(mp, *first);
Expand Down
3 changes: 3 additions & 0 deletions trunk/fs/xfs/xfs_ag.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,9 @@ typedef struct xfs_perag {
rwlock_t pag_ici_lock; /* incore inode lock */
struct radix_tree_root pag_ici_root; /* incore inode cache root */
int pag_ici_reclaimable; /* reclaimable inodes */

/* for rcu-safe freeing */
struct rcu_head rcu_head;
#endif
int pagb_count; /* pagb slots in use */
} xfs_perag_t;
Expand Down
25 changes: 17 additions & 8 deletions trunk/fs/xfs/xfs_mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,20 +199,22 @@ xfs_uuid_unmount(

/*
* Reference counting access wrappers to the perag structures.
* Because we never free per-ag structures, the only thing we
* have to protect against changes is the tree structure itself.
*/
struct xfs_perag *
xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno)
{
struct xfs_perag *pag;
int ref = 0;

spin_lock(&mp->m_perag_lock);
rcu_read_lock();
pag = radix_tree_lookup(&mp->m_perag_tree, agno);
if (pag) {
ASSERT(atomic_read(&pag->pag_ref) >= 0);
ref = atomic_inc_return(&pag->pag_ref);
}
spin_unlock(&mp->m_perag_lock);
rcu_read_unlock();
trace_xfs_perag_get(mp, agno, ref, _RET_IP_);
return pag;
}
Expand All @@ -227,10 +229,18 @@ xfs_perag_put(struct xfs_perag *pag)
trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_);
}

STATIC void
__xfs_free_perag(
struct rcu_head *head)
{
struct xfs_perag *pag = container_of(head, struct xfs_perag, rcu_head);

ASSERT(atomic_read(&pag->pag_ref) == 0);
kmem_free(pag);
}

/*
* Free up the resources associated with a mount structure. Assume that
* the structure was initially zeroed, so we can tell which fields got
* initialized.
* Free up the per-ag resources associated with the mount structure.
*/
STATIC void
xfs_free_perag(
Expand All @@ -242,10 +252,9 @@ xfs_free_perag(
for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
spin_lock(&mp->m_perag_lock);
pag = radix_tree_delete(&mp->m_perag_tree, agno);
ASSERT(pag);
ASSERT(atomic_read(&pag->pag_ref) == 0);
spin_unlock(&mp->m_perag_lock);
kmem_free(pag);
ASSERT(pag);
call_rcu(&pag->rcu_head, __xfs_free_perag);
}
}

Expand Down

0 comments on commit a5aa1a4

Please sign in to comment.