1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#ifndef EXPORT_SYMTAB
35# define EXPORT_SYMTAB
36#endif
37#define DEBUG_SUBSYSTEM S_LNET
38
39#include <linux/libcfs/libcfs.h>
40
41struct cfs_var_array {
42 unsigned int va_count;
43 unsigned int va_size;
44 struct cfs_cpt_table *va_cptab;
45 void *va_ptrs[0];
46};
47
48
49
50
51void
52cfs_percpt_free(void *vars)
53{
54 struct cfs_var_array *arr;
55 int i;
56
57 arr = container_of(vars, struct cfs_var_array, va_ptrs[0]);
58
59 for (i = 0; i < arr->va_count; i++) {
60 if (arr->va_ptrs[i] != NULL)
61 LIBCFS_FREE(arr->va_ptrs[i], arr->va_size);
62 }
63
64 LIBCFS_FREE(arr, offsetof(struct cfs_var_array,
65 va_ptrs[arr->va_count]));
66}
67EXPORT_SYMBOL(cfs_percpt_free);
68
69
70
71
72
73
74
75
76
77
78
79
80void *
81cfs_percpt_alloc(struct cfs_cpt_table *cptab, unsigned int size)
82{
83 struct cfs_var_array *arr;
84 int count;
85 int i;
86
87 count = cfs_cpt_number(cptab);
88
89 LIBCFS_ALLOC(arr, offsetof(struct cfs_var_array, va_ptrs[count]));
90 if (arr == NULL)
91 return NULL;
92
93 arr->va_size = size = L1_CACHE_ALIGN(size);
94 arr->va_count = count;
95 arr->va_cptab = cptab;
96
97 for (i = 0; i < count; i++) {
98 LIBCFS_CPT_ALLOC(arr->va_ptrs[i], cptab, i, size);
99 if (arr->va_ptrs[i] == NULL) {
100 cfs_percpt_free((void *)&arr->va_ptrs[0]);
101 return NULL;
102 }
103 }
104
105 return (void *)&arr->va_ptrs[0];
106}
107EXPORT_SYMBOL(cfs_percpt_alloc);
108
109
110
111
112
113int
114cfs_percpt_number(void *vars)
115{
116 struct cfs_var_array *arr;
117
118 arr = container_of(vars, struct cfs_var_array, va_ptrs[0]);
119
120 return arr->va_count;
121}
122EXPORT_SYMBOL(cfs_percpt_number);
123
124
125
126
127void *
128cfs_percpt_current(void *vars)
129{
130 struct cfs_var_array *arr;
131 int cpt;
132
133 arr = container_of(vars, struct cfs_var_array, va_ptrs[0]);
134 cpt = cfs_cpt_current(arr->va_cptab, 0);
135 if (cpt < 0)
136 return NULL;
137
138 return arr->va_ptrs[cpt];
139}
140EXPORT_SYMBOL(cfs_percpt_current);
141
142void *
143cfs_percpt_index(void *vars, int idx)
144{
145 struct cfs_var_array *arr;
146
147 arr = container_of(vars, struct cfs_var_array, va_ptrs[0]);
148
149 LASSERT(idx >= 0 && idx < arr->va_count);
150 return arr->va_ptrs[idx];
151}
152EXPORT_SYMBOL(cfs_percpt_index);
153
154
155
156
157void
158cfs_array_free(void *vars)
159{
160 struct cfs_var_array *arr;
161 int i;
162
163 arr = container_of(vars, struct cfs_var_array, va_ptrs[0]);
164
165 for (i = 0; i < arr->va_count; i++) {
166 if (arr->va_ptrs[i] == NULL)
167 continue;
168
169 LIBCFS_FREE(arr->va_ptrs[i], arr->va_size);
170 }
171 LIBCFS_FREE(arr, offsetof(struct cfs_var_array,
172 va_ptrs[arr->va_count]));
173}
174EXPORT_SYMBOL(cfs_array_free);
175
176
177
178
179
180
181void *
182cfs_array_alloc(int count, unsigned int size)
183{
184 struct cfs_var_array *arr;
185 int i;
186
187 LIBCFS_ALLOC(arr, offsetof(struct cfs_var_array, va_ptrs[count]));
188 if (arr == NULL)
189 return NULL;
190
191 arr->va_count = count;
192 arr->va_size = size;
193
194 for (i = 0; i < count; i++) {
195 LIBCFS_ALLOC(arr->va_ptrs[i], size);
196
197 if (arr->va_ptrs[i] == NULL) {
198 cfs_array_free((void *)&arr->va_ptrs[0]);
199 return NULL;
200 }
201 }
202
203 return (void *)&arr->va_ptrs[0];
204}
205EXPORT_SYMBOL(cfs_array_alloc);
206