Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

authored by

Alexei Starovoitov and committed by
Daniel Borkmann
005142b8 6e9cab2e

+29 -18
+1
include/linux/bpf.h
··· 1358 1358 struct btf *btf, const struct btf_type *t); 1359 1359 1360 1360 struct bpf_prog *bpf_prog_by_id(u32 id); 1361 + struct bpf_link *bpf_link_by_id(u32 id); 1361 1362 1362 1363 const struct bpf_func_proto *bpf_base_func_proto(enum bpf_func_id func_id); 1363 1364 #else /* !CONFIG_BPF_SYSCALL */
+28 -18
kernel/bpf/syscall.c
··· 4014 4014 return ret; 4015 4015 } 4016 4016 4017 - static int bpf_link_inc_not_zero(struct bpf_link *link) 4017 + static struct bpf_link *bpf_link_inc_not_zero(struct bpf_link *link) 4018 4018 { 4019 - return atomic64_fetch_add_unless(&link->refcnt, 1, 0) ? 0 : -ENOENT; 4019 + return atomic64_fetch_add_unless(&link->refcnt, 1, 0) ? link : ERR_PTR(-ENOENT); 4020 + } 4021 + 4022 + struct bpf_link *bpf_link_by_id(u32 id) 4023 + { 4024 + struct bpf_link *link; 4025 + 4026 + if (!id) 4027 + return ERR_PTR(-ENOENT); 4028 + 4029 + spin_lock_bh(&link_idr_lock); 4030 + /* before link is "settled", ID is 0, pretend it doesn't exist yet */ 4031 + link = idr_find(&link_idr, id); 4032 + if (link) { 4033 + if (link->id) 4034 + link = bpf_link_inc_not_zero(link); 4035 + else 4036 + link = ERR_PTR(-EAGAIN); 4037 + } else { 4038 + link = ERR_PTR(-ENOENT); 4039 + } 4040 + spin_unlock_bh(&link_idr_lock); 4041 + return link; 4020 4042 } 4021 4043 4022 4044 #define BPF_LINK_GET_FD_BY_ID_LAST_FIELD link_id ··· 4047 4025 { 4048 4026 struct bpf_link *link; 4049 4027 u32 id = attr->link_id; 4050 - int fd, err; 4028 + int fd; 4051 4029 4052 4030 if (CHECK_ATTR(BPF_LINK_GET_FD_BY_ID)) 4053 4031 return -EINVAL; ··· 4055 4033 if (!capable(CAP_SYS_ADMIN)) 4056 4034 return -EPERM; 4057 4035 4058 - spin_lock_bh(&link_idr_lock); 4059 - link = idr_find(&link_idr, id); 4060 - /* before link is "settled", ID is 0, pretend it doesn't exist yet */ 4061 - if (link) { 4062 - if (link->id) 4063 - err = bpf_link_inc_not_zero(link); 4064 - else 4065 - err = -EAGAIN; 4066 - } else { 4067 - err = -ENOENT; 4068 - } 4069 - spin_unlock_bh(&link_idr_lock); 4070 - 4071 - if (err) 4072 - return err; 4036 + link = bpf_link_by_id(id); 4037 + if (IS_ERR(link)) 4038 + return PTR_ERR(link); 4073 4039 4074 4040 fd = bpf_link_new_fd(link); 4075 4041 if (fd < 0)