30
30
#include "xfs_trace.h"
31
31
#include "xfs_inode.h"
32
32
#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"
112
34
113
35
/*
114
36
* xfs_initialize_perag_data
@@ -183,6 +105,18 @@ xfs_initialize_perag_data(
183
105
return error ;
184
106
}
185
107
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
+
186
120
/*
187
121
* Free up the per-ag resources within the specified AG range.
188
122
*/
@@ -195,22 +129,8 @@ xfs_free_perag_range(
195
129
{
196
130
xfs_agnumber_t agno ;
197
131
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 );
214
134
}
215
135
216
136
/* Find the size of the AG, in blocks. */
@@ -310,19 +230,13 @@ xfs_perag_alloc(
310
230
#ifdef __KERNEL__
311
231
/* Place kernel structure only init below this point. */
312
232
spin_lock_init (& pag -> pag_ici_lock );
313
- spin_lock_init (& pag -> pagb_lock );
314
- spin_lock_init (& pag -> pag_state_lock );
315
233
INIT_DELAYED_WORK (& pag -> pag_blockgc_work , xfs_blockgc_worker );
316
234
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 );
321
235
#endif /* __KERNEL__ */
322
236
323
237
error = xfs_buf_cache_init (& pag -> pag_bcache );
324
238
if (error )
325
- goto out_defer_drain_free ;
239
+ goto out_free_perag ;
326
240
327
241
/*
328
242
* Pre-calculated geometry
@@ -332,23 +246,15 @@ xfs_perag_alloc(
332
246
__xfs_agino_range (mp , pag -> block_count , & pag -> agino_min ,
333
247
& pag -> agino_max );
334
248
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 )
343
251
goto out_buf_cache_destroy ;
344
- }
345
252
346
253
return 0 ;
347
254
348
255
out_buf_cache_destroy :
349
256
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 :
352
258
kfree (pag );
353
259
return error ;
354
260
}
@@ -833,7 +739,7 @@ xfs_ag_shrink_space(
833
739
struct xfs_trans * * tpp ,
834
740
xfs_extlen_t delta )
835
741
{
836
- struct xfs_mount * mp = pag -> pag_mount ;
742
+ struct xfs_mount * mp = pag_mount ( pag ) ;
837
743
struct xfs_alloc_arg args = {
838
744
.tp = * tpp ,
839
745
.mp = mp ,
@@ -850,7 +756,7 @@ xfs_ag_shrink_space(
850
756
xfs_agblock_t aglen ;
851
757
int error , err2 ;
852
758
853
- ASSERT (pag -> pag_agno == mp -> m_sb .sb_agcount - 1 );
759
+ ASSERT (pag_agno ( pag ) == mp -> m_sb .sb_agcount - 1 );
854
760
error = xfs_ialloc_read_agi (pag , * tpp , 0 , & agibp );
855
761
if (error )
856
762
return error ;
@@ -947,8 +853,8 @@ xfs_ag_shrink_space(
947
853
948
854
/* Update perag geometry */
949
855
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 );
952
858
953
859
xfs_ialloc_log_agi (* tpp , agibp , XFS_AGI_LENGTH );
954
860
xfs_alloc_log_agf (* tpp , agfbp , XFS_AGF_LENGTH );
@@ -973,12 +879,13 @@ xfs_ag_extend_space(
973
879
struct xfs_trans * tp ,
974
880
xfs_extlen_t len )
975
881
{
882
+ struct xfs_mount * mp = pag_mount (pag );
976
883
struct xfs_buf * bp ;
977
884
struct xfs_agi * agi ;
978
885
struct xfs_agf * agf ;
979
886
int error ;
980
887
981
- ASSERT (pag -> pag_agno == pag -> pag_mount -> m_sb .sb_agcount - 1 );
888
+ ASSERT (pag_agno ( pag ) == mp -> m_sb .sb_agcount - 1 );
982
889
983
890
error = xfs_ialloc_read_agi (pag , tp , 0 , & bp );
984
891
if (error )
@@ -1018,8 +925,8 @@ xfs_ag_extend_space(
1018
925
1019
926
/* Update perag geometry */
1020
927
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 );
1023
930
return 0 ;
1024
931
}
1025
932
@@ -1046,7 +953,7 @@ xfs_ag_get_geometry(
1046
953
1047
954
/* Fill out form. */
1048
955
memset (ageo , 0 , sizeof (* ageo ));
1049
- ageo -> ag_number = pag -> pag_agno ;
956
+ ageo -> ag_number = pag_agno ( pag ) ;
1050
957
1051
958
agi = agi_bp -> b_addr ;
1052
959
ageo -> ag_icount = be32_to_cpu (agi -> agi_count );
0 commit comments