Skip to content

Commit e9c4d8b

Browse files
Christoph HellwigDarrick J. Wong
authored andcommitted
xfs: factor out a generic xfs_group structure
Split the lookup and refcount handling of struct xfs_perag into an embedded xfs_group structure that can be reused for the upcoming realtime groups. It will be extended with more features later. Note that he xg_type field will only need a single bit even with realtime group support. For now it fills a hole, but it might be worth to fold it into another field if we can use this space better. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]>
1 parent 0a4d797 commit e9c4d8b

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

+608
-399
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: 27 additions & 112 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,19 @@ 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+
xfs_defer_drain_free(&pag->pag_intents_drain);
116+
cancel_delayed_work_sync(&pag->pag_blockgc_work);
117+
xfs_buf_cache_destroy(&pag->pag_bcache);
118+
#endif
119+
}
120+
186121
/*
187122
* Free up the per-ag resources within the specified AG range.
188123
*/
@@ -195,22 +130,8 @@ xfs_free_perag_range(
195130
{
196131
xfs_agnumber_t agno;
197132

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-
}
133+
for (agno = first_agno; agno < end_agno; agno++)
134+
xfs_group_free(mp, agno, XG_TYPE_AG, xfs_perag_uninit);
214135
}
215136

216137
/* Find the size of the AG, in blocks. */
@@ -332,16 +253,9 @@ xfs_perag_alloc(
332253
__xfs_agino_range(mp, pag->block_count, &pag->agino_min,
333254
&pag->agino_max);
334255

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);
256+
error = xfs_group_insert(mp, pag_group(pag), index, XG_TYPE_AG);
257+
if (error)
343258
goto out_buf_cache_destroy;
344-
}
345259

346260
return 0;
347261

@@ -833,7 +747,7 @@ xfs_ag_shrink_space(
833747
struct xfs_trans **tpp,
834748
xfs_extlen_t delta)
835749
{
836-
struct xfs_mount *mp = pag->pag_mount;
750+
struct xfs_mount *mp = pag_mount(pag);
837751
struct xfs_alloc_arg args = {
838752
.tp = *tpp,
839753
.mp = mp,
@@ -850,7 +764,7 @@ xfs_ag_shrink_space(
850764
xfs_agblock_t aglen;
851765
int error, err2;
852766

853-
ASSERT(pag->pag_agno == mp->m_sb.sb_agcount - 1);
767+
ASSERT(pag_agno(pag) == mp->m_sb.sb_agcount - 1);
854768
error = xfs_ialloc_read_agi(pag, *tpp, 0, &agibp);
855769
if (error)
856770
return error;
@@ -947,8 +861,8 @@ xfs_ag_shrink_space(
947861

948862
/* Update perag geometry */
949863
pag->block_count -= delta;
950-
__xfs_agino_range(pag->pag_mount, pag->block_count, &pag->agino_min,
951-
&pag->agino_max);
864+
__xfs_agino_range(mp, pag->block_count, &pag->agino_min,
865+
&pag->agino_max);
952866

953867
xfs_ialloc_log_agi(*tpp, agibp, XFS_AGI_LENGTH);
954868
xfs_alloc_log_agf(*tpp, agfbp, XFS_AGF_LENGTH);
@@ -973,12 +887,13 @@ xfs_ag_extend_space(
973887
struct xfs_trans *tp,
974888
xfs_extlen_t len)
975889
{
890+
struct xfs_mount *mp = pag_mount(pag);
976891
struct xfs_buf *bp;
977892
struct xfs_agi *agi;
978893
struct xfs_agf *agf;
979894
int error;
980895

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

983898
error = xfs_ialloc_read_agi(pag, tp, 0, &bp);
984899
if (error)
@@ -1018,8 +933,8 @@ xfs_ag_extend_space(
1018933

1019934
/* Update perag geometry */
1020935
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);
936+
__xfs_agino_range(mp, pag->block_count, &pag->agino_min,
937+
&pag->agino_max);
1023938
return 0;
1024939
}
1025940

@@ -1046,7 +961,7 @@ xfs_ag_get_geometry(
1046961

1047962
/* Fill out form. */
1048963
memset(ageo, 0, sizeof(*ageo));
1049-
ageo->ag_number = pag->pag_agno;
964+
ageo->ag_number = pag_agno(pag);
1050965

1051966
agi = agi_bp->b_addr;
1052967
ageo->ag_icount = be32_to_cpu(agi->agi_count);

fs/xfs/libxfs/xfs_ag.h

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#ifndef __LIBXFS_AG_H
88
#define __LIBXFS_AG_H 1
99

10+
#include "xfs_group.h"
11+
1012
struct xfs_mount;
1113
struct xfs_trans;
1214
struct xfs_perag;
@@ -30,10 +32,7 @@ struct xfs_ag_resv {
3032
* performance of allocation group selection.
3133
*/
3234
struct xfs_perag {
33-
struct xfs_mount *pag_mount; /* owner filesystem */
34-
xfs_agnumber_t pag_agno; /* AG this structure belongs to */
35-
atomic_t pag_ref; /* passive reference count */
36-
atomic_t pag_active_ref; /* active reference count */
35+
struct xfs_group pag_group;
3736
unsigned long pag_opstate;
3837
uint8_t pagf_bno_level; /* # of levels in bno btree */
3938
uint8_t pagf_cnt_level; /* # of levels in cnt btree */
@@ -121,6 +120,26 @@ struct xfs_perag {
121120
#endif /* __KERNEL__ */
122121
};
123122

123+
static inline struct xfs_perag *to_perag(struct xfs_group *xg)
124+
{
125+
return container_of(xg, struct xfs_perag, pag_group);
126+
}
127+
128+
static inline struct xfs_group *pag_group(struct xfs_perag *pag)
129+
{
130+
return &pag->pag_group;
131+
}
132+
133+
static inline struct xfs_mount *pag_mount(const struct xfs_perag *pag)
134+
{
135+
return pag->pag_group.xg_mount;
136+
}
137+
138+
static inline xfs_agnumber_t pag_agno(const struct xfs_perag *pag)
139+
{
140+
return pag->pag_group.xg_gno;
141+
}
142+
124143
/*
125144
* Per-AG operational state. These are atomic flag bits.
126145
*/
@@ -151,13 +170,43 @@ int xfs_initialize_perag_data(struct xfs_mount *mp, xfs_agnumber_t agno);
151170
int xfs_update_last_ag_size(struct xfs_mount *mp, xfs_agnumber_t prev_agcount);
152171

153172
/* Passive AG references */
154-
struct xfs_perag *xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno);
155-
struct xfs_perag *xfs_perag_hold(struct xfs_perag *pag);
156-
void xfs_perag_put(struct xfs_perag *pag);
173+
static inline struct xfs_perag *
174+
xfs_perag_get(
175+
struct xfs_mount *mp,
176+
xfs_agnumber_t agno)
177+
{
178+
return to_perag(xfs_group_get(mp, agno, XG_TYPE_AG));
179+
}
180+
181+
static inline struct xfs_perag *
182+
xfs_perag_hold(
183+
struct xfs_perag *pag)
184+
{
185+
return to_perag(xfs_group_hold(pag_group(pag)));
186+
}
187+
188+
static inline void
189+
xfs_perag_put(
190+
struct xfs_perag *pag)
191+
{
192+
xfs_group_put(pag_group(pag));
193+
}
157194

158195
/* Active AG references */
159-
struct xfs_perag *xfs_perag_grab(struct xfs_mount *, xfs_agnumber_t);
160-
void xfs_perag_rele(struct xfs_perag *pag);
196+
static inline struct xfs_perag *
197+
xfs_perag_grab(
198+
struct xfs_mount *mp,
199+
xfs_agnumber_t agno)
200+
{
201+
return to_perag(xfs_group_grab(mp, agno, XG_TYPE_AG));
202+
}
203+
204+
static inline void
205+
xfs_perag_rele(
206+
struct xfs_perag *pag)
207+
{
208+
xfs_group_rele(pag_group(pag));
209+
}
161210

162211
/*
163212
* Per-ag geometry infomation and validation
@@ -233,9 +282,9 @@ xfs_perag_next(
233282
xfs_agnumber_t *agno,
234283
xfs_agnumber_t end_agno)
235284
{
236-
struct xfs_mount *mp = pag->pag_mount;
285+
struct xfs_mount *mp = pag_mount(pag);
237286

238-
*agno = pag->pag_agno + 1;
287+
*agno = pag_agno(pag) + 1;
239288
xfs_perag_rele(pag);
240289
while (*agno <= end_agno) {
241290
pag = xfs_perag_grab(mp, *agno);
@@ -266,9 +315,9 @@ xfs_perag_next_wrap(
266315
xfs_agnumber_t restart_agno,
267316
xfs_agnumber_t wrap_agno)
268317
{
269-
struct xfs_mount *mp = pag->pag_mount;
318+
struct xfs_mount *mp = pag_mount(pag);
270319

271-
*agno = pag->pag_agno + 1;
320+
*agno = pag_agno(pag) + 1;
272321
xfs_perag_rele(pag);
273322
while (*agno != stop_agno) {
274323
if (*agno >= wrap_agno) {
@@ -335,23 +384,23 @@ xfs_agbno_to_fsb(
335384
struct xfs_perag *pag,
336385
xfs_agblock_t agbno)
337386
{
338-
return XFS_AGB_TO_FSB(pag->pag_mount, pag->pag_agno, agbno);
387+
return XFS_AGB_TO_FSB(pag_mount(pag), pag_agno(pag), agbno);
339388
}
340389

341390
static inline xfs_daddr_t
342391
xfs_agbno_to_daddr(
343392
struct xfs_perag *pag,
344393
xfs_agblock_t agbno)
345394
{
346-
return XFS_AGB_TO_DADDR(pag->pag_mount, pag->pag_agno, agbno);
395+
return XFS_AGB_TO_DADDR(pag_mount(pag), pag_agno(pag), agbno);
347396
}
348397

349398
static inline xfs_ino_t
350399
xfs_agino_to_ino(
351400
struct xfs_perag *pag,
352401
xfs_agino_t agino)
353402
{
354-
return XFS_AGINO_TO_INO(pag->pag_mount, pag->pag_agno, agino);
403+
return XFS_AGINO_TO_INO(pag_mount(pag), pag_agno(pag), agino);
355404
}
356405

357406
#endif /* __LIBXFS_AG_H */

0 commit comments

Comments
 (0)