
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/ICA1GK -------------------------------- Create a bpf iter target for the 'partitions' interface, to which the bpf prog can attach. Signed-off-by: GONG Ruiqi <gongruiqi1@huawei.com> --- block/genhd.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/block/genhd.c b/block/genhd.c index 9d9b60501bcb..f19a86b11dea 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -1456,6 +1456,93 @@ static struct bpf_iter_reg diskstats_reg_info = { BTF_ID_LIST(btf_diststats_ids) BTF_ID(struct, block_device) BTF_ID(struct, disk_stats) + +static void *bpf_show_partition_start(struct seq_file *seqf, loff_t *pos) +{ + void *p; + + p = bpf_disk_seqf_start(seqf, pos); + if (!IS_ERR_OR_NULL(p) && !*pos) + seq_puts(seqf, "major minor #blocks name\n\n"); + return p; +} + +struct bpf_iter__partitions { + __bpf_md_ptr(struct bpf_iter_meta *, meta); + __bpf_md_ptr(struct block_device *, part); +}; + +DEFINE_BPF_ITER_FUNC(partitions, struct bpf_iter_meta *meta, + struct block_device *part) + +static void native_show_partition(struct seq_file *seqf, struct block_device *part) +{ + if (!bdev_nr_sectors(part)) + return; + seq_printf(seqf, "%4d %7d %10llu %pg\n", + MAJOR(part->bd_dev), MINOR(part->bd_dev), + bdev_nr_sectors(part) >> 1, part); +} + +static void __show_partition(struct seq_file *seqf, struct block_device *part) +{ + struct bpf_iter__partitions ctx; + struct bpf_iter_meta meta; + struct bpf_prog *prog; + + meta.seq = seqf; + prog = bpf_iter_get_info(&meta, false); + if (!prog) + return native_show_partition(seqf, part); + + ctx.meta = &meta; + ctx.part = part; + bpf_iter_run_prog(prog, &ctx); +} + +/* Inconvenient to operate Xarray in bpf progs. */ +static int bpf_show_partition(struct seq_file *seqf, void *v) +{ + struct gendisk *sgp = v; + struct block_device *part; + unsigned long idx; + + if (!get_capacity(sgp) || (sgp->flags & GENHD_FL_HIDDEN)) + return 0; + + rcu_read_lock(); + xa_for_each(&sgp->part_tbl, idx, part) + __show_partition(seqf, part); + rcu_read_unlock(); + return 0; +} + +static const struct seq_operations bpf_partitions_op = { + .start = bpf_show_partition_start, + .next = disk_seqf_next, + .stop = bpf_disk_seqf_stop, + .show = bpf_show_partition +}; + +static const struct bpf_iter_seq_info partitions_seq_info = { + .seq_ops = &bpf_partitions_op, + .init_seq_private = NULL, + .fini_seq_private = NULL, + .seq_priv_size = sizeof(struct class_dev_iter), +}; + +static struct bpf_iter_reg partitions_reg_info = { + .target = "partitions", + .ctx_arg_info_size = 1, + .ctx_arg_info = { + { offsetof(struct bpf_iter__partitions, part), + PTR_TO_BTF_ID }, // part won't be NULL + }, + .seq_info = &partitions_seq_info, +}; + +BTF_ID_LIST(btf_partitions_ids) +BTF_ID(struct, block_device) #endif /* CONFIG_BPF_RVI */ static int __init proc_genhd_init(void) @@ -1469,6 +1556,11 @@ static int __init proc_genhd_init(void) diskstats_reg_info.ctx_arg_info[0].btf_id = btf_diststats_ids[0]; diskstats_reg_info.ctx_arg_info[1].btf_id = btf_diststats_ids[1]; err = bpf_iter_reg_target(&diskstats_reg_info); + if (err) + return err; + + partitions_reg_info.ctx_arg_info[0].btf_id = btf_partitions_ids[0]; + err = bpf_iter_reg_target(&partitions_reg_info); #endif return err; } -- 2.25.1