Re: [PATCH v2] iomap: return partial I/O count on error in iomap_dio_bio_actor

Matthew Wilcox
2020-02-20T17:42:56Z

On Thu, Feb 20, 2020 at 09:23:55AM -0600, Goldwyn Rodrigues wrote:
> In case of a block device error, written parameter in iomap_end()
> is zero as opposed to the amount of submitted I/O.
> Filesystems such as btrfs need to account for the I/O in ordered
> extents, even if it resulted in an error. Having (incomplete)
> submitted bytes in written gives the filesystem the amount of data
> which has been submitted before the error occurred, and the
> filesystem code can choose how to use it.
>
> The final returned error for iomap_dio_rw() is set by
> iomap_dio_complete().
>
> Partial writes in direct I/O are considered an error. So,
> ->iomap_end() using written == 0 as error must be changed
> to written < length. In this case, ext4 is the only user.

I really had a hard time understanding this. I think what you meant
was:

Currently, I/Os that complete with an error indicate this by passing
written == 0 to the iomap_end function. However, btrfs needs to know how
many bytes were written for its own accounting. Change the convention
to pass the number of bytes which were actually written, and change the
only user to check for a short write instead of a zero length write.

> Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
> ---
> fs/ext4/inode.c | 2 +-
> fs/iomap/direct-io.c | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index e60aca791d3f..e50e7414351a 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -3475,7 +3475,7 @@ static int ext4_iomap_end(struct inode *inode, loff_t offset, loff_t length,
> * the I/O. Any blocks that may have been allocated in preparation for
> * the direct I/O will be reused during buffered I/O.
> */
> - if (flags & (IOMAP_WRITE | IOMAP_DIRECT) && written == 0)
> + if (flags & (IOMAP_WRITE | IOMAP_DIRECT) && written < length)
> return -ENOTBLK;
>
> return 0;
> diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c
> index 41c1e7c20a1f..01865db1bd09 100644
> --- a/fs/iomap/direct-io.c
> +++ b/fs/iomap/direct-io.c
> @@ -264,7 +264,7 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length,
> size_t n;
> if (dio->error) {
> iov_iter_revert(dio->submit.iter, copied);
> - copied = ret = 0;
> + ret = 0;
> goto out;
> }
>
> --
> 2.25.0
>