Skip to content

Commit

Permalink
xfs: Reference count per-ag structures
Browse files Browse the repository at this point in the history
Reference count the per-ag structures to ensure that we keep get/put
pairs balanced. Assert that the reference counts are zero at unmount
time to catch leaks. In future, reference counts will enable us to
safely remove perag structures by allowing us to detect when they
are no longer in use.

Signed-off-by: Dave Chinner <[email protected]>
Reviewed-by: Christoph Hellwig <[email protected]>
Signed-off-by: Alex Elder <[email protected]>
  • Loading branch information
dchinner authored and Alex Elder committed Jan 15, 2010
1 parent 1c1c6eb commit aed3bb9
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 4 deletions.
4 changes: 2 additions & 2 deletions fs/xfs/xfs_ag.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,8 @@ typedef struct xfs_perag_busy {
#define XFS_PAGB_NUM_SLOTS 128
#endif

typedef struct xfs_perag
{
typedef struct xfs_perag {
atomic_t pag_ref; /* perag reference count */
char pagf_init; /* this agf's entry is initialized */
char pagi_init; /* this agi's entry is initialized */
char pagf_metadata; /* the agf is preferred to be metadata */
Expand Down
1 change: 1 addition & 0 deletions fs/xfs/xfs_mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ 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(atomic_read(&pag->pag_ref) == 0);
spin_unlock(&mp->m_perag_lock);
ASSERT(pag);
kmem_free(pag->pagb_list);
Expand Down
11 changes: 9 additions & 2 deletions fs/xfs/xfs_mount.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d)
}

/*
* perag get/put wrappers for eventual ref counting
* perag get/put wrappers for ref counting
*/
static inline struct xfs_perag *
xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno)
Expand All @@ -393,14 +393,21 @@ xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno)

spin_lock(&mp->m_perag_lock);
pag = radix_tree_lookup(&mp->m_perag_tree, agno);
if (pag) {
ASSERT(atomic_read(&pag->pag_ref) >= 0);
/* catch leaks in the positive direction during testing */
ASSERT(atomic_read(&pag->pag_ref) < 1000);
atomic_inc(&pag->pag_ref);
}
spin_unlock(&mp->m_perag_lock);
return pag;
}

static inline void
xfs_perag_put(struct xfs_perag *pag)
{
/* nothing to see here, move along */
ASSERT(atomic_read(&pag->pag_ref) > 0);
atomic_dec(&pag->pag_ref);
}

/*
Expand Down

0 comments on commit aed3bb9

Please sign in to comment.