[PATCH RFC 1/2] iomap: Add a IOMAP_DIO_MAY_INLINE_COMP flag

Zhihao Cheng
2024-02-29T11:45:33Z

It will be more efficient to execute quick endio process(eg. non-sync
overwriting case) under irq process rather than starting a worker to
do it.
Add a flag to control DIO to be finished inline(under irq context), which
can be used for non-sync overwriting case.
Besides, skip invalidating pages if DIO is finished inline, which will
keep the same logic with dio_bio_end_aio in non-sync overwriting case.

Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
---
fs/iomap/direct-io.c | 10 ++++++++--
include/linux/iomap.h | 6 ++++++
2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c
index bcd3f8cf5ea4..221715b38ce2 100644
--- a/fs/iomap/direct-io.c
+++ b/fs/iomap/direct-io.c
@@ -110,7 +110,8 @@ ssize_t iomap_dio_complete(struct iomap_dio *dio)
* ->end_io() when necessary, otherwise a racing buffer read would cache
* zeros from unwritten extents.
*/
- if (!dio->error && dio->size && (dio->flags & IOMAP_DIO_WRITE))
+ if (!dio->error && dio->size && (dio->flags & IOMAP_DIO_WRITE) &&
+ !(dio->flags & IOMAP_DIO_INLINE_COMP))
kiocb_invalidate_post_direct_write(iocb, dio->size);

inode_dio_end(file_inode(iocb->ki_filp));
@@ -122,8 +123,10 @@ ssize_t iomap_dio_complete(struct iomap_dio *dio)
* If this is a DSYNC write, make sure we push it to stable
* storage now that we've written data.
*/
- if (dio->flags & IOMAP_DIO_NEED_SYNC)
+ if (dio->flags & IOMAP_DIO_NEED_SYNC) {
+ WARN_ON_ONCE(dio->flags & IOMAP_DIO_INLINE_COMP);
ret = generic_write_sync(iocb, ret);
+ }
if (ret > 0)
ret += dio->done_before;
}
@@ -628,6 +631,9 @@ __iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
*/
if (!(iocb->ki_flags & IOCB_SYNC))
dio->flags |= IOMAP_DIO_WRITE_THROUGH;
+ } else if (dio_flags & IOMAP_DIO_MAY_INLINE_COMP) {
+ /* writes could complete inline */
+ dio->flags |= IOMAP_DIO_INLINE_COMP;
}

/*
diff --git a/include/linux/iomap.h b/include/linux/iomap.h
index 96dd0acbba44..f292b10028d0 100644
--- a/include/linux/iomap.h
+++ b/include/linux/iomap.h
@@ -382,6 +382,12 @@ struct iomap_dio_ops {
*/
#define IOMAP_DIO_PARTIAL (1 << 2)

+/*
+ * DIO will be completed inline unless sync operation is needed after io is
+ * finished.
+ */
+#define IOMAP_DIO_MAY_INLINE_COMP (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);
--
2.39.2