linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Hou Tao <houtao@huaweicloud.com>
To: bpf@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org,
	Alexei Starovoitov <alexei.starovoitov@gmail.com>,
	Yonghong Song <yhs@fb.com>,
	Andrii Nakryiko <andrii.nakryiko@gmail.com>,
	Viacheslav Dubeyko <slava@dubeyko.com>,
	Amir Goldstein <amir73il@gmail.com>,
	houtao1@huawei.com
Subject: [RFC PATCH bpf-next 3/4] bpf: Introduce bpf iterator for file system mount
Date: Sun,  7 May 2023 12:01:06 +0800	[thread overview]
Message-ID: <20230507040107.3755166-4-houtao@huaweicloud.com> (raw)
In-Reply-To: <20230507040107.3755166-1-houtao@huaweicloud.com>

From: Hou Tao <houtao1@huawei.com>

Now the only way to query the information about a specific mount is to
parse the content of /proc/pid/mountinfo, find the specific mount and
return the needed information.

There is no way to query for a specific mount directly, so introduce bpf
iterator for fs mount to support that. By passing a fd to bpf iterator,
the bpf program will get the mount of the specific file and it can
output the necessary information for the mount in bpf iterator fd.

The following is the output from "test_progs -t bpf_iter_fs/fs_mnt"
which shows the basic information of a tmpfs mount:

  dev 0:31 id 40 parent_id 24 mnt_flags 0x1003 shared:17

Signed-off-by: Hou Tao <houtao1@huawei.com>
---
 include/linux/btf_ids.h        |  3 +-
 include/uapi/linux/bpf.h       |  1 +
 kernel/bpf/fs_iter.c           | 60 +++++++++++++++++++++++++++++-----
 tools/include/uapi/linux/bpf.h |  1 +
 4 files changed, 55 insertions(+), 10 deletions(-)

diff --git a/include/linux/btf_ids.h b/include/linux/btf_ids.h
index 9e036d1360e7..48537adee9fc 100644
--- a/include/linux/btf_ids.h
+++ b/include/linux/btf_ids.h
@@ -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 {
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 099048ba3edc..62bed6e603a5 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -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 {
diff --git a/kernel/bpf/fs_iter.c b/kernel/bpf/fs_iter.c
index cd7f10ea00ab..19f83211ccc4 100644
--- a/kernel/bpf/fs_iter.c
+++ b/kernel/bpf/fs_iter.c
@@ -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);
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 099048ba3edc..62bed6e603a5 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -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 {
-- 
2.29.2


  parent reply	other threads:[~2023-05-07  3:30 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-07  4:01 [RFC PATCH bpf-next 0/4] Introduce bpf iterators for file-system Hou Tao
2023-05-07  4:01 ` [RFC PATCH bpf-next 1/4] bpf: Introduce bpf iterator for file-system inode Hou Tao
2023-05-07  4:01 ` [RFC PATCH bpf-next 2/4] bpf: Add three kfunc helpers for bpf fs inode iterator Hou Tao
2023-05-07  4:01 ` Hou Tao [this message]
2023-05-07  4:01 ` [RFC PATCH bpf-next 4/4] selftests/bpf: Add test cases for bpf file-system iterator Hou Tao

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=20230507040107.3755166-4-houtao@huaweicloud.com \
    --to=houtao@huaweicloud.com \
    --cc=alexei.starovoitov@gmail.com \
    --cc=amir73il@gmail.com \
    --cc=andrii.nakryiko@gmail.com \
    --cc=bpf@vger.kernel.org \
    --cc=houtao1@huawei.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=slava@dubeyko.com \
    --cc=yhs@fb.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;
as well as URLs for NNTP newsgroup(s).