diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 30d49467578e..abdff1a0ae92 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -3035,15 +3035,21 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) struct inode *inode = file_inode(file); ssize_t ret; - if (unlikely(f2fs_cp_error(F2FS_I_SB(inode)))) - return -EIO; + if (unlikely(f2fs_cp_error(F2FS_I_SB(inode)))) { + ret = -EIO; + goto out; + } - if ((iocb->ki_flags & IOCB_NOWAIT) && !(iocb->ki_flags & IOCB_DIRECT)) - return -EINVAL; + if ((iocb->ki_flags & IOCB_NOWAIT) && !(iocb->ki_flags & IOCB_DIRECT)) { + ret = -EINVAL; + goto out; + } if (!inode_trylock(inode)) { - if (iocb->ki_flags & IOCB_NOWAIT) - return -EAGAIN; + if (iocb->ki_flags & IOCB_NOWAIT) { + ret = -EAGAIN; + goto out; + } inode_lock(inode); } @@ -3066,7 +3072,8 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) clear_inode_flag(inode, FI_NO_PREALLOC); inode_unlock(inode); - return -EAGAIN; + ret = -EAGAIN; + goto out; } } else { @@ -3077,7 +3084,8 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) if (err) { clear_inode_flag(inode, FI_NO_PREALLOC); inode_unlock(inode); - return err; + ret = err; + goto out; } } ret = __generic_file_write_iter(iocb, from); @@ -3091,7 +3099,9 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) f2fs_update_iostat(F2FS_I_SB(inode), APP_WRITE_IO, ret); } inode_unlock(inode); - +out: + trace_f2fs_file_write_iter(inode, iocb->ki_pos, + iov_iter_count(from), ret); if (ret > 0) ret = generic_write_sync(iocb, ret); return ret; diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index a3916b4dd57e..353a6fff2b80 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h @@ -533,6 +533,37 @@ TRACE_EVENT(f2fs_truncate_partial_nodes, __entry->err) ); +TRACE_EVENT(f2fs_file_write_iter, + + TP_PROTO(struct inode *inode, unsigned long offset, + unsigned long length, int ret), + + TP_ARGS(inode, offset, length, ret), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(ino_t, ino) + __field(unsigned long, offset) + __field(unsigned long, length) + __field(int, ret) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->offset = offset; + __entry->length = length; + __entry->ret = ret; + ), + + TP_printk("dev = (%d,%d), ino = %lu, " + "offset = %lu, length = %lu, written(err) = %d", + show_dev_ino(__entry), + __entry->offset, + __entry->length, + __entry->ret) +); + TRACE_EVENT(f2fs_map_blocks, TP_PROTO(struct inode *inode, struct f2fs_map_blocks *map, int ret),