From: Yufen Yu yuyufen@huawei.com
hulk inclusion category: feature bugzilla: NA CVE: NA
-------------------------------------------------
This patch adds a new struct xfs_writable_file into file uapi/include/linux/xfs.h and adds a tracepoint that can modify struct xfs_writable_file. Then we can set file->f_mode in ebpf program to control the file.
Signed-off-by: Yufen Yu yuyufen@huawei.com Reviewed-by: Hou Tao houtao1@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/xfs/xfs_file.c | 13 +++++++++++- fs/xfs/xfs_linux.h | 1 + fs/xfs/xfs_trace.h | 46 ++++++++++++++++++++++++++++++++++++++++ include/uapi/linux/xfs.h | 15 +++++++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 include/uapi/linux/xfs.h
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 1b2eb9d055ba0..ffc388c8b4523 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -232,10 +232,21 @@ xfs_file_buffered_aio_read( struct kiocb *iocb, struct iov_iter *to) { - struct xfs_inode *ip = XFS_I(file_inode(iocb->ki_filp)); + struct file *filp = iocb->ki_filp; + struct xfs_inode *ip = XFS_I(file_inode(filp)); ssize_t ret; + struct xfs_writable_file file; + + file.name = file_dentry(filp)->d_name.name; + file.f_mode = 0; + file.i_size = file_inode(filp)->i_size; + file.prev_pos = filp->f_ra.prev_pos;
trace_xfs_file_buffered_read(ip, iov_iter_count(to), iocb->ki_pos); + trace_xfs_file_read(&file, ip, iov_iter_count(to), iocb->ki_pos); + + if (file.f_mode) + filp->f_mode |= file.f_mode;
if (iocb->ki_flags & IOCB_NOWAIT) { if (!xfs_ilock_nowait(ip, XFS_IOLOCK_SHARED)) diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h index edbd5a210df22..086173507c271 100644 --- a/fs/xfs/xfs_linux.h +++ b/fs/xfs/xfs_linux.h @@ -60,6 +60,7 @@ typedef __u32 xfs_nlink_t; #include <linux/list_sort.h> #include <linux/ratelimit.h> #include <linux/rhashtable.h> +#include <uapi/linux/xfs.h>
#include <asm/page.h> #include <asm/div64.h> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index a3e7813778b06..678a02d145445 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -3371,6 +3371,52 @@ TRACE_EVENT(xfs_iunlink_update_bucket, __entry->new_ptr) );
+DECLARE_EVENT_CLASS(xfs_file_read, + TP_PROTO(struct xfs_writable_file *file, struct xfs_inode *ip, + size_t count, loff_t offset), + TP_ARGS(file, ip, count, offset), + TP_STRUCT__entry( + __field(struct xfs_writable_file *, file) + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(loff_t, offset) + __field(size_t, count) + ), + TP_fast_assign( + __entry->file = 0; + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->offset = offset; + __entry->count = count; + ), + TP_printk("dev %d:%d ino 0x%llx offset 0x%llx count 0x%zx", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->offset, + __entry->count) +); + +#ifdef DEFINE_EVENT_WRITABLE +#undef XFS_DEFINE_EVENT +#define XFS_DEFINE_EVENT(template, call, proto, args, size) \ + DEFINE_EVENT_WRITABLE(template, call, PARAMS(proto), \ + PARAMS(args), size) +#else +#undef XFS_DEFINE_EVENT +#define XFS_DEFINE_EVENT(template, call, proto, args, size) \ + DEFINE_EVENT(template, call, PARAMS(proto), PARAMS(args)) +#endif + +XFS_DEFINE_EVENT(xfs_file_read, xfs_file_read, + + TP_PROTO(struct xfs_writable_file *file, struct xfs_inode *ip, + size_t count, loff_t offset), + + TP_ARGS(file, ip, count, offset), + + sizeof(struct xfs_writable_file) +); + #endif /* _TRACE_XFS_H */
#undef TRACE_INCLUDE_PATH diff --git a/include/uapi/linux/xfs.h b/include/uapi/linux/xfs.h new file mode 100644 index 0000000000000..635a83914273b --- /dev/null +++ b/include/uapi/linux/xfs.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ + +#ifndef _UAPI_LINUX_XFS_H +#define _UAPI_LINUX_XFS_H + +#include <linux/types.h> + +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 */