mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 20:51:44 +00:00
bpf: Factor out bpf_link_by_id() helper.
Refactor the code a bit to extract bpf_link_by_id() helper. It's similar to existing bpf_prog_by_id(). Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Andrii Nakryiko <andriin@fb.com> Acked-by: Song Liu <songliubraving@fb.com> Link: https://lore.kernel.org/bpf/20200819042759.51280-2-alexei.starovoitov@gmail.com
This commit is contained in:
parent
6e9cab2e3f
commit
005142b8a1
@ -1358,6 +1358,7 @@ int btf_check_type_match(struct bpf_verifier_env *env, struct bpf_prog *prog,
|
||||
struct btf *btf, const struct btf_type *t);
|
||||
|
||||
struct bpf_prog *bpf_prog_by_id(u32 id);
|
||||
struct bpf_link *bpf_link_by_id(u32 id);
|
||||
|
||||
const struct bpf_func_proto *bpf_base_func_proto(enum bpf_func_id func_id);
|
||||
#else /* !CONFIG_BPF_SYSCALL */
|
||||
|
@ -4014,9 +4014,31 @@ static int link_detach(union bpf_attr *attr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bpf_link_inc_not_zero(struct bpf_link *link)
|
||||
static struct bpf_link *bpf_link_inc_not_zero(struct bpf_link *link)
|
||||
{
|
||||
return atomic64_fetch_add_unless(&link->refcnt, 1, 0) ? 0 : -ENOENT;
|
||||
return atomic64_fetch_add_unless(&link->refcnt, 1, 0) ? link : ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
struct bpf_link *bpf_link_by_id(u32 id)
|
||||
{
|
||||
struct bpf_link *link;
|
||||
|
||||
if (!id)
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
||||
spin_lock_bh(&link_idr_lock);
|
||||
/* before link is "settled", ID is 0, pretend it doesn't exist yet */
|
||||
link = idr_find(&link_idr, id);
|
||||
if (link) {
|
||||
if (link->id)
|
||||
link = bpf_link_inc_not_zero(link);
|
||||
else
|
||||
link = ERR_PTR(-EAGAIN);
|
||||
} else {
|
||||
link = ERR_PTR(-ENOENT);
|
||||
}
|
||||
spin_unlock_bh(&link_idr_lock);
|
||||
return link;
|
||||
}
|
||||
|
||||
#define BPF_LINK_GET_FD_BY_ID_LAST_FIELD link_id
|
||||
@ -4025,7 +4047,7 @@ static int bpf_link_get_fd_by_id(const union bpf_attr *attr)
|
||||
{
|
||||
struct bpf_link *link;
|
||||
u32 id = attr->link_id;
|
||||
int fd, err;
|
||||
int fd;
|
||||
|
||||
if (CHECK_ATTR(BPF_LINK_GET_FD_BY_ID))
|
||||
return -EINVAL;
|
||||
@ -4033,21 +4055,9 @@ static int bpf_link_get_fd_by_id(const union bpf_attr *attr)
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
spin_lock_bh(&link_idr_lock);
|
||||
link = idr_find(&link_idr, id);
|
||||
/* before link is "settled", ID is 0, pretend it doesn't exist yet */
|
||||
if (link) {
|
||||
if (link->id)
|
||||
err = bpf_link_inc_not_zero(link);
|
||||
else
|
||||
err = -EAGAIN;
|
||||
} else {
|
||||
err = -ENOENT;
|
||||
}
|
||||
spin_unlock_bh(&link_idr_lock);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
link = bpf_link_by_id(id);
|
||||
if (IS_ERR(link))
|
||||
return PTR_ERR(link);
|
||||
|
||||
fd = bpf_link_new_fd(link);
|
||||
if (fd < 0)
|
||||
|
Loading…
Reference in New Issue
Block a user