@@ -257,7 +257,8 @@ extern u32 btf_sock_ids[];
BTF_TRACING_TYPE(BTF_TRACING_TYPE_FILE, file) \
BTF_TRACING_TYPE(BTF_TRACING_TYPE_VMA, vm_area_struct) \
BTF_TRACING_TYPE(BTF_TRACING_TYPE_INODE, inode) \
- BTF_TRACING_TYPE(BTF_TRACING_TYPE_DENTRY, dentry)
+ BTF_TRACING_TYPE(BTF_TRACING_TYPE_DENTRY, dentry) \
+ BTF_TRACING_TYPE(BTF_TRACING_TYPE_MOUNT, mount)
enum {
@@ -97,6 +97,7 @@ enum bpf_cgroup_iter_order {
enum bpf_fs_iter_type {
BPF_FS_ITER_INODE = 0, /* a specific inode */
+ BPF_FS_ITER_MNT, /* a specific mount */
};
union bpf_iter_link_info {
@@ -9,7 +9,11 @@
#include <linux/btf_ids.h>
#include <linux/seq_file.h>
+/* TODO: move fs_iter.c to fs directory ? */
+#include "../../fs/mount.h"
+
DEFINE_BPF_ITER_FUNC(fs_inode, struct bpf_iter_meta *meta, struct inode *inode, struct dentry *dentry);
+DEFINE_BPF_ITER_FUNC(fs_mnt, struct bpf_iter_meta *meta, struct mount *mnt);
struct bpf_iter__fs_inode {
__bpf_md_ptr(struct bpf_iter_meta *, meta);
@@ -17,6 +21,11 @@ struct bpf_iter__fs_inode {
__bpf_md_ptr(struct dentry *, dentry);
};
+struct bpf_iter__fs_mnt {
+ __bpf_md_ptr(struct bpf_iter_meta *, meta);
+ __bpf_md_ptr(struct mount *, mnt);
+};
+
struct bpf_fs_iter_aux_info {
atomic_t count;
enum bpf_fs_iter_type type;
@@ -47,7 +56,7 @@ static int bpf_iter_attach_fs(struct bpf_prog *prog, union bpf_iter_link_info *l
struct bpf_fs_iter_aux_info *fs;
struct file *filp;
- if (linfo->fs.type > BPF_FS_ITER_INODE)
+ if (linfo->fs.type > BPF_FS_ITER_MNT)
return -EINVAL;
/* TODO: The file-system is pinned */
filp = fget(linfo->fs.fd);
@@ -99,12 +108,14 @@ static void *fs_iter_seq_start(struct seq_file *m, loff_t *pos)
if (*pos == 0)
++*pos;
- return file_inode(info->fs->filp);
+ if (info->fs->type == BPF_FS_ITER_INODE)
+ return file_inode(info->fs->filp);
+ return real_mount(info->fs->filp->f_path.mnt);
}
static int __fs_iter_seq_show(struct seq_file *m, void *v, bool stop)
{
- struct bpf_iter__fs_inode ctx;
+ struct bpf_iter_seq_fs_info *info = m->private;
struct bpf_iter_meta meta;
struct bpf_prog *prog;
int err;
@@ -114,11 +125,21 @@ static int __fs_iter_seq_show(struct seq_file *m, void *v, bool stop)
if (!prog)
return 0;
- ctx.meta = &meta;
- ctx.inode = v;
- ctx.dentry = v ? d_find_alias(v) : NULL;
- err = bpf_iter_run_prog(prog, &ctx);
- dput(ctx.dentry);
+ if (info->fs->type == BPF_FS_ITER_INODE) {
+ struct bpf_iter__fs_inode ino_ctx;
+
+ ino_ctx.meta = &meta;
+ ino_ctx.inode = v;
+ ino_ctx.dentry = v ? d_find_alias(v) : NULL;
+ err = bpf_iter_run_prog(prog, &ino_ctx);
+ dput(ino_ctx.dentry);
+ } else {
+ struct bpf_iter__fs_mnt mnt_ctx;
+
+ mnt_ctx.meta = &meta;
+ mnt_ctx.mnt = v;
+ err = bpf_iter_run_prog(prog, &mnt_ctx);
+ }
return err;
}
@@ -165,10 +186,31 @@ static struct bpf_iter_reg fs_inode_reg_info = {
.seq_info = &fs_iter_seq_info,
};
+static struct bpf_iter_reg fs_mnt_reg_info = {
+ .target = "fs_mnt",
+ .attach_target = bpf_iter_attach_fs,
+ .detach_target = bpf_iter_detach_fs,
+ .ctx_arg_info_size = 1,
+ .ctx_arg_info = {
+ { offsetof(struct bpf_iter__fs_mnt, mnt), PTR_TO_BTF_ID_OR_NULL },
+ },
+ .seq_info = &fs_iter_seq_info,
+};
+
static int __init fs_iter_init(void)
{
+ int err;
+
fs_inode_reg_info.ctx_arg_info[0].btf_id = btf_tracing_ids[BTF_TRACING_TYPE_INODE];
fs_inode_reg_info.ctx_arg_info[1].btf_id = btf_tracing_ids[BTF_TRACING_TYPE_DENTRY];
- return bpf_iter_reg_target(&fs_inode_reg_info);
+ err = bpf_iter_reg_target(&fs_inode_reg_info);
+ if (err)
+ return err;
+
+ fs_mnt_reg_info.ctx_arg_info[0].btf_id = btf_tracing_ids[BTF_TRACING_TYPE_MOUNT];
+ err = bpf_iter_reg_target(&fs_mnt_reg_info);
+ if (err)
+ bpf_iter_unreg_target(&fs_inode_reg_info);
+ return err;
}
late_initcall(fs_iter_init);
@@ -97,6 +97,7 @@ enum bpf_cgroup_iter_order {
enum bpf_fs_iter_type {
BPF_FS_ITER_INODE = 0, /* a specific inode */
+ BPF_FS_ITER_MNT, /* a specific mount */
};
union bpf_iter_link_info {