Commit bedf1495 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'iomap-6.4-merge-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull iomap updates from Darrick Wong:
 "The only changes for this cycle are the addition of tracepoints to the
  iomap directio code so that Ritesh (who is working on porting ext2 to
  iomap) can observe the io flows more easily.

  Summary:

   - Remove an unused symbol

   - Add tracepoints for the directio code"

* tag 'iomap-6.4-merge-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
  iomap: Add DIO tracepoints
  iomap: Remove IOMAP_DIO_NOSYNC unused dio flag
  fs.h: Add TRACE_IOCB_STRINGS for use in trace points
parents b28e6315 3fd41721
......@@ -130,6 +130,7 @@ ssize_t iomap_dio_complete(struct iomap_dio *dio)
if (ret > 0)
ret += dio->done_before;
trace_iomap_dio_complete(iocb, dio->error, ret);
kfree(dio);
return ret;
......@@ -493,6 +494,8 @@ __iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
struct blk_plug plug;
struct iomap_dio *dio;
trace_iomap_dio_rw_begin(iocb, iter, dio_flags, done_before);
if (!iomi.len)
return NULL;
......@@ -541,7 +544,7 @@ __iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
}
/* for data sync or sync, we need sync completion processing */
if (iocb_is_dsync(iocb) && !(dio_flags & IOMAP_DIO_NOSYNC)) {
if (iocb_is_dsync(iocb)) {
dio->flags |= IOMAP_DIO_NEED_SYNC;
/*
......@@ -650,8 +653,10 @@ __iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
*/
dio->wait_for_completion = wait_for_completion;
if (!atomic_dec_and_test(&dio->ref)) {
if (!wait_for_completion)
if (!wait_for_completion) {
trace_iomap_dio_rw_queued(inode, iomi.pos, iomi.len);
return ERR_PTR(-EIOCBQUEUED);
}
for (;;) {
set_current_state(TASK_UNINTERRUPTIBLE);
......
......@@ -3,6 +3,7 @@
* Copyright (c) 2019 Christoph Hellwig
*/
#include <linux/iomap.h>
#include <linux/uio.h>
/*
* We include this last to have the helpers above available for the trace
......
......@@ -83,6 +83,7 @@ DEFINE_RANGE_EVENT(iomap_writepage);
DEFINE_RANGE_EVENT(iomap_release_folio);
DEFINE_RANGE_EVENT(iomap_invalidate_folio);
DEFINE_RANGE_EVENT(iomap_dio_invalidate_fail);
DEFINE_RANGE_EVENT(iomap_dio_rw_queued);
#define IOMAP_TYPE_STRINGS \
{ IOMAP_HOLE, "HOLE" }, \
......@@ -107,6 +108,11 @@ DEFINE_RANGE_EVENT(iomap_dio_invalidate_fail);
{ IOMAP_F_BUFFER_HEAD, "BH" }, \
{ IOMAP_F_SIZE_CHANGED, "SIZE_CHANGED" }
#define IOMAP_DIO_STRINGS \
{IOMAP_DIO_FORCE_WAIT, "DIO_FORCE_WAIT" }, \
{IOMAP_DIO_OVERWRITE_ONLY, "DIO_OVERWRITE_ONLY" }, \
{IOMAP_DIO_PARTIAL, "DIO_PARTIAL" }
DECLARE_EVENT_CLASS(iomap_class,
TP_PROTO(struct inode *inode, struct iomap *iomap),
TP_ARGS(inode, iomap),
......@@ -183,6 +189,78 @@ TRACE_EVENT(iomap_iter,
(void *)__entry->caller)
);
TRACE_EVENT(iomap_dio_rw_begin,
TP_PROTO(struct kiocb *iocb, struct iov_iter *iter,
unsigned int dio_flags, size_t done_before),
TP_ARGS(iocb, iter, dio_flags, done_before),
TP_STRUCT__entry(
__field(dev_t, dev)
__field(ino_t, ino)
__field(loff_t, isize)
__field(loff_t, pos)
__field(size_t, count)
__field(size_t, done_before)
__field(int, ki_flags)
__field(unsigned int, dio_flags)
__field(bool, aio)
),
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->done_before = done_before;
__entry->ki_flags = iocb->ki_flags;
__entry->dio_flags = dio_flags;
__entry->aio = !is_sync_kiocb(iocb);
),
TP_printk("dev %d:%d ino 0x%lx size 0x%llx offset 0x%llx length 0x%zx done_before 0x%zx flags %s dio_flags %s aio %d",
MAJOR(__entry->dev), MINOR(__entry->dev),
__entry->ino,
__entry->isize,
__entry->pos,
__entry->count,
__entry->done_before,
__print_flags(__entry->ki_flags, "|", TRACE_IOCB_STRINGS),
__print_flags(__entry->dio_flags, "|", IOMAP_DIO_STRINGS),
__entry->aio)
);
TRACE_EVENT(iomap_dio_complete,
TP_PROTO(struct kiocb *iocb, int error, ssize_t ret),
TP_ARGS(iocb, error, ret),
TP_STRUCT__entry(
__field(dev_t, dev)
__field(ino_t, ino)
__field(loff_t, isize)
__field(loff_t, pos)
__field(int, ki_flags)
__field(bool, aio)
__field(int, error)
__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->ki_flags = iocb->ki_flags;
__entry->aio = !is_sync_kiocb(iocb);
__entry->error = error;
__entry->ret = ret;
),
TP_printk("dev %d:%d ino 0x%lx size 0x%llx offset 0x%llx flags %s aio %d error %d ret %zd",
MAJOR(__entry->dev), MINOR(__entry->dev),
__entry->ino,
__entry->isize,
__entry->pos,
__print_flags(__entry->ki_flags, "|", TRACE_IOCB_STRINGS),
__entry->aio,
__entry->error,
__entry->ret)
);
#endif /* _IOMAP_TRACE_H */
#undef TRACE_INCLUDE_PATH
......
......@@ -343,6 +343,20 @@ enum rw_hint {
/* can use bio alloc cache */
#define IOCB_ALLOC_CACHE (1 << 21)
/* for use in trace events */
#define TRACE_IOCB_STRINGS \
{ IOCB_HIPRI, "HIPRI" }, \
{ IOCB_DSYNC, "DSYNC" }, \
{ IOCB_SYNC, "SYNC" }, \
{ IOCB_NOWAIT, "NOWAIT" }, \
{ IOCB_APPEND, "APPEND" }, \
{ IOCB_EVENTFD, "EVENTFD"}, \
{ IOCB_DIRECT, "DIRECT" }, \
{ IOCB_WRITE, "WRITE" }, \
{ IOCB_WAITQ, "WAITQ" }, \
{ IOCB_NOIO, "NOIO" }, \
{ IOCB_ALLOC_CACHE, "ALLOC_CACHE" }
struct kiocb {
struct file *ki_filp;
loff_t ki_pos;
......
......@@ -377,12 +377,6 @@ struct iomap_dio_ops {
*/
#define IOMAP_DIO_PARTIAL (1 << 2)
/*
* The caller will sync the write if needed; do not sync it within
* iomap_dio_rw. Overrides IOMAP_DIO_FORCE_WAIT.
*/
#define IOMAP_DIO_NOSYNC (1 << 3)
ssize_t iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
const struct iomap_ops *ops, const struct iomap_dio_ops *dops,
unsigned int dio_flags, void *private, size_t done_before);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment