@@ -150,15 +150,15 @@ static int __init register_array_map(void)
150150}
151151late_initcall (register_array_map );
152152
153- static struct bpf_map * prog_array_map_alloc (union bpf_attr * attr )
153+ static struct bpf_map * fd_array_map_alloc (union bpf_attr * attr )
154154{
155- /* only bpf_prog file descriptors can be stored in prog_array map */
155+ /* only file descriptors can be stored in this type of map */
156156 if (attr -> value_size != sizeof (u32 ))
157157 return ERR_PTR (- EINVAL );
158158 return array_map_alloc (attr );
159159}
160160
161- static void prog_array_map_free (struct bpf_map * map )
161+ static void fd_array_map_free (struct bpf_map * map )
162162{
163163 struct bpf_array * array = container_of (map , struct bpf_array , map );
164164 int i ;
@@ -167,21 +167,21 @@ static void prog_array_map_free(struct bpf_map *map)
167167
168168 /* make sure it's empty */
169169 for (i = 0 ; i < array -> map .max_entries ; i ++ )
170- BUG_ON (array -> prog [i ] != NULL );
170+ BUG_ON (array -> ptrs [i ] != NULL );
171171 kvfree (array );
172172}
173173
174- static void * prog_array_map_lookup_elem (struct bpf_map * map , void * key )
174+ static void * fd_array_map_lookup_elem (struct bpf_map * map , void * key )
175175{
176176 return NULL ;
177177}
178178
179179/* only called from syscall */
180- static int prog_array_map_update_elem (struct bpf_map * map , void * key ,
181- void * value , u64 map_flags )
180+ static int fd_array_map_update_elem (struct bpf_map * map , void * key ,
181+ void * value , u64 map_flags )
182182{
183183 struct bpf_array * array = container_of (map , struct bpf_array , map );
184- struct bpf_prog * prog , * old_prog ;
184+ void * new_ptr , * old_ptr ;
185185 u32 index = * (u32 * )key , ufd ;
186186
187187 if (map_flags != BPF_ANY )
@@ -191,57 +191,75 @@ static int prog_array_map_update_elem(struct bpf_map *map, void *key,
191191 return - E2BIG ;
192192
193193 ufd = * (u32 * )value ;
194- prog = bpf_prog_get (ufd );
195- if (IS_ERR (prog ))
196- return PTR_ERR (prog );
197-
198- if (!bpf_prog_array_compatible (array , prog )) {
199- bpf_prog_put (prog );
200- return - EINVAL ;
201- }
194+ new_ptr = map -> ops -> map_fd_get_ptr (map , ufd );
195+ if (IS_ERR (new_ptr ))
196+ return PTR_ERR (new_ptr );
202197
203- old_prog = xchg (array -> prog + index , prog );
204- if (old_prog )
205- bpf_prog_put_rcu ( old_prog );
198+ old_ptr = xchg (array -> ptrs + index , new_ptr );
199+ if (old_ptr )
200+ map -> ops -> map_fd_put_ptr ( old_ptr );
206201
207202 return 0 ;
208203}
209204
210- static int prog_array_map_delete_elem (struct bpf_map * map , void * key )
205+ static int fd_array_map_delete_elem (struct bpf_map * map , void * key )
211206{
212207 struct bpf_array * array = container_of (map , struct bpf_array , map );
213- struct bpf_prog * old_prog ;
208+ void * old_ptr ;
214209 u32 index = * (u32 * )key ;
215210
216211 if (index >= array -> map .max_entries )
217212 return - E2BIG ;
218213
219- old_prog = xchg (array -> prog + index , NULL );
220- if (old_prog ) {
221- bpf_prog_put_rcu ( old_prog );
214+ old_ptr = xchg (array -> ptrs + index , NULL );
215+ if (old_ptr ) {
216+ map -> ops -> map_fd_put_ptr ( old_ptr );
222217 return 0 ;
223218 } else {
224219 return - ENOENT ;
225220 }
226221}
227222
223+ static void * prog_fd_array_get_ptr (struct bpf_map * map , int fd )
224+ {
225+ struct bpf_array * array = container_of (map , struct bpf_array , map );
226+ struct bpf_prog * prog = bpf_prog_get (fd );
227+ if (IS_ERR (prog ))
228+ return prog ;
229+
230+ if (!bpf_prog_array_compatible (array , prog )) {
231+ bpf_prog_put (prog );
232+ return ERR_PTR (- EINVAL );
233+ }
234+ return prog ;
235+ }
236+
237+ static void prog_fd_array_put_ptr (void * ptr )
238+ {
239+ struct bpf_prog * prog = ptr ;
240+
241+ bpf_prog_put_rcu (prog );
242+ }
243+
228244/* decrement refcnt of all bpf_progs that are stored in this map */
229- void bpf_prog_array_map_clear (struct bpf_map * map )
245+ void bpf_fd_array_map_clear (struct bpf_map * map )
230246{
231247 struct bpf_array * array = container_of (map , struct bpf_array , map );
232248 int i ;
233249
234250 for (i = 0 ; i < array -> map .max_entries ; i ++ )
235- prog_array_map_delete_elem (map , & i );
251+ fd_array_map_delete_elem (map , & i );
236252}
237253
238254static const struct bpf_map_ops prog_array_ops = {
239- .map_alloc = prog_array_map_alloc ,
240- .map_free = prog_array_map_free ,
255+ .map_alloc = fd_array_map_alloc ,
256+ .map_free = fd_array_map_free ,
241257 .map_get_next_key = array_map_get_next_key ,
242- .map_lookup_elem = prog_array_map_lookup_elem ,
243- .map_update_elem = prog_array_map_update_elem ,
244- .map_delete_elem = prog_array_map_delete_elem ,
258+ .map_lookup_elem = fd_array_map_lookup_elem ,
259+ .map_update_elem = fd_array_map_update_elem ,
260+ .map_delete_elem = fd_array_map_delete_elem ,
261+ .map_fd_get_ptr = prog_fd_array_get_ptr ,
262+ .map_fd_put_ptr = prog_fd_array_put_ptr ,
245263};
246264
247265static struct bpf_map_type_list prog_array_type __read_mostly = {
0 commit comments