> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index 1e8688975d16..a1b54da1ded2 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
[ ... ]
> @@ -13683,11 +13683,18 @@ static int bpf_link__detach_struct_ops(struct
> bpf_link *link)
> return close(link->fd);
> }
>
> -struct bpf_link *bpf_map__attach_struct_ops(const struct bpf_map *map)
> +struct bpf_link *bpf_map__attach_struct_ops_opts(const struct bpf_map *map,
> + const struct
> bpf_struct_ops_opts *opts)
> {
> + DECLARE_LIBBPF_OPTS(bpf_link_create_opts, link_opts);
> struct bpf_link_struct_ops *link;
> + int err, fd, target_fd;
> __u32 zero = 0;
> - int err, fd;
> +
> + if (!OPTS_VALID(opts, bpf_struct_ops_opts)) {
> + pr_warn("map '%s': invalid opts\n", map->name);
> + return libbpf_err_ptr(-EINVAL);
> + }
>
> if (!bpf_map__is_struct_ops(map)) {
> pr_warn("map '%s': can't attach non-struct_ops map\n",
> map->name);
[ ... ]
> @@ -13724,7 +13731,9 @@ struct bpf_link *bpf_map__attach_struct_ops(const
> struct bpf_map *map)
> return &link->link;
> }
>
> - fd = bpf_link_create(map->fd, 0, BPF_STRUCT_OPS, NULL);
> + link_opts.flags = OPTS_GET(opts, flags, 0);
> + target_fd = OPTS_GET(opts, target_fd, 0);
> + fd = bpf_link_create(map->fd, target_fd, BPF_STRUCT_OPS, &link_opts);
The expected_revision field declared in struct bpf_struct_ops_opts is never
read or used. The code only reads flags and target_fd from opts, which could
cause silent data loss if users set expected_revision expecting it to be
honored.
Looking at similar opts structures (bpf_cgroup_opts, bpf_tcx_opts,
bpf_netkit_opts), they all pass expected_revision to bpf_link_create_opts.
Should expected_revision be propagated here as well?
This was raised by [email protected] in v3:
https://lore.kernel.org/bpf/3af5210f45be4a508e584263a5517781ca762d28d4f6b831b987795662715...@mail.kernel.org/
> if (fd < 0) {
> free(link);
> return libbpf_err_ptr(fd);
[ ... ]
> diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
> index bba4e8464396..18af178547ad 100644
> --- a/tools/lib/bpf/libbpf.h
> +++ b/tools/lib/bpf/libbpf.h
> @@ -945,6 +945,20 @@ bpf_program__attach_cgroup_opts(const struct bpf_program
> *prog, int cgroup_fd,
> struct bpf_map;
>
> LIBBPF_API struct bpf_link *bpf_map__attach_struct_ops(const struct bpf_map
> *map);
> +
> +struct bpf_struct_ops_opts {
> + /* size of this struct, for forward/backward compatibility */
> + size_t sz;
> + __u32 flags;
> + __u32 target_fd;
> + __u64 expected_revision;
> + size_t :0;
> +};
> +#define bpf_struct_ops_opts__last_field expected_revision
> +
> +LIBBPF_API struct bpf_link *
> +bpf_map__attach_struct_ops_opts(const struct bpf_map *map,
> + const struct bpf_struct_ops_opts *opts);
> LIBBPF_API int bpf_link__update_map(struct bpf_link *link, const struct
> bpf_map *map);
>
> struct bpf_iter_attach_opts {
[ ... ]
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/26429228214