Skip to content

Commit 131ffe5

Browse files
committed
Merge tag 'perag-xarray-6.13_2024-11-05' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux into staging-merge
xfs: convert perag to use xarrays [v5.5 01/10] Convert the xfs_mount perag tree to use an xarray instead of a radix tree. There should be no functional changes here. With a bit of luck, this should all go splendidly. Signed-off-by: Darrick J. Wong <[email protected]>
2 parents fe4e0fa + d664965 commit 131ffe5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+457
-529
lines changed

fs/xfs/libxfs/xfs_ag.c

Lines changed: 73 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,7 @@ xfs_perag_rele(
107107
struct xfs_perag *pag)
108108
{
109109
trace_xfs_perag_rele(pag, _RET_IP_);
110-
if (atomic_dec_and_test(&pag->pag_active_ref))
111-
wake_up(&pag->pag_active_wq);
110+
atomic_dec(&pag->pag_active_ref);
112111
}
113112

114113
/*
@@ -273,6 +272,10 @@ xfs_agino_range(
273272
return __xfs_agino_range(mp, xfs_ag_block_count(mp, agno), first, last);
274273
}
275274

275+
/*
276+
* Update the perag of the previous tail AG if it has been changed during
277+
* recovery (i.e. recovery of a growfs).
278+
*/
276279
int
277280
xfs_update_last_ag_size(
278281
struct xfs_mount *mp,
@@ -290,80 +293,92 @@ xfs_update_last_ag_size(
290293
return 0;
291294
}
292295

293-
int
294-
xfs_initialize_perag(
296+
static int
297+
xfs_perag_alloc(
295298
struct xfs_mount *mp,
296-
xfs_agnumber_t old_agcount,
297-
xfs_agnumber_t new_agcount,
298-
xfs_rfsblock_t dblocks,
299-
xfs_agnumber_t *maxagi)
299+
xfs_agnumber_t index,
300+
xfs_agnumber_t agcount,
301+
xfs_rfsblock_t dblocks)
300302
{
301303
struct xfs_perag *pag;
302-
xfs_agnumber_t index;
303304
int error;
304305

305-
for (index = old_agcount; index < new_agcount; index++) {
306-
pag = kzalloc(sizeof(*pag), GFP_KERNEL);
307-
if (!pag) {
308-
error = -ENOMEM;
309-
goto out_unwind_new_pags;
310-
}
311-
pag->pag_agno = index;
312-
pag->pag_mount = mp;
313-
314-
error = xa_insert(&mp->m_perags, index, pag, GFP_KERNEL);
315-
if (error) {
316-
WARN_ON_ONCE(error == -EBUSY);
317-
goto out_free_pag;
318-
}
306+
pag = kzalloc(sizeof(*pag), GFP_KERNEL);
307+
if (!pag)
308+
return -ENOMEM;
319309

320310
#ifdef __KERNEL__
321-
/* Place kernel structure only init below this point. */
322-
spin_lock_init(&pag->pag_ici_lock);
323-
spin_lock_init(&pag->pagb_lock);
324-
spin_lock_init(&pag->pag_state_lock);
325-
INIT_DELAYED_WORK(&pag->pag_blockgc_work, xfs_blockgc_worker);
326-
INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
327-
xfs_defer_drain_init(&pag->pag_intents_drain);
328-
init_waitqueue_head(&pag->pagb_wait);
329-
init_waitqueue_head(&pag->pag_active_wq);
330-
pag->pagb_count = 0;
331-
pag->pagb_tree = RB_ROOT;
332-
xfs_hooks_init(&pag->pag_rmap_update_hooks);
311+
/* Place kernel structure only init below this point. */
312+
spin_lock_init(&pag->pag_ici_lock);
313+
spin_lock_init(&pag->pagb_lock);
314+
spin_lock_init(&pag->pag_state_lock);
315+
INIT_DELAYED_WORK(&pag->pag_blockgc_work, xfs_blockgc_worker);
316+
INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
317+
xfs_defer_drain_init(&pag->pag_intents_drain);
318+
init_waitqueue_head(&pag->pagb_wait);
319+
pag->pagb_tree = RB_ROOT;
320+
xfs_hooks_init(&pag->pag_rmap_update_hooks);
333321
#endif /* __KERNEL__ */
334322

335-
error = xfs_buf_cache_init(&pag->pag_bcache);
336-
if (error)
337-
goto out_remove_pag;
323+
error = xfs_buf_cache_init(&pag->pag_bcache);
324+
if (error)
325+
goto out_defer_drain_free;
338326

339-
/* Active ref owned by mount indicates AG is online. */
340-
atomic_set(&pag->pag_active_ref, 1);
327+
/*
328+
* Pre-calculated geometry
329+
*/
330+
pag->block_count = __xfs_ag_block_count(mp, index, agcount, dblocks);
331+
pag->min_block = XFS_AGFL_BLOCK(mp);
332+
__xfs_agino_range(mp, pag->block_count, &pag->agino_min,
333+
&pag->agino_max);
341334

342-
/*
343-
* Pre-calculated geometry
344-
*/
345-
pag->block_count = __xfs_ag_block_count(mp, index, new_agcount,
346-
dblocks);
347-
pag->min_block = XFS_AGFL_BLOCK(mp);
348-
__xfs_agino_range(mp, pag->block_count, &pag->agino_min,
349-
&pag->agino_max);
335+
pag->pag_agno = index;
336+
pag->pag_mount = mp;
337+
/* Active ref owned by mount indicates AG is online. */
338+
atomic_set(&pag->pag_active_ref, 1);
339+
340+
error = xa_insert(&mp->m_perags, index, pag, GFP_KERNEL);
341+
if (error) {
342+
WARN_ON_ONCE(error == -EBUSY);
343+
goto out_buf_cache_destroy;
350344
}
351345

352-
index = xfs_set_inode_alloc(mp, new_agcount);
346+
return 0;
353347

354-
if (maxagi)
355-
*maxagi = index;
348+
out_buf_cache_destroy:
349+
xfs_buf_cache_destroy(&pag->pag_bcache);
350+
out_defer_drain_free:
351+
xfs_defer_drain_free(&pag->pag_intents_drain);
352+
kfree(pag);
353+
return error;
354+
}
356355

356+
int
357+
xfs_initialize_perag(
358+
struct xfs_mount *mp,
359+
xfs_agnumber_t orig_agcount,
360+
xfs_agnumber_t new_agcount,
361+
xfs_rfsblock_t dblocks,
362+
xfs_agnumber_t *maxagi)
363+
{
364+
xfs_agnumber_t index;
365+
int error;
366+
367+
if (orig_agcount >= new_agcount)
368+
return 0;
369+
370+
for (index = orig_agcount; index < new_agcount; index++) {
371+
error = xfs_perag_alloc(mp, index, new_agcount, dblocks);
372+
if (error)
373+
goto out_unwind_new_pags;
374+
}
375+
376+
*maxagi = xfs_set_inode_alloc(mp, new_agcount);
357377
mp->m_ag_prealloc_blocks = xfs_prealloc_blocks(mp);
358378
return 0;
359379

360-
out_remove_pag:
361-
xfs_defer_drain_free(&pag->pag_intents_drain);
362-
pag = xa_erase(&mp->m_perags, index);
363-
out_free_pag:
364-
kfree(pag);
365380
out_unwind_new_pags:
366-
xfs_free_perag_range(mp, old_agcount, index);
381+
xfs_free_perag_range(mp, orig_agcount, index);
367382
return error;
368383
}
369384

@@ -872,7 +887,7 @@ xfs_ag_shrink_space(
872887

873888
/* internal log shouldn't also show up in the free space btrees */
874889
error = xfs_alloc_vextent_exact_bno(&args,
875-
XFS_AGB_TO_FSB(mp, pag->pag_agno, aglen - delta));
890+
xfs_agbno_to_fsb(pag, aglen - delta));
876891
if (!error && args.agbno == NULLAGBLOCK)
877892
error = -ENOSPC;
878893

fs/xfs/libxfs/xfs_ag.h

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ struct xfs_perag {
3434
xfs_agnumber_t pag_agno; /* AG this structure belongs to */
3535
atomic_t pag_ref; /* passive reference count */
3636
atomic_t pag_active_ref; /* active reference count */
37-
wait_queue_head_t pag_active_wq;/* woken active_ref falls to zero */
3837
unsigned long pag_opstate;
3938
uint8_t pagf_bno_level; /* # of levels in bno btree */
4039
uint8_t pagf_cnt_level; /* # of levels in cnt btree */
@@ -55,7 +54,6 @@ struct xfs_perag {
5554
xfs_agino_t pagl_leftrec;
5655
xfs_agino_t pagl_rightrec;
5756

58-
int pagb_count; /* pagb slots in use */
5957
uint8_t pagf_refcount_level; /* recount btree height */
6058

6159
/* Blocks reserved for all kinds of metadata. */
@@ -144,8 +142,8 @@ __XFS_AG_OPSTATE(prefers_metadata, PREFERS_METADATA)
144142
__XFS_AG_OPSTATE(allows_inodes, ALLOWS_INODES)
145143
__XFS_AG_OPSTATE(agfl_needs_reset, AGFL_NEEDS_RESET)
146144

147-
int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t old_agcount,
148-
xfs_agnumber_t agcount, xfs_rfsblock_t dcount,
145+
int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t orig_agcount,
146+
xfs_agnumber_t new_agcount, xfs_rfsblock_t dcount,
149147
xfs_agnumber_t *maxagi);
150148
void xfs_free_perag_range(struct xfs_mount *mp, xfs_agnumber_t first_agno,
151149
xfs_agnumber_t end_agno);
@@ -332,4 +330,28 @@ int xfs_ag_extend_space(struct xfs_perag *pag, struct xfs_trans *tp,
332330
xfs_extlen_t len);
333331
int xfs_ag_get_geometry(struct xfs_perag *pag, struct xfs_ag_geometry *ageo);
334332

333+
static inline xfs_fsblock_t
334+
xfs_agbno_to_fsb(
335+
struct xfs_perag *pag,
336+
xfs_agblock_t agbno)
337+
{
338+
return XFS_AGB_TO_FSB(pag->pag_mount, pag->pag_agno, agbno);
339+
}
340+
341+
static inline xfs_daddr_t
342+
xfs_agbno_to_daddr(
343+
struct xfs_perag *pag,
344+
xfs_agblock_t agbno)
345+
{
346+
return XFS_AGB_TO_DADDR(pag->pag_mount, pag->pag_agno, agbno);
347+
}
348+
349+
static inline xfs_ino_t
350+
xfs_agino_to_ino(
351+
struct xfs_perag *pag,
352+
xfs_agino_t agino)
353+
{
354+
return XFS_AGINO_TO_INO(pag->pag_mount, pag->pag_agno, agino);
355+
}
356+
335357
#endif /* __LIBXFS_AG_H */

fs/xfs/libxfs/xfs_ag_resv.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,7 @@ __xfs_ag_resv_init(
206206
else
207207
error = xfs_dec_fdblocks(mp, hidden_space, true);
208208
if (error) {
209-
trace_xfs_ag_resv_init_error(pag->pag_mount, pag->pag_agno,
210-
error, _RET_IP_);
209+
trace_xfs_ag_resv_init_error(pag, error, _RET_IP_);
211210
xfs_warn(mp,
212211
"Per-AG reservation for AG %u failed. Filesystem may run out of space.",
213212
pag->pag_agno);

fs/xfs/libxfs/xfs_alloc.c

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,14 +1252,14 @@ xfs_alloc_ag_vextent_small(
12521252
if (fbno == NULLAGBLOCK)
12531253
goto out;
12541254

1255-
xfs_extent_busy_reuse(args->mp, args->pag, fbno, 1,
1255+
xfs_extent_busy_reuse(args->pag, fbno, 1,
12561256
(args->datatype & XFS_ALLOC_NOBUSY));
12571257

12581258
if (args->datatype & XFS_ALLOC_USERDATA) {
12591259
struct xfs_buf *bp;
12601260

12611261
error = xfs_trans_get_buf(args->tp, args->mp->m_ddev_targp,
1262-
XFS_AGB_TO_DADDR(args->mp, args->agno, fbno),
1262+
xfs_agbno_to_daddr(args->pag, fbno),
12631263
args->mp->m_bsize, 0, &bp);
12641264
if (error)
12651265
goto error;
@@ -2037,7 +2037,6 @@ int
20372037
xfs_free_ag_extent(
20382038
struct xfs_trans *tp,
20392039
struct xfs_buf *agbp,
2040-
xfs_agnumber_t agno,
20412040
xfs_agblock_t bno,
20422041
xfs_extlen_t len,
20432042
const struct xfs_owner_info *oinfo,
@@ -2358,19 +2357,19 @@ xfs_free_ag_extent(
23582357
* Update the freespace totals in the ag and superblock.
23592358
*/
23602359
error = xfs_alloc_update_counters(tp, agbp, len);
2361-
xfs_ag_resv_free_extent(agbp->b_pag, type, tp, len);
2360+
xfs_ag_resv_free_extent(pag, type, tp, len);
23622361
if (error)
23632362
goto error0;
23642363

23652364
XFS_STATS_INC(mp, xs_freex);
23662365
XFS_STATS_ADD(mp, xs_freeb, len);
23672366

2368-
trace_xfs_free_extent(mp, agno, bno, len, type, haveleft, haveright);
2367+
trace_xfs_free_extent(pag, bno, len, type, haveleft, haveright);
23692368

23702369
return 0;
23712370

23722371
error0:
2373-
trace_xfs_free_extent(mp, agno, bno, len, type, -1, -1);
2372+
trace_xfs_free_extent(pag, bno, len, type, -1, -1);
23742373
if (bno_cur)
23752374
xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR);
23762375
if (cnt_cur)
@@ -2934,9 +2933,8 @@ xfs_alloc_fix_freelist(
29342933
* Deferring the free disconnects freeing up the AGFL slot from
29352934
* freeing the block.
29362935
*/
2937-
error = xfs_free_extent_later(tp,
2938-
XFS_AGB_TO_FSB(mp, args->agno, bno), 1,
2939-
&targs.oinfo, XFS_AG_RESV_AGFL, 0);
2936+
error = xfs_free_extent_later(tp, xfs_agbno_to_fsb(pag, bno),
2937+
1, &targs.oinfo, XFS_AG_RESV_AGFL, 0);
29402938
if (error)
29412939
goto out_agbp_relse;
29422940
}
@@ -3360,7 +3358,7 @@ xfs_read_agf(
33603358
struct xfs_mount *mp = pag->pag_mount;
33613359
int error;
33623360

3363-
trace_xfs_read_agf(pag->pag_mount, pag->pag_agno);
3361+
trace_xfs_read_agf(pag);
33643362

33653363
error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
33663364
XFS_AG_DADDR(mp, pag->pag_agno, XFS_AGF_DADDR(mp)),
@@ -3391,7 +3389,7 @@ xfs_alloc_read_agf(
33913389
int error;
33923390
int allocbt_blks;
33933391

3394-
trace_xfs_alloc_read_agf(pag->pag_mount, pag->pag_agno);
3392+
trace_xfs_alloc_read_agf(pag);
33953393

33963394
/* We don't support trylock when freeing. */
33973395
ASSERT((flags & (XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK)) !=
@@ -3595,7 +3593,7 @@ xfs_alloc_vextent_finish(
35953593
goto out_drop_perag;
35963594
}
35973595

3598-
args->fsbno = XFS_AGB_TO_FSB(mp, args->agno, args->agbno);
3596+
args->fsbno = xfs_agbno_to_fsb(args->pag, args->agbno);
35993597

36003598
ASSERT(args->len >= args->minlen);
36013599
ASSERT(args->len <= args->maxlen);
@@ -3616,7 +3614,7 @@ xfs_alloc_vextent_finish(
36163614
if (error)
36173615
goto out_drop_perag;
36183616

3619-
ASSERT(!xfs_extent_busy_search(mp, args->pag, args->agbno,
3617+
ASSERT(!xfs_extent_busy_search(args->pag, args->agbno,
36203618
args->len));
36213619
}
36223620

@@ -3647,7 +3645,6 @@ xfs_alloc_vextent_this_ag(
36473645
struct xfs_alloc_arg *args,
36483646
xfs_agnumber_t agno)
36493647
{
3650-
struct xfs_mount *mp = args->mp;
36513648
xfs_agnumber_t minimum_agno;
36523649
uint32_t alloc_flags = 0;
36533650
int error;
@@ -3660,8 +3657,8 @@ xfs_alloc_vextent_this_ag(
36603657

36613658
trace_xfs_alloc_vextent_this_ag(args);
36623659

3663-
error = xfs_alloc_vextent_check_args(args, XFS_AGB_TO_FSB(mp, agno, 0),
3664-
&minimum_agno);
3660+
error = xfs_alloc_vextent_check_args(args,
3661+
xfs_agbno_to_fsb(args->pag, 0), &minimum_agno);
36653662
if (error) {
36663663
if (error == -ENOSPC)
36673664
return 0;
@@ -4010,8 +4007,7 @@ __xfs_free_extent(
40104007
goto err_release;
40114008
}
40124009

4013-
error = xfs_free_ag_extent(tp, agbp, pag->pag_agno, agbno, len, oinfo,
4014-
type);
4010+
error = xfs_free_ag_extent(tp, agbp, agbno, len, oinfo, type);
40154011
if (error)
40164012
goto err_release;
40174013

fs/xfs/libxfs/xfs_alloc.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,8 @@ int xfs_alloc_put_freelist(struct xfs_perag *pag, struct xfs_trans *tp,
7979
struct xfs_buf *agfbp, struct xfs_buf *agflbp,
8080
xfs_agblock_t bno, int btreeblk);
8181
int xfs_free_ag_extent(struct xfs_trans *tp, struct xfs_buf *agbp,
82-
xfs_agnumber_t agno, xfs_agblock_t bno,
83-
xfs_extlen_t len, const struct xfs_owner_info *oinfo,
84-
enum xfs_ag_resv_type type);
82+
xfs_agblock_t bno, xfs_extlen_t len,
83+
const struct xfs_owner_info *oinfo, enum xfs_ag_resv_type type);
8584

8685
/*
8786
* Compute and fill in value of m_alloc_maxlevels.

fs/xfs/libxfs/xfs_alloc_btree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ xfs_allocbt_alloc_block(
8686
}
8787

8888
atomic64_inc(&cur->bc_mp->m_allocbt_blks);
89-
xfs_extent_busy_reuse(cur->bc_mp, cur->bc_ag.pag, bno, 1, false);
89+
xfs_extent_busy_reuse(cur->bc_ag.pag, bno, 1, false);
9090

9191
new->s = cpu_to_be32(bno);
9292

0 commit comments

Comments
 (0)