/* only called from syscall */ static int prog_array_map_update_elem(struct bpf_map *map, void *key, void *value, u64 map_flags) { struct bpf_array *array = container_of(map, struct bpf_array, map); struct bpf_prog *prog, *old_prog; u32 index = *(u32 *)key, ufd; if (map_flags != BPF_ANY) return -EINVAL; if (index >= array->map.max_entries) return -E2BIG; ufd = *(u32 *)value; prog = bpf_prog_get(ufd); if (IS_ERR(prog)) return PTR_ERR(prog); if (!bpf_prog_array_compatible(array, prog)) { bpf_prog_put(prog); return -EINVAL; } old_prog = xchg(array->prog + index, prog); if (old_prog) bpf_prog_put_rcu(old_prog); return 0; }
static int prog_array_map_delete_elem(struct bpf_map *map, void *key) { struct bpf_array *array = container_of(map, struct bpf_array, map); struct bpf_prog *old_prog; u32 index = *(u32 *)key; if (index >= array->map.max_entries) return -E2BIG; old_prog = xchg(array->prog + index, NULL); if (old_prog) { bpf_prog_put_rcu(old_prog); return 0; } else { return -ENOENT; } }
static void prog_fd_array_put_ptr(void *ptr) { struct bpf_prog *prog = ptr; bpf_prog_put_rcu(prog); }