Skip to content

Commit 28cf0d1

Browse files
committed
Merge tag 'generic-groups-6.13_2024-11-05' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux into staging-merge
xfs: create a generic allocation group structure [v5.5 02/10] Soon we'll be sharding the realtime volume into separate allocation groups. These rt groups will /mostly/ behave the same as the ones on the data device, but since rt groups don't have quite the same set of struct fields as perags, let's hoist the parts that will be shared by both into a common xfs_group object. With a bit of luck, this should all go splendidly. Signed-off-by: Darrick J. Wong <[email protected]>
2 parents 131ffe5 + e5e5cae commit 28cf0d1

Some content is hidden

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

70 files changed

+1381
-1051
lines changed

fs/xfs/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ xfs-y += xfs_trace.o
1414

1515
# build the libxfs code first
1616
xfs-y += $(addprefix libxfs/, \
17+
xfs_group.o \
1718
xfs_ag.o \
1819
xfs_alloc.o \
1920
xfs_alloc_btree.o \

fs/xfs/libxfs/xfs_ag.c

Lines changed: 28 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -30,85 +30,7 @@
3030
#include "xfs_trace.h"
3131
#include "xfs_inode.h"
3232
#include "xfs_icache.h"
33-
34-
35-
/*
36-
* Passive reference counting access wrappers to the perag structures. If the
37-
* per-ag structure is to be freed, the freeing code is responsible for cleaning
38-
* up objects with passive references before freeing the structure. This is
39-
* things like cached buffers.
40-
*/
41-
struct xfs_perag *
42-
xfs_perag_get(
43-
struct xfs_mount *mp,
44-
xfs_agnumber_t agno)
45-
{
46-
struct xfs_perag *pag;
47-
48-
rcu_read_lock();
49-
pag = xa_load(&mp->m_perags, agno);
50-
if (pag) {
51-
trace_xfs_perag_get(pag, _RET_IP_);
52-
ASSERT(atomic_read(&pag->pag_ref) >= 0);
53-
atomic_inc(&pag->pag_ref);
54-
}
55-
rcu_read_unlock();
56-
return pag;
57-
}
58-
59-
/* Get a passive reference to the given perag. */
60-
struct xfs_perag *
61-
xfs_perag_hold(
62-
struct xfs_perag *pag)
63-
{
64-
ASSERT(atomic_read(&pag->pag_ref) > 0 ||
65-
atomic_read(&pag->pag_active_ref) > 0);
66-
67-
trace_xfs_perag_hold(pag, _RET_IP_);
68-
atomic_inc(&pag->pag_ref);
69-
return pag;
70-
}
71-
72-
void
73-
xfs_perag_put(
74-
struct xfs_perag *pag)
75-
{
76-
trace_xfs_perag_put(pag, _RET_IP_);
77-
ASSERT(atomic_read(&pag->pag_ref) > 0);
78-
atomic_dec(&pag->pag_ref);
79-
}
80-
81-
/*
82-
* Active references for perag structures. This is for short term access to the
83-
* per ag structures for walking trees or accessing state. If an AG is being
84-
* shrunk or is offline, then this will fail to find that AG and return NULL
85-
* instead.
86-
*/
87-
struct xfs_perag *
88-
xfs_perag_grab(
89-
struct xfs_mount *mp,
90-
xfs_agnumber_t agno)
91-
{
92-
struct xfs_perag *pag;
93-
94-
rcu_read_lock();
95-
pag = xa_load(&mp->m_perags, agno);
96-
if (pag) {
97-
trace_xfs_perag_grab(pag, _RET_IP_);
98-
if (!atomic_inc_not_zero(&pag->pag_active_ref))
99-
pag = NULL;
100-
}
101-
rcu_read_unlock();
102-
return pag;
103-
}
104-
105-
void
106-
xfs_perag_rele(
107-
struct xfs_perag *pag)
108-
{
109-
trace_xfs_perag_rele(pag, _RET_IP_);
110-
atomic_dec(&pag->pag_active_ref);
111-
}
33+
#include "xfs_group.h"
11234

11335
/*
11436
* xfs_initialize_perag_data
@@ -183,6 +105,18 @@ xfs_initialize_perag_data(
183105
return error;
184106
}
185107

108+
static void
109+
xfs_perag_uninit(
110+
struct xfs_group *xg)
111+
{
112+
#ifdef __KERNEL__
113+
struct xfs_perag *pag = to_perag(xg);
114+
115+
cancel_delayed_work_sync(&pag->pag_blockgc_work);
116+
xfs_buf_cache_destroy(&pag->pag_bcache);
117+
#endif
118+
}
119+
186120
/*
187121
* Free up the per-ag resources within the specified AG range.
188122
*/
@@ -195,22 +129,8 @@ xfs_free_perag_range(
195129
{
196130
xfs_agnumber_t agno;
197131

198-
for (agno = first_agno; agno < end_agno; agno++) {
199-
struct xfs_perag *pag = xa_erase(&mp->m_perags, agno);
200-
201-
ASSERT(pag);
202-
XFS_IS_CORRUPT(pag->pag_mount, atomic_read(&pag->pag_ref) != 0);
203-
xfs_defer_drain_free(&pag->pag_intents_drain);
204-
205-
cancel_delayed_work_sync(&pag->pag_blockgc_work);
206-
xfs_buf_cache_destroy(&pag->pag_bcache);
207-
208-
/* drop the mount's active reference */
209-
xfs_perag_rele(pag);
210-
XFS_IS_CORRUPT(pag->pag_mount,
211-
atomic_read(&pag->pag_active_ref) != 0);
212-
kfree_rcu_mightsleep(pag);
213-
}
132+
for (agno = first_agno; agno < end_agno; agno++)
133+
xfs_group_free(mp, agno, XG_TYPE_AG, xfs_perag_uninit);
214134
}
215135

216136
/* Find the size of the AG, in blocks. */
@@ -310,19 +230,13 @@ xfs_perag_alloc(
310230
#ifdef __KERNEL__
311231
/* Place kernel structure only init below this point. */
312232
spin_lock_init(&pag->pag_ici_lock);
313-
spin_lock_init(&pag->pagb_lock);
314-
spin_lock_init(&pag->pag_state_lock);
315233
INIT_DELAYED_WORK(&pag->pag_blockgc_work, xfs_blockgc_worker);
316234
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);
321235
#endif /* __KERNEL__ */
322236

323237
error = xfs_buf_cache_init(&pag->pag_bcache);
324238
if (error)
325-
goto out_defer_drain_free;
239+
goto out_free_perag;
326240

327241
/*
328242
* Pre-calculated geometry
@@ -332,23 +246,15 @@ xfs_perag_alloc(
332246
__xfs_agino_range(mp, pag->block_count, &pag->agino_min,
333247
&pag->agino_max);
334248

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);
249+
error = xfs_group_insert(mp, pag_group(pag), index, XG_TYPE_AG);
250+
if (error)
343251
goto out_buf_cache_destroy;
344-
}
345252

346253
return 0;
347254

348255
out_buf_cache_destroy:
349256
xfs_buf_cache_destroy(&pag->pag_bcache);
350-
out_defer_drain_free:
351-
xfs_defer_drain_free(&pag->pag_intents_drain);
257+
out_free_perag:
352258
kfree(pag);
353259
return error;
354260
}
@@ -833,7 +739,7 @@ xfs_ag_shrink_space(
833739
struct xfs_trans **tpp,
834740
xfs_extlen_t delta)
835741
{
836-
struct xfs_mount *mp = pag->pag_mount;
742+
struct xfs_mount *mp = pag_mount(pag);
837743
struct xfs_alloc_arg args = {
838744
.tp = *tpp,
839745
.mp = mp,
@@ -850,7 +756,7 @@ xfs_ag_shrink_space(
850756
xfs_agblock_t aglen;
851757
int error, err2;
852758

853-
ASSERT(pag->pag_agno == mp->m_sb.sb_agcount - 1);
759+
ASSERT(pag_agno(pag) == mp->m_sb.sb_agcount - 1);
854760
error = xfs_ialloc_read_agi(pag, *tpp, 0, &agibp);
855761
if (error)
856762
return error;
@@ -947,8 +853,8 @@ xfs_ag_shrink_space(
947853

948854
/* Update perag geometry */
949855
pag->block_count -= delta;
950-
__xfs_agino_range(pag->pag_mount, pag->block_count, &pag->agino_min,
951-
&pag->agino_max);
856+
__xfs_agino_range(mp, pag->block_count, &pag->agino_min,
857+
&pag->agino_max);
952858

953859
xfs_ialloc_log_agi(*tpp, agibp, XFS_AGI_LENGTH);
954860
xfs_alloc_log_agf(*tpp, agfbp, XFS_AGF_LENGTH);
@@ -973,12 +879,13 @@ xfs_ag_extend_space(
973879
struct xfs_trans *tp,
974880
xfs_extlen_t len)
975881
{
882+
struct xfs_mount *mp = pag_mount(pag);
976883
struct xfs_buf *bp;
977884
struct xfs_agi *agi;
978885
struct xfs_agf *agf;
979886
int error;
980887

981-
ASSERT(pag->pag_agno == pag->pag_mount->m_sb.sb_agcount - 1);
888+
ASSERT(pag_agno(pag) == mp->m_sb.sb_agcount - 1);
982889

983890
error = xfs_ialloc_read_agi(pag, tp, 0, &bp);
984891
if (error)
@@ -1018,8 +925,8 @@ xfs_ag_extend_space(
1018925

1019926
/* Update perag geometry */
1020927
pag->block_count = be32_to_cpu(agf->agf_length);
1021-
__xfs_agino_range(pag->pag_mount, pag->block_count, &pag->agino_min,
1022-
&pag->agino_max);
928+
__xfs_agino_range(mp, pag->block_count, &pag->agino_min,
929+
&pag->agino_max);
1023930
return 0;
1024931
}
1025932

@@ -1046,7 +953,7 @@ xfs_ag_get_geometry(
1046953

1047954
/* Fill out form. */
1048955
memset(ageo, 0, sizeof(*ageo));
1049-
ageo->ag_number = pag->pag_agno;
956+
ageo->ag_number = pag_agno(pag);
1050957

1051958
agi = agi_bp->b_addr;
1052959
ageo->ag_icount = be32_to_cpu(agi->agi_count);

0 commit comments

Comments
 (0)