[PATCH 1/2] [RFC for fuse-next ] fuse: DIO writes always use the same code path

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



There were two code paths direct-io writes could
take. When daemon/server side did not set FOPEN_DIRECT_IO
    fuse_cache_write_iter -> direct_write_fallback
and with FOPEN_DIRECT_IO being set
    fuse_direct_write_iter

Advantage of fuse_direct_write_iter is that it has optimizations
for parallel DIO writes - it might only take a shared inode lock,
instead of the exclusive lock.

With commits b5a2a3a0b776/80e4f25262f9 the fuse_direct_write_iter
path also handles concurrent page IO (dirty flush and page release),
just the condition on fc->direct_io_relax had to be removed.

Performance wise this basically gives the same improvements as
commit 153524053bbb, just O_DIRECT is sufficient, without the need
that server side sets FOPEN_DIRECT_IO
(it has to set FOPEN_PARALLEL_DIRECT_WRITES), though.

Cc: Hao Xu <howeyxu@xxxxxxxxxxx>
Cc: Christoph Hellwig <hch@xxxxxxxxxxxxx>
Cc: Miklos Szeredi <miklos@xxxxxxxxxx>
Cc: Dharmendra Singh <dsingh@xxxxxxx>
Cc: linux-fsdevel@xxxxxxxxxxxxxxx
---
 fs/fuse/file.c | 27 +++++++++------------------
 1 file changed, 9 insertions(+), 18 deletions(-)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 1cdb6327511e..a5414f46d254 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1338,15 +1338,8 @@ static ssize_t fuse_cache_write_iter(struct kiocb *iocb, struct iov_iter *from)
 	if (err)
 		goto out;
 
-	if (iocb->ki_flags & IOCB_DIRECT) {
-		written = generic_file_direct_write(iocb, from);
-		if (written < 0 || !iov_iter_count(from))
-			goto out;
-		written = direct_write_fallback(iocb, from, written,
-				fuse_perform_write(iocb, from));
-	} else {
-		written = fuse_perform_write(iocb, from);
-	}
+	written = fuse_perform_write(iocb, from);
+
 out:
 	inode_unlock(inode);
 	if (written > 0)
@@ -1441,19 +1434,16 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
 	int err = 0;
 	struct fuse_io_args *ia;
 	unsigned int max_pages;
-	bool fopen_direct_io = ff->open_flags & FOPEN_DIRECT_IO;
 
 	max_pages = iov_iter_npages(iter, fc->max_pages);
 	ia = fuse_io_alloc(io, max_pages);
 	if (!ia)
 		return -ENOMEM;
 
-	if (fopen_direct_io && fc->direct_io_relax) {
-		res = filemap_write_and_wait_range(mapping, pos, pos + count - 1);
-		if (res) {
-			fuse_io_free(ia);
-			return res;
-		}
+	res = filemap_write_and_wait_range(mapping, pos, pos + count - 1);
+	if (res) {
+		fuse_io_free(ia);
+		return res;
 	}
 	if (!cuse && fuse_range_is_writeback(inode, idx_from, idx_to)) {
 		if (!write)
@@ -1463,7 +1453,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
 			inode_unlock(inode);
 	}
 
-	if (fopen_direct_io && write) {
+	if (write) {
 		res = invalidate_inode_pages2_range(mapping, idx_from, idx_to);
 		if (res) {
 			fuse_io_free(ia);
@@ -1646,7 +1636,8 @@ 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))
+	if (!(ff->open_flags & FOPEN_DIRECT_IO) &&
+	    !(iocb->ki_flags & IOCB_DIRECT))
 		return fuse_cache_write_iter(iocb, from);
 	else
 		return fuse_direct_write_iter(iocb, from);
-- 
2.39.2




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux