From: Yufen Yu yuyufen@huawei.com
hulk inclusion category: feature bugzilla: NA CVE: NA
-------------------------------------------------
Usage: cd tools/testing/selftests make -C bpf -j ./test_xfs_file # running
Signed-off-by: Yufen Yu yuyufen@huawei.com Reviewed-by: Hou Tao houtao1@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- tools/include/uapi/linux/xfs.h | 17 +++++++ tools/testing/selftests/bpf/Makefile | 5 +- .../testing/selftests/bpf/test_set_xfs_file.c | 40 +++++++++++++++ tools/testing/selftests/bpf/test_xfs_file.c | 51 +++++++++++++++++++ 4 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 tools/include/uapi/linux/xfs.h create mode 100644 tools/testing/selftests/bpf/test_set_xfs_file.c create mode 100644 tools/testing/selftests/bpf/test_xfs_file.c
diff --git a/tools/include/uapi/linux/xfs.h b/tools/include/uapi/linux/xfs.h new file mode 100644 index 0000000000000..f333a2eb74074 --- /dev/null +++ b/tools/include/uapi/linux/xfs.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI_LINUX_XFS_H +#define _UAPI_LINUX_XFS_H + +#include <linux/types.h> + +#define FMODE_RANDOM (0x1000) +#define FMODE_WILLNEED (0x40000000) + +struct xfs_writable_file { + const unsigned char *name; + unsigned int f_mode; /* can be set into file->f_mode */ + long long i_size; /* file size */ + long long prev_pos; /* ra->prev_pos */ +}; + +#endif /* _UAPI_LINUX_XFS_H */ diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index f3f874ba186bb..1ba656a8ed656 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -23,7 +23,8 @@ $(TEST_CUSTOM_PROGS): $(OUTPUT)/%: %.c TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \ test_align test_verifier_log test_dev_cgroup test_tcpbpf_user \ test_sock test_btf test_sockmap test_lirc_mode2_user get_cgroup_id_user \ - test_socket_cookie test_cgroup_storage test_select_reuseport + test_socket_cookie test_cgroup_storage test_select_reuseport test_xfs_file +
TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test_obj_id.o \ test_pkt_md_access.o test_xdp_redirect.o test_xdp_meta.o sockmap_parse_prog.o \ @@ -35,7 +36,7 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test test_get_stack_rawtp.o test_sockmap_kern.o test_sockhash_kern.o \ test_lwt_seg6local.o sendmsg4_prog.o sendmsg6_prog.o test_lirc_mode2_kern.o \ get_cgroup_id_kern.o socket_cookie_prog.o test_select_reuseport_kern.o \ - test_skb_cgroup_id_kern.o + test_skb_cgroup_id_kern.o test_set_xfs_file.o
# Order correspond to 'make run_tests' order TEST_PROGS := test_kmod.sh \ diff --git a/tools/testing/selftests/bpf/test_set_xfs_file.c b/tools/testing/selftests/bpf/test_set_xfs_file.c new file mode 100644 index 0000000000000..0b289bbc3985d --- /dev/null +++ b/tools/testing/selftests/bpf/test_set_xfs_file.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/bpf.h> +#include "bpf_helpers.h" +#include <string.h> +#include <linux/xfs.h> + +/* from /sys/kernel/debug/tracing/events/xfs/xfs_read_file */ +struct xfs_read_buffer_args { + struct xfs_writable_file *file; +}; + +SEC("tracepoint/xfs/xfs_file_read") +int bpf_prog1(struct xfs_read_buffer_args *ctx) +{ + char fmt[] = "name: %s, f_mode:%d, i_size:%lu\n"; + struct xfs_writable_file *file = ctx->file; + char name[64] = {}; + char *tmp; + unsigned long i_size; + int len; + + bpf_probe_read(&tmp, 8, &(file->name)); + len = bpf_probe_read_str(name, 64, tmp); + bpf_probe_read(&i_size, 8, &(file->i_size)); + + if (!strncmp("blk_", name, 4)) { + /* blk_xxx.meta or blk_xxx with size < 2M */ + if (len == 27 || (len == 15 && i_size <= 2 * 1024 * 1024)) + file->f_mode |= FMODE_WILLNEED; + /* blk_xxx */ + else if (len == 15) + file->f_mode |= FMODE_RANDOM; + bpf_trace_printk(fmt, sizeof(fmt), name, file->f_mode, i_size); + } + return 0; +} + +char _license[] SEC("license") = "GPL"; +__u32 _version SEC("version") = 1; diff --git a/tools/testing/selftests/bpf/test_xfs_file.c b/tools/testing/selftests/bpf/test_xfs_file.c new file mode 100644 index 0000000000000..d0bc971d93bf9 --- /dev/null +++ b/tools/testing/selftests/bpf/test_xfs_file.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <assert.h> +#include <sys/time.h> +#include <unistd.h> + +#include <linux/bpf.h> +#include <bpf/bpf.h> +#include <bpf/libbpf.h> + +#include "bpf_rlimit.h" + +#define SLEEP_SECS 9999999 + +int main(int argc, char *argv[]) +{ + const char *file = "./test_set_xfs_file.o"; + struct bpf_object *obj; + int efd, err, prog_fd; + int delay = SLEEP_SECS; + char *endptr, *str; + + if (argc == 2) { + str = argv[1]; + delay = strtol(str, &endptr, 10); + } + + err = bpf_prog_load(file, BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE, &obj, + &prog_fd); + if (err) { + printf("Failed to load xfs program\n"); + goto out; + } + + efd = bpf_raw_tracepoint_open("xfs_file_read", prog_fd); + if (efd < 0) { + printf("Fail to open tracepoint, efd %d\n", efd); + goto out; + } + + sleep(delay); + + printf("END\n"); + +out: + return err; +}