On 9/18/23 22:13, kernel test robot wrote:
Hi Bernd,
kernel test robot noticed the following build warnings:
[auto build test WARNING on mszeredi-fuse/for-next]
Thanks, updated patch:
---
From: Bernd Schubert <bschubert@xxxxxxx>
Subject: fuse: Remove fuse_direct_write_iter code path / use
IOCB_DIRECT
fuse_direct_write_iter is basically duplicating what is already
in fuse_cache_write_iter/generic_file_direct_write. That can be
avoided by setting IOCB_DIRECT in fuse_file_write_iter, after that
fuse_cache_write_iter can be used for the FOPEN_DIRECT_IO code path
and fuse_direct_write_iter can be removed.
Before it was using for FOPEN_DIRECT_IO
1) async (!is_sync_kiocb(iocb)) && IOCB_DIRECT
fuse_file_write_iter
fuse_direct_write_iter
fuse_direct_IO
fuse_send_dio
2) sync (is_sync_kiocb(iocb)) or IOCB_DIRECT not being set
fuse_file_write_iter
fuse_direct_write_iter
fuse_send_dio
3) FOPEN_DIRECT_IO not set
Same as the consolidates path below
The new consolidated code path is always
fuse_file_write_iter
fuse_cache_write_iter
generic_file_write_iter
__generic_file_write_iter
generic_file_direct_write
mapping->a_ops->direct_IO / fuse_direct_IO
fuse_send_dio
So in general for FOPEN_DIRECT_IO the code path gets longer. Additionally
fuse_direct_IO does an allocation of struct fuse_io_priv - might be a bit
slower in micro benchmarks.
Also, the IOCB_DIRECT information gets lost (as we now set it outselves).
But then IOCB_DIRECT is directly related to O_DIRECT set in
struct file::f_flags.
An additional change is for condition 2 above, which might will now do
async IO on the condition ff->fm->fc->async_dio. Given that async IO for
FOPEN_DIRECT_IO was especially introduced in commit
'commit 23c94e1cdcbf ("fuse: Switch to using async direct IO for
FOPEN_DIRECT_IO")'
it should not matter. Especially as fuse_direct_IO is blocking for
is_sync_kiocb(), at worst it has another slight overhead.
Advantage is the removal of code paths and conditions and it is now also
possible to remove FOPEN_DIRECT_IO conditions in fuse_send_dio
(in a later patch).
Cc: Hao Xu <howeyxu@xxxxxxxxxxx>
Cc: Miklos Szeredi <miklos@xxxxxxxxxx>
Cc: Dharmendra Singh <dsingh@xxxxxxx>
Cc: linux-fsdevel@xxxxxxxxxxxxxxx
Signed-off-by: Bernd Schubert <bschubert@xxxxxxx>
---
fs/fuse/file.c | 60 +++++++++-----------------------------------------
1 file changed, 10 insertions(+), 50 deletions(-)
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 24fa6cab836f..41e10e6f5aa4 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1061,6 +1061,12 @@ static unsigned int fuse_write_flags(struct kiocb *iocb)
if (iocb->ki_flags & IOCB_SYNC)
flags |= O_SYNC;
+ /*
+ * Note: If O_DIRECT should be ever added here,
+ * iocb->ki_flags & IOCB_DIRECT cannot be trusted when
+ * FOPEN_DIRECT_IO is set.
+ */
+
return flags;
}
@@ -1631,52 +1637,6 @@ static ssize_t fuse_direct_read_iter(struct kiocb *iocb, struct iov_iter *to)
return res;
}
-static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from)
-{
- struct inode *inode = file_inode(iocb->ki_filp);
- struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(iocb);
- ssize_t res;
- bool exclusive_lock = fuse_dio_wr_exclusive_lock(iocb, from, inode);
-
- /*
- * Take exclusive lock if
- * - Parallel direct writes are disabled - a user space decision
- * - Parallel direct writes are enabled and i_size is being extended.
- * This might not be needed at all, but needs further investigation.
- */
- if (exclusive_lock)
- inode_lock(inode);
- else {
- inode_lock_shared(inode);
-
- /* A race with truncate might have come up as the decision for
- * the lock type was done without holding the lock, check again.
- */
- if (fuse_io_past_eof(iocb, from)) {
- inode_unlock_shared(inode);
- inode_lock(inode);
- exclusive_lock = true;
- }
- }
-
- res = generic_write_checks(iocb, from);
- if (res > 0) {
- if (!is_sync_kiocb(iocb) && iocb->ki_flags & IOCB_DIRECT) {
- res = fuse_direct_IO(iocb, from);
- } else {
- res = fuse_send_dio(&io, from, &iocb->ki_pos,
- FUSE_DIO_WRITE);
- fuse_write_update_attr(inode, iocb->ki_pos, res);
- }
- }
- if (exclusive_lock)
- inode_unlock(inode);
- else
- inode_unlock_shared(inode);
-
- return res;
-}
-
static ssize_t fuse_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
struct file *file = iocb->ki_filp;
@@ -1707,10 +1667,10 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
if (FUSE_IS_DAX(inode))
return fuse_dax_write_iter(iocb, from);
- if (!(ff->open_flags & FOPEN_DIRECT_IO))
- return fuse_cache_write_iter(iocb, from);
- else
- return fuse_direct_write_iter(iocb, from);
+ if (ff->open_flags & FOPEN_DIRECT_IO)
+ iocb->ki_flags |= IOCB_DIRECT;
+
+ return fuse_cache_write_iter(iocb, from);
}
static void fuse_writepage_free(struct fuse_writepage_args *wpa)
--
2.39.2