From: Bob Liu <bob.liu@oracle.com>
To: Leah Rumancik <leah.rumancik@gmail.com>,
bpf@vger.kernel.org, linux-block@vger.kernel.org
Cc: orbekk@google.com, harshads@google.com, jasiu@google.com,
saranyamohan@google.com, tytso@google.com, bvanassche@google.com,
"Martin K. Petersen" <martin.petersen@oracle.com>
Subject: Re: [RFC PATCH 1/4] bpf: add new prog_type BPF_PROG_TYPE_IO_FILTER
Date: Mon, 17 Aug 2020 22:18:47 +0800 [thread overview]
Message-ID: <a0a97488-58c7-1f00-c987-d75e1329159c@oracle.com> (raw)
In-Reply-To: <20200812163305.545447-2-leah.rumancik@gmail.com>
On 8/13/20 12:33 AM, Leah Rumancik wrote:
> Introducing a new program type BPF_PROG_TYPE_IO_FILTER and a new
> attach type BPF_BIO_SUBMIT.
>
Nice work!
> This program type is intended to help filter and monitor IO requests.
>
I was also working on similar tasks.
> Co-developed-by: Saranya Muruganandam <saranyamohan@google.com>
> Signed-off-by: Saranya Muruganandam <saranyamohan@google.com>
> Signed-off-by: Kjetil Ørbekk <orbekk@google.com>
> Signed-off-by: Harshad Shirwadkar <harshads@google.com>
> Signed-off-by: Leah Rumancik <leah.rumancik@gmail.com>
> ---
> block/Makefile | 1 +
> block/blk-bpf-io-filter.c | 209 ++++++++++++++++++
> block/blk-bpf-io-filter.h | 16 ++
> block/blk-core.c | 6 +
> block/genhd.c | 3 +
> include/linux/bpf_io_filter.h | 23 ++
> include/linux/bpf_types.h | 4 +
> include/linux/genhd.h | 4 +
> include/uapi/linux/bpf.h | 11 +
> init/Kconfig | 8 +
> kernel/bpf/syscall.c | 9 +
> kernel/bpf/verifier.c | 1 +
> tools/bpf/bpftool/feature.c | 2 +
> tools/bpf/bpftool/main.h | 2 +
> tools/include/uapi/linux/bpf.h | 11 +
> tools/lib/bpf/libbpf.c | 2 +
> tools/lib/bpf/libbpf_probes.c | 1 +
> .../selftests/bpf/prog_tests/section_names.c | 5 +
> 18 files changed, 318 insertions(+)
> create mode 100644 block/blk-bpf-io-filter.c
> create mode 100644 block/blk-bpf-io-filter.h
> create mode 100644 include/linux/bpf_io_filter.h
>
It would be better to review if this changes can be separated to small patches.
> diff --git a/block/Makefile b/block/Makefile
> index 78719169fb2a..358ace8002cd 100644
> --- a/block/Makefile
> +++ b/block/Makefile
> @@ -38,3 +38,4 @@ obj-$(CONFIG_BLK_SED_OPAL) += sed-opal.o
> obj-$(CONFIG_BLK_PM) += blk-pm.o
> obj-$(CONFIG_BLK_INLINE_ENCRYPTION) += keyslot-manager.o blk-crypto.o
> obj-$(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) += blk-crypto-fallback.o
> +obj-$(CONFIG_BPF_IO_FILTER) += blk-bpf-io-filter.o
> diff --git a/block/blk-bpf-io-filter.c b/block/blk-bpf-io-filter.c
> new file mode 100644
> index 000000000000..453d6b156bd2
> --- /dev/null
> +++ b/block/blk-bpf-io-filter.c
> @@ -0,0 +1,209 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/bpf_io_filter.h>
> +
> +#include <linux/bpf.h>
> +#include <linux/bpf_trace.h>
> +#include <linux/filter.h>
> +#include <linux/kallsyms.h>
> +#include <linux/bpf_verifier.h>
> +#include <linux/kobject.h>
> +#include <linux/sysfs.h>
> +#include <linux/genhd.h>
> +#include <uapi/linux/bpf.h>
> +#include <linux/bio.h>
> +
> +#include "blk-bpf-io-filter.h"
> +
> +#define io_filter_rcu_dereference_progs(disk) \
> + rcu_dereference_protected(disk->progs, lockdep_is_held(&disk->io_filter_lock))
> +
> +static const struct bpf_func_proto *
> +io_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
> +{
> + switch (func_id) {
> + case BPF_FUNC_map_lookup_elem:
> + return &bpf_map_lookup_elem_proto;
> + case BPF_FUNC_map_update_elem:
> + return &bpf_map_update_elem_proto;
> + case BPF_FUNC_map_delete_elem:
> + return &bpf_map_delete_elem_proto;
> + case BPF_FUNC_map_push_elem:
> + return &bpf_map_push_elem_proto;
> + case BPF_FUNC_map_pop_elem:
> + return &bpf_map_pop_elem_proto;
> + case BPF_FUNC_map_peek_elem:
> + return &bpf_map_peek_elem_proto;
> + case BPF_FUNC_trace_printk:
> + if (capable(CAP_SYS_ADMIN))
> + return bpf_get_trace_printk_proto();
> + fallthrough;
> + default:
> + return NULL;
> + }
> +}
> +
> +const struct bpf_prog_ops io_filter_prog_ops = {
> +};
> +
> +static bool io_filter_is_valid_access(int off, int size,
> + enum bpf_access_type type,
> + const struct bpf_prog *prog,
> + struct bpf_insn_access_aux *info)
> +{
> + const __u32 size_default = sizeof(__u32);
> +
> + if (type != BPF_READ)
> + return false;
> +
> + if (off < 0 || off >= offsetofend(struct bpf_io_request, opf))
> + return false;
> +
> + if (off % size != 0)
> + return false;
> +
> + switch (off) {
> + case offsetof(struct bpf_io_request, sector_start):
> + return size == sizeof(__u64);
> + case offsetof(struct bpf_io_request, sector_cnt):
> + return size == sizeof(__u32);
> + case bpf_ctx_range(struct bpf_io_request, opf):
> + bpf_ctx_record_field_size(info, size_default);
> + return bpf_ctx_narrow_access_ok(off, size, size_default);
> + default:
> + return false;
> + }
> +}
> +
> +const struct bpf_verifier_ops io_filter_verifier_ops = {
> + .get_func_proto = io_filter_func_proto,
> + .is_valid_access = io_filter_is_valid_access,
> +};
> +
> +#define BPF_MAX_PROGS 64
> +
> +int io_filter_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog)
> +{
> + struct gendisk *disk;
> + struct fd f;
> + struct bpf_prog_array *old_array;
> + struct bpf_prog_array *new_array;
> + int ret;
> +
> + if (attr->attach_flags)
> + return -EINVAL;
> +
> + f = fdget(attr->target_fd);
> + if (!f.file)
> + return -EBADF;
> +
> + disk = I_BDEV(f.file->f_mapping->host)->bd_disk;
> + if (disk == NULL)
> + return -ENXIO;
> +
> + ret = mutex_lock_interruptible(&disk->io_filter_lock);
> + if (ret)
> + return ret;
> +
> + old_array = io_filter_rcu_dereference_progs(disk);
> + if (old_array && bpf_prog_array_length(old_array) >= BPF_MAX_PROGS) {
> + ret = -E2BIG;
> + goto unlock;
> + }
> +
> + ret = bpf_prog_array_copy(old_array, NULL, prog, &new_array);
> + if (ret < 0)
> + goto unlock;
> +
> + rcu_assign_pointer(disk->progs, new_array);
> + bpf_prog_array_free(old_array);
> +
> +unlock:
> + mutex_unlock(&disk->io_filter_lock);
> + return ret;
> +}
> +
> +int io_filter_prog_detach(const union bpf_attr *attr)
> +{
> + struct bpf_prog *prog;
> + struct gendisk *disk;
> + struct fd f;
> + struct bpf_prog_array *old_array;
> + struct bpf_prog_array *new_array;
> + int ret;
> +
> + if (attr->attach_flags)
> + return -EINVAL;
> +
> + /* increments prog refcnt */
> + prog = bpf_prog_get_type(attr->attach_bpf_fd,
> + BPF_PROG_TYPE_IO_FILTER);
> +
> + if (IS_ERR(prog))
> + return PTR_ERR(prog);
> +
> + f = fdget(attr->target_fd);
> + if (!f.file) {
> + ret = -EBADF;
> + goto put;
> + }
> +
> + disk = I_BDEV(f.file->f_mapping->host)->bd_disk;
> + if (disk == NULL) {
> + ret = -ENXIO;
> + goto put;
> + }
> +
> + ret = mutex_lock_interruptible(&disk->io_filter_lock);
> + if (ret)
> + goto put;
> +
> + old_array = io_filter_rcu_dereference_progs(disk);
> + ret = bpf_prog_array_copy(old_array, prog, NULL, &new_array);
> + if (ret)
> + goto unlock;
> +
> + rcu_assign_pointer(disk->progs, new_array);
> + bpf_prog_array_free(old_array);
> + bpf_prog_put(prog); /* put for detaching of program from dev */
> +
> +unlock:
> + mutex_unlock(&disk->io_filter_lock);
> +put:
> + bpf_prog_put(prog); /* put for bpf_prog_get_type */
> + return ret;
> +}
> +
> +/* allows IO by default if no programs attached */
> +int io_filter_bpf_run(struct bio *bio)
> +{
> + struct bpf_io_request io_req = {
> + .sector_start = bio->bi_iter.bi_sector,
> + .sector_cnt = bio_sectors(bio),
> + .opf = bio->bi_opf,
> + };
> +
> + return BPF_PROG_RUN_ARRAY_CHECK(bio->bi_disk->progs, &io_req, BPF_PROG_RUN);
I think pass "struct bpf_io_request" is not enough, since we may want to do the filter based on
some special patterns against the io data.
I used to pass "page_to_virt(bio->bi_io_vec->bv_page)" into ebpf program..
Regards,
Bob
> +}
> +
> +void io_filter_bpf_init(struct gendisk *disk)
> +{
> + mutex_init(&disk->io_filter_lock);
> +}
> +
> +void io_filter_bpf_free(struct gendisk *disk)
> +{
> + struct bpf_prog_array_item *item;
> + struct bpf_prog_array *array;
> +
> + mutex_destroy(&disk->io_filter_lock);
> +
> + array = io_filter_rcu_dereference_progs(disk);
> + if (!array)
> + return;
> +
> + for (item = array->items; item->prog; item++)
> + bpf_prog_put(item->prog);
> +
> + bpf_prog_array_free(array);
> +}
> diff --git a/block/blk-bpf-io-filter.h b/block/blk-bpf-io-filter.h
> new file mode 100644
> index 000000000000..cca705c4659e
> --- /dev/null
> +++ b/block/blk-bpf-io-filter.h
> @@ -0,0 +1,16 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#ifndef _BLK_BPF_IO_FILTER
> +#define _BLK_BPF_IO_FILTER
> +
> +#ifdef CONFIG_BPF_IO_FILTER
> +void io_filter_bpf_init(struct gendisk *disk);
> +void io_filter_bpf_free(struct gendisk *disk);
> +int io_filter_bpf_run(struct bio *bio);
> +#else
> +static inline void io_filter_bpf_init(struct gendisk *disk) { }
> +static inline void io_filter_bpf_free(struct gendisk *disk) { }
> +static inline int io_filter_bpf_run(struct bio *bio) { return IO_ALLOW; }
> +#endif
> +
> +#endif /* _BLK_BPF_IO_FILTER */
> diff --git a/block/blk-core.c b/block/blk-core.c
> index 03252af8c82c..740ac4807f41 100644
> --- a/block/blk-core.c
> +++ b/block/blk-core.c
> @@ -50,6 +50,7 @@
> #include "blk-mq-sched.h"
> #include "blk-pm.h"
> #include "blk-rq-qos.h"
> +#include "blk-bpf-io-filter.h"
>
> #ifdef CONFIG_DEBUG_FS
> struct dentry *blk_debugfs_root;
> @@ -1005,6 +1006,11 @@ generic_make_request_checks(struct bio *bio)
> }
> }
>
> + if (!io_filter_bpf_run(bio)) {
> + status = BLK_STS_PROTECTION;
> + goto end_io;
> + }
> +
> if (!test_bit(QUEUE_FLAG_POLL, &q->queue_flags))
> bio->bi_opf &= ~REQ_HIPRI;
>
> diff --git a/block/genhd.c b/block/genhd.c
> index 1a7659327664..cff346c78ec6 100644
> --- a/block/genhd.c
> +++ b/block/genhd.c
> @@ -25,6 +25,7 @@
> #include <linux/badblocks.h>
>
> #include "blk.h"
> +#include "blk-bpf-io-filter.h"
>
> static DEFINE_MUTEX(block_class_lock);
> static struct kobject *block_depr;
> @@ -935,6 +936,7 @@ void del_gendisk(struct gendisk *disk)
> if (!sysfs_deprecated)
> sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
> pm_runtime_set_memalloc_noio(disk_to_dev(disk), false);
> + io_filter_bpf_free(disk);
> device_del(disk_to_dev(disk));
> }
> EXPORT_SYMBOL(del_gendisk);
> @@ -1719,6 +1721,7 @@ struct gendisk *__alloc_disk_node(int minors, int node_id)
>
> disk->minors = minors;
> rand_initialize_disk(disk);
> + io_filter_bpf_init(disk);
> disk_to_dev(disk)->class = &block_class;
> disk_to_dev(disk)->type = &disk_type;
> device_initialize(disk_to_dev(disk));
> diff --git a/include/linux/bpf_io_filter.h b/include/linux/bpf_io_filter.h
> new file mode 100644
> index 000000000000..6f8a3da963ed
> --- /dev/null
> +++ b/include/linux/bpf_io_filter.h
> @@ -0,0 +1,23 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#ifndef _BPF_IO_FILTER_H
> +#define _BPF_IO_FILTER_H
> +
> +#include <uapi/linux/bpf.h>
> +struct bpf_prog;
> +
> +#ifdef CONFIG_BPF_IO_FILTER
> +int io_filter_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog);
> +int io_filter_prog_detach(const union bpf_attr *attr);
> +#else
> +static inline int io_filter_prog_attach(const union bpf_attr *attr,
> + struct bpf_prog *prog)
> +{
> + return -EINVAL;
> +}
> +static inline int io_filter_prog_detach(const union bpf_attr *attr)
> +{
> + return -EINVAL;
> +}
> +#endif
> +#endif /* _BPF_IO_FILTER_H */
> diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h
> index a18ae82a298a..f05193a2756e 100644
> --- a/include/linux/bpf_types.h
> +++ b/include/linux/bpf_types.h
> @@ -49,6 +49,10 @@ BPF_PROG_TYPE(BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE, raw_tracepoint_writable,
> BPF_PROG_TYPE(BPF_PROG_TYPE_TRACING, tracing,
> void *, void *)
> #endif
> +#ifdef CONFIG_BPF_IO_FILTER
> +BPF_PROG_TYPE(BPF_PROG_TYPE_IO_FILTER, io_filter,
> + struct bpf_io_request, struct bpf_io_request)
> +#endif
> #ifdef CONFIG_CGROUP_BPF
> BPF_PROG_TYPE(BPF_PROG_TYPE_CGROUP_DEVICE, cg_dev,
> struct bpf_cgroup_dev_ctx, struct bpf_cgroup_dev_ctx)
> diff --git a/include/linux/genhd.h b/include/linux/genhd.h
> index 392aad5e29a2..2da2cb1d0c46 100644
> --- a/include/linux/genhd.h
> +++ b/include/linux/genhd.h
> @@ -209,6 +209,10 @@ struct gendisk {
> int node_id;
> struct badblocks *bb;
> struct lockdep_map lockdep_map;
> +#ifdef CONFIG_BPF_IO_FILTER
> + struct bpf_prog_array __rcu *progs;
> + struct mutex io_filter_lock;
> +#endif
> };
>
> #if IS_REACHABLE(CONFIG_CDROM)
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index 8bd33050b7bb..4f84ab93d82c 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -189,6 +189,7 @@ enum bpf_prog_type {
> BPF_PROG_TYPE_STRUCT_OPS,
> BPF_PROG_TYPE_EXT,
> BPF_PROG_TYPE_LSM,
> + BPF_PROG_TYPE_IO_FILTER,
> };
>
> enum bpf_attach_type {
> @@ -226,6 +227,7 @@ enum bpf_attach_type {
> BPF_CGROUP_INET4_GETSOCKNAME,
> BPF_CGROUP_INET6_GETSOCKNAME,
> BPF_XDP_DEVMAP,
> + BPF_BIO_SUBMIT,
> __MAX_BPF_ATTACH_TYPE
> };
>
> @@ -4261,4 +4263,13 @@ struct bpf_pidns_info {
> __u32 pid;
> __u32 tgid;
> };
> +
> +#define IO_ALLOW 1
> +#define IO_BLOCK 0
> +
> +struct bpf_io_request {
> + __u64 sector_start; /* first sector */
> + __u32 sector_cnt; /* number of sectors */
> + __u32 opf; /* bio->bi_opf */
> +};
> #endif /* _UAPI__LINUX_BPF_H__ */
> diff --git a/init/Kconfig b/init/Kconfig
> index 0498af567f70..f44de091757e 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -1647,6 +1647,14 @@ config KALLSYMS_BASE_RELATIVE
>
> # syscall, maps, verifier
>
> +config BPF_IO_FILTER
> + bool "Instrumentation of block io filtering subsystem with BPF"
> + depends on BPF_EVENTS
> + depends on BPF_SYSCALL
> + help
> + Enables instrumentation of the hooks in block subsystem with eBPF
> + programs for observing and filtering io.
> +
> config BPF_LSM
> bool "LSM Instrumentation with BPF"
> depends on BPF_EVENTS
> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> index 0fd80ac81f70..179c37efe8e2 100644
> --- a/kernel/bpf/syscall.c
> +++ b/kernel/bpf/syscall.c
> @@ -29,6 +29,7 @@
> #include <linux/bpf_lsm.h>
> #include <linux/poll.h>
> #include <linux/bpf-netns.h>
> +#include <linux/bpf_io_filter.h>
>
> #define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \
> (map)->map_type == BPF_MAP_TYPE_CGROUP_ARRAY || \
> @@ -1964,6 +1965,7 @@ bpf_prog_load_check_attach(enum bpf_prog_type prog_type,
>
> switch (prog_type) {
> case BPF_PROG_TYPE_TRACING:
> + case BPF_PROG_TYPE_IO_FILTER:
> case BPF_PROG_TYPE_LSM:
> case BPF_PROG_TYPE_STRUCT_OPS:
> case BPF_PROG_TYPE_EXT:
> @@ -2815,6 +2817,8 @@ attach_type_to_prog_type(enum bpf_attach_type attach_type)
> return BPF_PROG_TYPE_CGROUP_SOCKOPT;
> case BPF_TRACE_ITER:
> return BPF_PROG_TYPE_TRACING;
> + case BPF_BIO_SUBMIT:
> + return BPF_PROG_TYPE_IO_FILTER;
> default:
> return BPF_PROG_TYPE_UNSPEC;
> }
> @@ -2858,6 +2862,9 @@ static int bpf_prog_attach(const union bpf_attr *attr)
> case BPF_PROG_TYPE_LIRC_MODE2:
> ret = lirc_prog_attach(attr, prog);
> break;
> + case BPF_PROG_TYPE_IO_FILTER:
> + ret = io_filter_prog_attach(attr, prog);
> + break;
> case BPF_PROG_TYPE_FLOW_DISSECTOR:
> ret = netns_bpf_prog_attach(attr, prog);
> break;
> @@ -2906,6 +2913,8 @@ static int bpf_prog_detach(const union bpf_attr *attr)
> case BPF_PROG_TYPE_CGROUP_SYSCTL:
> case BPF_PROG_TYPE_SOCK_OPS:
> return cgroup_bpf_prog_detach(attr, ptype);
> + case BPF_PROG_TYPE_IO_FILTER:
> + return io_filter_prog_detach(attr);
> default:
> return -EINVAL;
> }
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 94cead5a43e5..71372e99a722 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -2613,6 +2613,7 @@ static bool may_access_direct_pkt_data(struct bpf_verifier_env *env,
> case BPF_PROG_TYPE_LWT_SEG6LOCAL:
> case BPF_PROG_TYPE_SK_REUSEPORT:
> case BPF_PROG_TYPE_FLOW_DISSECTOR:
> + case BPF_PROG_TYPE_IO_FILTER:
> case BPF_PROG_TYPE_CGROUP_SKB:
> if (t == BPF_WRITE)
> return false;
> diff --git a/tools/bpf/bpftool/feature.c b/tools/bpf/bpftool/feature.c
> index 768bf77df886..765702ae0189 100644
> --- a/tools/bpf/bpftool/feature.c
> +++ b/tools/bpf/bpftool/feature.c
> @@ -383,6 +383,8 @@ static void probe_kernel_image_config(const char *define_prefix)
> { "CONFIG_IPV6_SEG6_BPF", },
> /* BPF_PROG_TYPE_LIRC_MODE2 and related helpers */
> { "CONFIG_BPF_LIRC_MODE2", },
> + /* BPF_PROG_TYPE_IO_FILTER */
> + { "CONFIG_BPF_IO_FILTER", },
> /* BPF stream parser and BPF socket maps */
> { "CONFIG_BPF_STREAM_PARSER", },
> /* xt_bpf module for passing BPF programs to netfilter */
> diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h
> index 5cdf0bc049bd..0607ae6f6d90 100644
> --- a/tools/bpf/bpftool/main.h
> +++ b/tools/bpf/bpftool/main.h
> @@ -86,6 +86,7 @@ static const char * const prog_type_name[] = {
> [BPF_PROG_TYPE_TRACING] = "tracing",
> [BPF_PROG_TYPE_STRUCT_OPS] = "struct_ops",
> [BPF_PROG_TYPE_EXT] = "ext",
> + [BPF_PROG_TYPE_IO_FILTER] = "io_filter",
> };
>
> static const char * const attach_type_name[__MAX_BPF_ATTACH_TYPE] = {
> @@ -122,6 +123,7 @@ static const char * const attach_type_name[__MAX_BPF_ATTACH_TYPE] = {
> [BPF_TRACE_FEXIT] = "fexit",
> [BPF_MODIFY_RETURN] = "mod_ret",
> [BPF_LSM_MAC] = "lsm_mac",
> + [BPF_BIO_SUBMIT] = "bio_submit",
> };
>
> extern const char * const map_type_name[];
> diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
> index 8bd33050b7bb..f665e37b7277 100644
> --- a/tools/include/uapi/linux/bpf.h
> +++ b/tools/include/uapi/linux/bpf.h
> @@ -189,6 +189,7 @@ enum bpf_prog_type {
> BPF_PROG_TYPE_STRUCT_OPS,
> BPF_PROG_TYPE_EXT,
> BPF_PROG_TYPE_LSM,
> + BPF_PROG_TYPE_IO_FILTER,
> };
>
> enum bpf_attach_type {
> @@ -226,6 +227,7 @@ enum bpf_attach_type {
> BPF_CGROUP_INET4_GETSOCKNAME,
> BPF_CGROUP_INET6_GETSOCKNAME,
> BPF_XDP_DEVMAP,
> + BPF_BIO_SUBMIT,
> __MAX_BPF_ATTACH_TYPE
> };
>
> @@ -4261,4 +4263,13 @@ struct bpf_pidns_info {
> __u32 pid;
> __u32 tgid;
> };
> +
> +#define IO_ALLOW 1
> +#define IO_BLOCK 0
> +
> +struct bpf_io_request {
> + __u64 sector_start; /* first sector */
> + __u32 sector_cnt; /* number of sectors */
> + __u32 opf; /* bio->bi_opf */
> +};
> #endif /* _UAPI__LINUX_BPF_H__ */
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index 11e4725b8b1c..609b16007891 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -6724,6 +6724,8 @@ static const struct bpf_sec_def section_defs[] = {
> BPF_EAPROG_SEC("cgroup/setsockopt", BPF_PROG_TYPE_CGROUP_SOCKOPT,
> BPF_CGROUP_SETSOCKOPT),
> BPF_PROG_SEC("struct_ops", BPF_PROG_TYPE_STRUCT_OPS),
> + BPF_APROG_SEC("io_filter", BPF_PROG_TYPE_IO_FILTER,
> + BPF_BIO_SUBMIT),
> };
>
> #undef BPF_PROG_SEC_IMPL
> diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
> index 10cd8d1891f5..b882b200a402 100644
> --- a/tools/lib/bpf/libbpf_probes.c
> +++ b/tools/lib/bpf/libbpf_probes.c
> @@ -109,6 +109,7 @@ probe_load(enum bpf_prog_type prog_type, const struct bpf_insn *insns,
> case BPF_PROG_TYPE_STRUCT_OPS:
> case BPF_PROG_TYPE_EXT:
> case BPF_PROG_TYPE_LSM:
> + case BPF_PROG_TYPE_IO_FILTER:
> default:
> break;
> }
> diff --git a/tools/testing/selftests/bpf/prog_tests/section_names.c b/tools/testing/selftests/bpf/prog_tests/section_names.c
> index 713167449c98..ef6658a776b1 100644
> --- a/tools/testing/selftests/bpf/prog_tests/section_names.c
> +++ b/tools/testing/selftests/bpf/prog_tests/section_names.c
> @@ -158,6 +158,11 @@ static struct sec_name_test tests[] = {
> {0, BPF_PROG_TYPE_CGROUP_SOCKOPT, BPF_CGROUP_SETSOCKOPT},
> {0, BPF_CGROUP_SETSOCKOPT},
> },
> + {
> + "io_filter",
> + {0, BPF_PROG_TYPE_IO_FILTER, BPF_BIO_SUBMIT},
> + {0, BPF_BIO_SUBMIT},
> + },
> };
>
> static void test_prog_type_by_name(const struct sec_name_test *test)
>
next prev parent reply other threads:[~2020-08-17 14:18 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-12 16:33 [RFC PATCH 0/4] block/bpf: add eBPF based block layer IO filtering Leah Rumancik
2020-08-12 16:33 ` [RFC PATCH 1/4] bpf: add new prog_type BPF_PROG_TYPE_IO_FILTER Leah Rumancik
2020-08-13 23:00 ` Martin KaFai Lau
2020-09-04 15:43 ` Leah Rumancik
2020-08-17 14:18 ` Bob Liu [this message]
2020-08-17 16:32 ` Alexei Starovoitov
2020-09-04 16:46 ` Leah Rumancik
2020-09-04 18:50 ` Alexei Starovoitov
2020-09-17 18:33 ` Leah Rumancik
2020-09-01 16:53 ` Leah Rumancik
2020-09-02 7:36 ` Bob Liu
2020-08-18 12:53 ` Jakub Sitnicki
2020-09-04 17:29 ` Leah Rumancik
2020-08-12 16:33 ` [RFC PATCH 2/4] bpf: add protect_gpt sample program Leah Rumancik
2020-08-13 22:58 ` Martin KaFai Lau
2020-09-01 16:33 ` Leah Rumancik
2020-08-12 16:33 ` [RFC PATCH 3/4] bpf: add eBPF IO filter documentation Leah Rumancik
2020-08-12 17:04 ` Bart Van Assche
2020-08-12 17:50 ` Jonathan Corbet
2020-09-01 15:35 ` Leah Rumancik
2020-08-12 16:33 ` [RFC PATCH 4/4] bpf: add BPF_PROG_TYPE_LSM to bpftool name array Leah Rumancik
2020-08-12 17:00 ` Bart Van Assche
2020-08-12 18:17 ` Tobias Klauser
2020-09-01 15:18 ` Leah Rumancik
2020-08-17 6:37 ` [RFC PATCH 0/4] block/bpf: add eBPF based block layer IO filtering Christoph Hellwig
2020-08-18 2:44 ` Ming Lei
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=a0a97488-58c7-1f00-c987-d75e1329159c@oracle.com \
--to=bob.liu@oracle.com \
--cc=bpf@vger.kernel.org \
--cc=bvanassche@google.com \
--cc=harshads@google.com \
--cc=jasiu@google.com \
--cc=leah.rumancik@gmail.com \
--cc=linux-block@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=orbekk@google.com \
--cc=saranyamohan@google.com \
--cc=tytso@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox