From: Goldwyn Rodrigues <rgoldwyn@suse.de>
To: darrick.wong@oracle.com
Cc: linux-btrfs@vger.kernel.org, fdmanana@gmail.com,
linux-fsdevel@vger.kernel.org, hch@lst.de,
Goldwyn Rodrigues <rgoldwyn@suse.com>
Subject: [PATCH 3/3] xfs: fallback to buffered I/O if direct I/O is short
Date: Fri, 5 Jun 2020 15:48:38 -0500 [thread overview]
Message-ID: <20200605204838.10765-4-rgoldwyn@suse.de> (raw)
In-Reply-To: <20200605204838.10765-1-rgoldwyn@suse.de>
From: Goldwyn Rodrigues <rgoldwyn@suse.com>
Most filesystems such as ext4 and btrfs fallback to buffered I/O in case
direct write's fail. In case direct I/O is short, fallback to buffered
write to complete the I/O. Make sure the data is on disk by performing a
filemap_write_and_wait_range() and invalidating the pages in the range.
For reads, call xfs_file_buffered_aio_read() in case of short I/O.
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
---
fs/xfs/xfs_file.c | 41 ++++++++++++++++++++++++++++++++++-------
1 file changed, 34 insertions(+), 7 deletions(-)
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 4b8bdecc3863..786391228dea 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -31,6 +31,10 @@
#include <linux/fadvise.h>
static const struct vm_operations_struct xfs_file_vm_ops;
+STATIC ssize_t xfs_file_buffered_aio_write(struct kiocb *iocb,
+ struct iov_iter *from);
+STATIC ssize_t xfs_file_buffered_aio_read(struct kiocb *iocb,
+ struct iov_iter *to);
int
xfs_update_prealloc_flags(
@@ -169,6 +173,7 @@ xfs_file_dio_aio_read(
struct xfs_inode *ip = XFS_I(file_inode(iocb->ki_filp));
size_t count = iov_iter_count(to);
ssize_t ret;
+ ssize_t buffered_read = 0;
trace_xfs_file_direct_read(ip, count, iocb->ki_pos);
@@ -187,7 +192,13 @@ xfs_file_dio_aio_read(
is_sync_kiocb(iocb));
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
- return ret;
+ if (ret < 0 || ret == count)
+ return ret;
+
+ iocb->ki_flags &= ~IOCB_DIRECT;
+ buffered_read = xfs_file_buffered_aio_read(iocb, to);
+
+ return ret + buffered_read;
}
static noinline ssize_t
@@ -483,6 +494,9 @@ xfs_file_dio_aio_write(
int iolock;
size_t count = iov_iter_count(from);
struct xfs_buftarg *target = xfs_inode_buftarg(ip);
+ loff_t offset, end;
+ ssize_t buffered_write = 0;
+ int err;
/* DIO must be aligned to device logical sector size */
if ((iocb->ki_pos | count) & target->bt_logical_sectormask)
@@ -552,12 +566,25 @@ xfs_file_dio_aio_write(
out:
xfs_iunlock(ip, iolock);
- /*
- * No fallback to buffered IO on errors for XFS, direct IO will either
- * complete fully or fail.
- */
- ASSERT(ret < 0 || ret == count);
- return ret;
+ if (ret < 0 || ret == count)
+ return ret;
+
+ /* Fallback to buffered write */
+
+ offset = iocb->ki_pos;
+
+ buffered_write = xfs_file_buffered_aio_write(iocb, from);
+ if (buffered_write < 0)
+ return ret;
+
+ end = offset + buffered_write - 1;
+
+ err = filemap_write_and_wait_range(mapping, offset, end);
+ if (!err)
+ invalidate_mapping_pages(mapping, offset >> PAGE_SHIFT,
+ end >> PAGE_SHIFT);
+
+ return ret + buffered_write;
}
static noinline ssize_t
--
2.25.0
next prev parent reply other threads:[~2020-06-05 20:48 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-05 20:48 [PATCH 0/3] Transient errors in Direct I/O Goldwyn Rodrigues
2020-06-05 20:48 ` [PATCH 1/3] iomap: dio Return zero in case of unsuccessful pagecache invalidation Goldwyn Rodrigues
2020-06-06 3:13 ` Matthew Wilcox
2020-06-05 20:48 ` [PATCH 2/3] btrfs: Wait for extent bits to release page Goldwyn Rodrigues
2020-06-08 10:20 ` Filipe Manana
2020-06-08 12:13 ` Goldwyn Rodrigues
2020-06-05 20:48 ` Goldwyn Rodrigues [this message]
2020-06-10 2:59 ` [PATCH 0/3] Transient errors in Direct I/O Dave Chinner
2020-06-10 5:05 ` Dave Chinner
2020-06-11 14:13 ` Goldwyn Rodrigues
2020-06-10 5:31 ` Qu Wenruo
2020-06-11 14:11 ` Goldwyn Rodrigues
2020-06-12 12:56 ` Qu Wenruo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200605204838.10765-4-rgoldwyn@suse.de \
--to=rgoldwyn@suse.de \
--cc=darrick.wong@oracle.com \
--cc=fdmanana@gmail.com \
--cc=hch@lst.de \
--cc=linux-btrfs@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=rgoldwyn@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).