Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aed3bb90 authored by Dave Chinner's avatar Dave Chinner Committed by Alex Elder
Browse files

xfs: Reference count per-ag structures



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: default avatarDave Chinner <david@fromorbit.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAlex Elder <aelder@sgi.com>
parent 1c1c6ebc
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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 */
+1 −0
Original line number Diff line number Diff line
@@ -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);
+9 −2
Original line number Diff line number Diff line
@@ -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)
@@ -393,6 +393,12 @@ 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;
}
@@ -400,7 +406,8 @@ xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno)
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);
}

/*