f2fs: introduce data read/write showing path info
This was used in Android for a long time. Let's upstream it. Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
c2ca36e82f
commit
c277f1411d
|
@ -4329,17 +4329,39 @@ out:
|
||||||
static ssize_t f2fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
static ssize_t f2fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
||||||
{
|
{
|
||||||
struct inode *inode = file_inode(iocb->ki_filp);
|
struct inode *inode = file_inode(iocb->ki_filp);
|
||||||
|
const loff_t pos = iocb->ki_pos;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
if (!f2fs_is_compress_backend_ready(inode))
|
if (!f2fs_is_compress_backend_ready(inode))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (f2fs_should_use_dio(inode, iocb, to))
|
if (trace_f2fs_dataread_start_enabled()) {
|
||||||
return f2fs_dio_read_iter(iocb, to);
|
char *p = f2fs_kmalloc(F2FS_I_SB(inode), PATH_MAX, GFP_KERNEL);
|
||||||
|
char *path;
|
||||||
|
|
||||||
ret = filemap_read(iocb, to, 0);
|
if (!p)
|
||||||
if (ret > 0)
|
goto skip_read_trace;
|
||||||
f2fs_update_iostat(F2FS_I_SB(inode), APP_BUFFERED_READ_IO, ret);
|
|
||||||
|
path = dentry_path_raw(file_dentry(iocb->ki_filp), p, PATH_MAX);
|
||||||
|
if (IS_ERR(path)) {
|
||||||
|
kfree(p);
|
||||||
|
goto skip_read_trace;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace_f2fs_dataread_start(inode, pos, iov_iter_count(to),
|
||||||
|
current->pid, path, current->comm);
|
||||||
|
kfree(p);
|
||||||
|
}
|
||||||
|
skip_read_trace:
|
||||||
|
if (f2fs_should_use_dio(inode, iocb, to)) {
|
||||||
|
ret = f2fs_dio_read_iter(iocb, to);
|
||||||
|
} else {
|
||||||
|
ret = filemap_read(iocb, to, 0);
|
||||||
|
if (ret > 0)
|
||||||
|
f2fs_update_iostat(F2FS_I_SB(inode), APP_BUFFERED_READ_IO, ret);
|
||||||
|
}
|
||||||
|
if (trace_f2fs_dataread_end_enabled())
|
||||||
|
trace_f2fs_dataread_end(inode, pos, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4631,14 +4653,36 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||||
/* Possibly preallocate the blocks for the write. */
|
/* Possibly preallocate the blocks for the write. */
|
||||||
target_size = iocb->ki_pos + iov_iter_count(from);
|
target_size = iocb->ki_pos + iov_iter_count(from);
|
||||||
preallocated = f2fs_preallocate_blocks(iocb, from, dio);
|
preallocated = f2fs_preallocate_blocks(iocb, from, dio);
|
||||||
if (preallocated < 0)
|
if (preallocated < 0) {
|
||||||
ret = preallocated;
|
ret = preallocated;
|
||||||
else
|
} else {
|
||||||
|
if (trace_f2fs_datawrite_start_enabled()) {
|
||||||
|
char *p = f2fs_kmalloc(F2FS_I_SB(inode),
|
||||||
|
PATH_MAX, GFP_KERNEL);
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
if (!p)
|
||||||
|
goto skip_write_trace;
|
||||||
|
path = dentry_path_raw(file_dentry(iocb->ki_filp),
|
||||||
|
p, PATH_MAX);
|
||||||
|
if (IS_ERR(path)) {
|
||||||
|
kfree(p);
|
||||||
|
goto skip_write_trace;
|
||||||
|
}
|
||||||
|
trace_f2fs_datawrite_start(inode, orig_pos, orig_count,
|
||||||
|
current->pid, path, current->comm);
|
||||||
|
kfree(p);
|
||||||
|
}
|
||||||
|
skip_write_trace:
|
||||||
/* Do the actual write. */
|
/* Do the actual write. */
|
||||||
ret = dio ?
|
ret = dio ?
|
||||||
f2fs_dio_write_iter(iocb, from, &may_need_sync):
|
f2fs_dio_write_iter(iocb, from, &may_need_sync):
|
||||||
f2fs_buffered_write_iter(iocb, from);
|
f2fs_buffered_write_iter(iocb, from);
|
||||||
|
|
||||||
|
if (trace_f2fs_datawrite_end_enabled())
|
||||||
|
trace_f2fs_datawrite_end(inode, orig_pos, ret);
|
||||||
|
}
|
||||||
|
|
||||||
/* Don't leave any preallocated blocks around past i_size. */
|
/* Don't leave any preallocated blocks around past i_size. */
|
||||||
if (preallocated && i_size_read(inode) < target_size) {
|
if (preallocated && i_size_read(inode) < target_size) {
|
||||||
f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||||
|
|
|
@ -2067,6 +2067,100 @@ TRACE_EVENT(f2fs_fiemap,
|
||||||
__entry->ret)
|
__entry->ret)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
DECLARE_EVENT_CLASS(f2fs__rw_start,
|
||||||
|
|
||||||
|
TP_PROTO(struct inode *inode, loff_t offset, int bytes,
|
||||||
|
pid_t pid, char *pathname, char *command),
|
||||||
|
|
||||||
|
TP_ARGS(inode, offset, bytes, pid, pathname, command),
|
||||||
|
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__string(pathbuf, pathname)
|
||||||
|
__field(loff_t, offset)
|
||||||
|
__field(int, bytes)
|
||||||
|
__field(loff_t, i_size)
|
||||||
|
__string(cmdline, command)
|
||||||
|
__field(pid_t, pid)
|
||||||
|
__field(ino_t, ino)
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_fast_assign(
|
||||||
|
/*
|
||||||
|
* Replace the spaces in filenames and cmdlines
|
||||||
|
* because this screws up the tooling that parses
|
||||||
|
* the traces.
|
||||||
|
*/
|
||||||
|
__assign_str(pathbuf, pathname);
|
||||||
|
(void)strreplace(__get_str(pathbuf), ' ', '_');
|
||||||
|
__entry->offset = offset;
|
||||||
|
__entry->bytes = bytes;
|
||||||
|
__entry->i_size = i_size_read(inode);
|
||||||
|
__assign_str(cmdline, command);
|
||||||
|
(void)strreplace(__get_str(cmdline), ' ', '_');
|
||||||
|
__entry->pid = pid;
|
||||||
|
__entry->ino = inode->i_ino;
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_printk("entry_name %s, offset %llu, bytes %d, cmdline %s,"
|
||||||
|
" pid %d, i_size %llu, ino %lu",
|
||||||
|
__get_str(pathbuf), __entry->offset, __entry->bytes,
|
||||||
|
__get_str(cmdline), __entry->pid, __entry->i_size,
|
||||||
|
(unsigned long) __entry->ino)
|
||||||
|
);
|
||||||
|
|
||||||
|
DECLARE_EVENT_CLASS(f2fs__rw_end,
|
||||||
|
|
||||||
|
TP_PROTO(struct inode *inode, loff_t offset, int bytes),
|
||||||
|
|
||||||
|
TP_ARGS(inode, offset, bytes),
|
||||||
|
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__field(ino_t, ino)
|
||||||
|
__field(loff_t, offset)
|
||||||
|
__field(int, bytes)
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_fast_assign(
|
||||||
|
__entry->ino = inode->i_ino;
|
||||||
|
__entry->offset = offset;
|
||||||
|
__entry->bytes = bytes;
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_printk("ino %lu, offset %llu, bytes %d",
|
||||||
|
(unsigned long) __entry->ino,
|
||||||
|
__entry->offset, __entry->bytes)
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_EVENT(f2fs__rw_start, f2fs_dataread_start,
|
||||||
|
|
||||||
|
TP_PROTO(struct inode *inode, loff_t offset, int bytes,
|
||||||
|
pid_t pid, char *pathname, char *command),
|
||||||
|
|
||||||
|
TP_ARGS(inode, offset, bytes, pid, pathname, command)
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_EVENT(f2fs__rw_end, f2fs_dataread_end,
|
||||||
|
|
||||||
|
TP_PROTO(struct inode *inode, loff_t offset, int bytes),
|
||||||
|
|
||||||
|
TP_ARGS(inode, offset, bytes)
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_EVENT(f2fs__rw_start, f2fs_datawrite_start,
|
||||||
|
|
||||||
|
TP_PROTO(struct inode *inode, loff_t offset, int bytes,
|
||||||
|
pid_t pid, char *pathname, char *command),
|
||||||
|
|
||||||
|
TP_ARGS(inode, offset, bytes, pid, pathname, command)
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_EVENT(f2fs__rw_end, f2fs_datawrite_end,
|
||||||
|
|
||||||
|
TP_PROTO(struct inode *inode, loff_t offset, int bytes),
|
||||||
|
|
||||||
|
TP_ARGS(inode, offset, bytes)
|
||||||
|
);
|
||||||
|
|
||||||
#endif /* _TRACE_F2FS_H */
|
#endif /* _TRACE_F2FS_H */
|
||||||
|
|
||||||
/* This part must be outside protection */
|
/* This part must be outside protection */
|
||||||
|
|
Loading…
Reference in New Issue