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,19 @@ 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
+ 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
+
186
121
/*
187
122
* Free up the per-ag resources within the specified AG range.
188
123
*/
@@ -195,22 +130,8 @@ xfs_free_perag_range(
195
130
{
196
131
xfs_agnumber_t agno ;
197
132
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 );
214
135
}
215
136
216
137
/* Find the size of the AG, in blocks. */
@@ -332,16 +253,9 @@ xfs_perag_alloc(
332
253
__xfs_agino_range (mp , pag -> block_count , & pag -> agino_min ,
333
254
& pag -> agino_max );
334
255
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 )
343
258
goto out_buf_cache_destroy ;
344
- }
345
259
346
260
return 0 ;
347
261
@@ -833,7 +747,7 @@ xfs_ag_shrink_space(
833
747
struct xfs_trans * * tpp ,
834
748
xfs_extlen_t delta )
835
749
{
836
- struct xfs_mount * mp = pag -> pag_mount ;
750
+ struct xfs_mount * mp = pag_mount ( pag ) ;
837
751
struct xfs_alloc_arg args = {
838
752
.tp = * tpp ,
839
753
.mp = mp ,
@@ -850,7 +764,7 @@ xfs_ag_shrink_space(
850
764
xfs_agblock_t aglen ;
851
765
int error , err2 ;
852
766
853
- ASSERT (pag -> pag_agno == mp -> m_sb .sb_agcount - 1 );
767
+ ASSERT (pag_agno ( pag ) == mp -> m_sb .sb_agcount - 1 );
854
768
error = xfs_ialloc_read_agi (pag , * tpp , 0 , & agibp );
855
769
if (error )
856
770
return error ;
@@ -947,8 +861,8 @@ xfs_ag_shrink_space(
947
861
948
862
/* Update perag geometry */
949
863
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 );
952
866
953
867
xfs_ialloc_log_agi (* tpp , agibp , XFS_AGI_LENGTH );
954
868
xfs_alloc_log_agf (* tpp , agfbp , XFS_AGF_LENGTH );
@@ -973,12 +887,13 @@ xfs_ag_extend_space(
973
887
struct xfs_trans * tp ,
974
888
xfs_extlen_t len )
975
889
{
890
+ struct xfs_mount * mp = pag_mount (pag );
976
891
struct xfs_buf * bp ;
977
892
struct xfs_agi * agi ;
978
893
struct xfs_agf * agf ;
979
894
int error ;
980
895
981
- ASSERT (pag -> pag_agno == pag -> pag_mount -> m_sb .sb_agcount - 1 );
896
+ ASSERT (pag_agno ( pag ) == mp -> m_sb .sb_agcount - 1 );
982
897
983
898
error = xfs_ialloc_read_agi (pag , tp , 0 , & bp );
984
899
if (error )
@@ -1018,8 +933,8 @@ xfs_ag_extend_space(
1018
933
1019
934
/* Update perag geometry */
1020
935
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 );
1023
938
return 0 ;
1024
939
}
1025
940
@@ -1046,7 +961,7 @@ xfs_ag_get_geometry(
1046
961
1047
962
/* Fill out form. */
1048
963
memset (ageo , 0 , sizeof (* ageo ));
1049
- ageo -> ag_number = pag -> pag_agno ;
964
+ ageo -> ag_number = pag_agno ( pag ) ;
1050
965
1051
966
agi = agi_bp -> b_addr ;
1052
967
ageo -> ag_icount = be32_to_cpu (agi -> agi_count );
0 commit comments