diff options
| -rw-r--r-- | fs/ext2/Makefile | 5 | ||||
| -rw-r--r-- | fs/ext2/file.c | 10 | ||||
| -rw-r--r-- | fs/ext2/trace.c | 6 | ||||
| -rw-r--r-- | fs/ext2/trace.h | 94 | 
4 files changed, 113 insertions, 2 deletions
diff --git a/fs/ext2/Makefile b/fs/ext2/Makefile index 311479d864a7..8860948ef9ca 100644 --- a/fs/ext2/Makefile +++ b/fs/ext2/Makefile @@ -6,7 +6,10 @@  obj-$(CONFIG_EXT2_FS) += ext2.o  ext2-y := balloc.o dir.o file.o ialloc.o inode.o \ -	  ioctl.o namei.o super.o symlink.o +	  ioctl.o namei.o super.o symlink.o trace.o + +# For tracepoints to include our trace.h from tracepoint infrastructure +CFLAGS_trace.o := -I$(src)  ext2-$(CONFIG_EXT2_FS_XATTR)	 += xattr.o xattr_user.o xattr_trusted.o  ext2-$(CONFIG_EXT2_FS_POSIX_ACL) += acl.o diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 98add36c1a59..7a32f202908e 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -29,6 +29,7 @@  #include "ext2.h"  #include "xattr.h"  #include "acl.h" +#include "trace.h"  #ifdef CONFIG_FS_DAX  static ssize_t ext2_dax_read_iter(struct kiocb *iocb, struct iov_iter *to) @@ -168,9 +169,11 @@ static ssize_t ext2_dio_read_iter(struct kiocb *iocb, struct iov_iter *to)  	struct inode *inode = file->f_mapping->host;  	ssize_t ret; +	trace_ext2_dio_read_begin(iocb, to, 0);  	inode_lock_shared(inode);  	ret = iomap_dio_rw(iocb, to, &ext2_iomap_ops, NULL, 0, NULL, 0);  	inode_unlock_shared(inode); +	trace_ext2_dio_read_end(iocb, to, ret);  	return ret;  } @@ -198,6 +201,7 @@ static int ext2_dio_write_end_io(struct kiocb *iocb, ssize_t size,  		mark_inode_dirty(inode);  	}  out: +	trace_ext2_dio_write_endio(iocb, size, error);  	return error;  } @@ -214,7 +218,9 @@ static ssize_t ext2_dio_write_iter(struct kiocb *iocb, struct iov_iter *from)  	unsigned long blocksize = inode->i_sb->s_blocksize;  	loff_t offset = iocb->ki_pos;  	loff_t count = iov_iter_count(from); +	ssize_t status = 0; +	trace_ext2_dio_write_begin(iocb, from, 0);  	inode_lock(inode);  	ret = generic_write_checks(iocb, from);  	if (ret <= 0) @@ -242,7 +248,6 @@ static ssize_t ext2_dio_write_iter(struct kiocb *iocb, struct iov_iter *from)  	/* handle case for partial write and for fallback to buffered write */  	if (ret >= 0 && iov_iter_count(from)) {  		loff_t pos, endbyte; -		ssize_t status;  		int ret2;  		iocb->ki_flags &= ~IOCB_DIRECT; @@ -268,6 +273,9 @@ static ssize_t ext2_dio_write_iter(struct kiocb *iocb, struct iov_iter *from)  out_unlock:  	inode_unlock(inode); +	if (status) +		trace_ext2_dio_write_buff_end(iocb, from, status); +	trace_ext2_dio_write_end(iocb, from, ret);  	return ret;  } diff --git a/fs/ext2/trace.c b/fs/ext2/trace.c new file mode 100644 index 000000000000..b01cdf6526fd --- /dev/null +++ b/fs/ext2/trace.c @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "ext2.h" +#include <linux/uio.h> + +#define CREATE_TRACE_POINTS +#include "trace.h" diff --git a/fs/ext2/trace.h b/fs/ext2/trace.h new file mode 100644 index 000000000000..7d230e13576e --- /dev/null +++ b/fs/ext2/trace.h @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0 + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM ext2 + +#if !defined(_EXT2_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _EXT2_TRACE_H + +#include <linux/tracepoint.h> + +DECLARE_EVENT_CLASS(ext2_dio_class, +	TP_PROTO(struct kiocb *iocb, struct iov_iter *iter, ssize_t ret), +	TP_ARGS(iocb, iter, ret), +	TP_STRUCT__entry( +		__field(dev_t,	dev) +		__field(ino_t,	ino) +		__field(loff_t, isize) +		__field(loff_t, pos) +		__field(size_t,	count) +		__field(int,	ki_flags) +		__field(bool,	aio) +		__field(ssize_t, ret) +	), +	TP_fast_assign( +		__entry->dev = file_inode(iocb->ki_filp)->i_sb->s_dev; +		__entry->ino = file_inode(iocb->ki_filp)->i_ino; +		__entry->isize = file_inode(iocb->ki_filp)->i_size; +		__entry->pos = iocb->ki_pos; +		__entry->count = iov_iter_count(iter); +		__entry->ki_flags = iocb->ki_flags; +		__entry->aio = !is_sync_kiocb(iocb); +		__entry->ret = ret; +	), +	TP_printk("dev %d:%d ino 0x%lx isize 0x%llx pos 0x%llx len %zu flags %s aio %d ret %zd", +		  MAJOR(__entry->dev), MINOR(__entry->dev), +		  __entry->ino, +		  __entry->isize, +		  __entry->pos, +		  __entry->count, +		  __print_flags(__entry->ki_flags, "|", TRACE_IOCB_STRINGS), +		  __entry->aio, +		  __entry->ret) +); + +#define DEFINE_DIO_RW_EVENT(name)					  \ +DEFINE_EVENT(ext2_dio_class, name,					  \ +	TP_PROTO(struct kiocb *iocb, struct iov_iter *iter, ssize_t ret), \ +	TP_ARGS(iocb, iter, ret)) +DEFINE_DIO_RW_EVENT(ext2_dio_write_begin); +DEFINE_DIO_RW_EVENT(ext2_dio_write_end); +DEFINE_DIO_RW_EVENT(ext2_dio_write_buff_end); +DEFINE_DIO_RW_EVENT(ext2_dio_read_begin); +DEFINE_DIO_RW_EVENT(ext2_dio_read_end); + +TRACE_EVENT(ext2_dio_write_endio, +	TP_PROTO(struct kiocb *iocb, ssize_t size, int ret), +	TP_ARGS(iocb, size, ret), +	TP_STRUCT__entry( +		__field(dev_t,	dev) +		__field(ino_t,	ino) +		__field(loff_t, isize) +		__field(loff_t, pos) +		__field(ssize_t, size) +		__field(int,	ki_flags) +		__field(bool,	aio) +		__field(int,	ret) +	), +	TP_fast_assign( +		__entry->dev = file_inode(iocb->ki_filp)->i_sb->s_dev; +		__entry->ino = file_inode(iocb->ki_filp)->i_ino; +		__entry->isize = file_inode(iocb->ki_filp)->i_size; +		__entry->pos = iocb->ki_pos; +		__entry->size = size; +		__entry->ki_flags = iocb->ki_flags; +		__entry->aio = !is_sync_kiocb(iocb); +		__entry->ret = ret; +	), +	TP_printk("dev %d:%d ino 0x%lx isize 0x%llx pos 0x%llx len %zd flags %s aio %d ret %d", +		  MAJOR(__entry->dev), MINOR(__entry->dev), +		  __entry->ino, +		  __entry->isize, +		  __entry->pos, +		  __entry->size, +		  __print_flags(__entry->ki_flags, "|", TRACE_IOCB_STRINGS), +		  __entry->aio, +		  __entry->ret) +); + +#endif /* _EXT2_TRACE_H */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE trace +#include <trace/define_trace.h>  | 
