Skip to content

Commit 16eaab8

Browse files
Brian FosterDarrick J. Wong
authored andcommitted
xfs: introduce in-core global counter of allocbt blocks
Introduce an in-core counter to track the sum of all allocbt blocks used by the filesystem. This value is currently tracked per-ag via the ->agf_btreeblks field in the AGF, which also happens to include rmapbt blocks. A global, in-core count of allocbt blocks is required to identify the subset of global ->m_fdblocks that consists of unavailable blocks currently used for allocation btrees. To support this calculation at block reservation time, construct a similar global counter for allocbt blocks, populate it on first read of each AGF and update it as allocbt blocks are used and released. Signed-off-by: Brian Foster <[email protected]> Reviewed-by: Chandan Babu R <[email protected]> Reviewed-by: Allison Henderson <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]>
1 parent 2675ad3 commit 16eaab8

File tree

3 files changed

+22
-0
lines changed

3 files changed

+22
-0
lines changed

fs/xfs/libxfs/xfs_alloc.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3033,6 +3033,7 @@ xfs_alloc_read_agf(
30333033
struct xfs_agf *agf; /* ag freelist header */
30343034
struct xfs_perag *pag; /* per allocation group data */
30353035
int error;
3036+
int allocbt_blks;
30363037

30373038
trace_xfs_alloc_read_agf(mp, agno);
30383039

@@ -3063,6 +3064,19 @@ xfs_alloc_read_agf(
30633064
pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level);
30643065
pag->pagf_init = 1;
30653066
pag->pagf_agflreset = xfs_agfl_needs_reset(mp, agf);
3067+
3068+
/*
3069+
* Update the in-core allocbt counter. Filter out the rmapbt
3070+
* subset of the btreeblks counter because the rmapbt is managed
3071+
* by perag reservation. Subtract one for the rmapbt root block
3072+
* because the rmap counter includes it while the btreeblks
3073+
* counter only tracks non-root blocks.
3074+
*/
3075+
allocbt_blks = pag->pagf_btreeblks;
3076+
if (xfs_sb_version_hasrmapbt(&mp->m_sb))
3077+
allocbt_blks -= be32_to_cpu(agf->agf_rmap_blocks) - 1;
3078+
if (allocbt_blks > 0)
3079+
atomic64_add(allocbt_blks, &mp->m_allocbt_blks);
30663080
}
30673081
#ifdef DEBUG
30683082
else if (!XFS_FORCED_SHUTDOWN(mp)) {

fs/xfs/libxfs/xfs_alloc_btree.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ xfs_allocbt_alloc_block(
7171
return 0;
7272
}
7373

74+
atomic64_inc(&cur->bc_mp->m_allocbt_blks);
7475
xfs_extent_busy_reuse(cur->bc_mp, cur->bc_ag.agno, bno, 1, false);
7576

7677
new->s = cpu_to_be32(bno);
@@ -94,6 +95,7 @@ xfs_allocbt_free_block(
9495
if (error)
9596
return error;
9697

98+
atomic64_dec(&cur->bc_mp->m_allocbt_blks);
9799
xfs_extent_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1,
98100
XFS_EXTENT_BUSY_SKIP_DISCARD);
99101
return 0;

fs/xfs/xfs_mount.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,12 @@ typedef struct xfs_mount {
170170
* extents or anything related to the rt device.
171171
*/
172172
struct percpu_counter m_delalloc_blks;
173+
/*
174+
* Global count of allocation btree blocks in use across all AGs. Only
175+
* used when perag reservation is enabled. Helps prevent block
176+
* reservation from attempting to reserve allocation btree blocks.
177+
*/
178+
atomic64_t m_allocbt_blks;
173179

174180
struct radix_tree_root m_perag_tree; /* per-ag accounting info */
175181
spinlock_t m_perag_lock; /* lock for m_perag_tree */

0 commit comments

Comments
 (0)