From 240d0f2c96d81d9ef68c640b53f0b987d9e0333e Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 8 Oct 2019 15:57:11 +0200 Subject: [PATCH 1/2] iomap: Allow forcing of waiting for running DIO in iomap_dio_rw() Filesystems do not support doing IO and asynchronous in some cases. For example in case of unaligned writes or in case file size needs to be extended (e.g. for ext4). Instead of forcing filesystem to wait for AIO in such cases, provide iomap_dio_rw_wait() which does the waiting for IO and also executes iomap_dio_complete() inline providing its return value to the caller. Signed-off-by: Jan Kara --- fs/iomap/direct-io.c | 8 ++++---- include/linux/iomap.h | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c index 1fc28c2da279..12a806ed61fa 100644 --- a/fs/iomap/direct-io.c +++ b/fs/iomap/direct-io.c @@ -391,8 +391,9 @@ iomap_dio_actor(struct inode *inode, loff_t pos, loff_t length, * completion. */ ssize_t -iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, - const struct iomap_ops *ops, const struct iomap_dio_ops *dops) +__iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, + const struct iomap_ops *ops, const struct iomap_dio_ops *dops, + bool wait_for_completion) { struct address_space *mapping = iocb->ki_filp->f_mapping; struct inode *inode = file_inode(iocb->ki_filp); @@ -400,7 +401,6 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, loff_t pos = iocb->ki_pos, start = pos; loff_t end = iocb->ki_pos + count - 1, ret = 0; unsigned int flags = IOMAP_DIRECT; - bool wait_for_completion = is_sync_kiocb(iocb); struct blk_plug plug; struct iomap_dio *dio; @@ -555,4 +555,4 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, kfree(dio); return ret; } -EXPORT_SYMBOL_GPL(iomap_dio_rw); +EXPORT_SYMBOL_GPL(__iomap_dio_rw); diff --git a/include/linux/iomap.h b/include/linux/iomap.h index 7aa5d6117936..5c2d3afbd9b3 100644 --- a/include/linux/iomap.h +++ b/include/linux/iomap.h @@ -194,8 +194,20 @@ struct iomap_dio_ops { unsigned flags); }; -ssize_t iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, - const struct iomap_ops *ops, const struct iomap_dio_ops *dops); +ssize_t __iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, + const struct iomap_ops *ops, const struct iomap_dio_ops *dops, + bool wait_for_completion); +static inline ssize_t iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, + const struct iomap_ops *ops, const struct iomap_dio_ops *dops) +{ + return __iomap_dio_rw(iocb, iter, ops, dops, is_sync_kiocb(iocb)); +} +static inline ssize_t iomap_dio_rw_wait(struct kiocb *iocb, + struct iov_iter *iter, const struct iomap_ops *ops, + const struct iomap_dio_ops *dops) +{ + return __iomap_dio_rw(iocb, iter, ops, dops, true); +} int iomap_dio_iopoll(struct kiocb *kiocb, bool spin); #ifdef CONFIG_SWAP -- 2.16.4