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
348255out_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