All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] block: fix DIO handling regressions in blkdev_read_iter()
@ 2022-02-01 10:04 Ilya Dryomov
  2022-02-02 14:12 ` Christoph Hellwig
  2022-02-02 14:48 ` Jens Axboe
  0 siblings, 2 replies; 3+ messages in thread
From: Ilya Dryomov @ 2022-02-01 10:04 UTC (permalink / raw)
  To: linux-block; +Cc: Jens Axboe, Christoph Hellwig, Pavel Begunkov

Commit ceaa762527f4 ("block: move direct_IO into our own read_iter
handler") introduced several regressions for bdev DIO:

1. read spanning EOF always returns 0 instead of the number of bytes
   read.  This is because "count" is assigned early and isn't updated
   when the iterator is truncated:

     $ lsblk -o name,size /dev/vdb
     NAME SIZE
     vdb    1G
     $ xfs_io -d -c 'pread -b 4M 1021M 4M' /dev/vdb
     read 0/4194304 bytes at offset 1070596096
     0.000000 bytes, 0 ops; 0.0007 sec (0.000000 bytes/sec and 0.0000 ops/sec)

     instead of

     $ xfs_io -d -c 'pread -b 4M 1021M 4M' /dev/vdb
     read 3145728/4194304 bytes at offset 1070596096
     3 MiB, 1 ops; 0.0007 sec (3.865 GiB/sec and 1319.2612 ops/sec)

2. truncated iterator isn't reexpanded
3. iterator isn't reverted on blkdev_direct_IO() error
4. zero size read no longer skips atime update

Fixes: ceaa762527f4 ("block: move direct_IO into our own read_iter handler")
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
 block/fops.c | 33 +++++++++++++++++++--------------
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/block/fops.c b/block/fops.c
index 26bf15c770d2..4f59e0f5bf30 100644
--- a/block/fops.c
+++ b/block/fops.c
@@ -566,34 +566,37 @@ static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
 	struct block_device *bdev = iocb->ki_filp->private_data;
 	loff_t size = bdev_nr_bytes(bdev);
-	size_t count = iov_iter_count(to);
 	loff_t pos = iocb->ki_pos;
 	size_t shorted = 0;
 	ssize_t ret = 0;
+	size_t count;
 
-	if (unlikely(pos + count > size)) {
+	if (unlikely(pos + iov_iter_count(to) > size)) {
 		if (pos >= size)
 			return 0;
 		size -= pos;
-		if (count > size) {
-			shorted = count - size;
-			iov_iter_truncate(to, size);
-		}
+		shorted = iov_iter_count(to) - size;
+		iov_iter_truncate(to, size);
 	}
 
+	count = iov_iter_count(to);
+	if (!count)
+		goto reexpand; /* skip atime */
+
 	if (iocb->ki_flags & IOCB_DIRECT) {
 		struct address_space *mapping = iocb->ki_filp->f_mapping;
 
 		if (iocb->ki_flags & IOCB_NOWAIT) {
-			if (filemap_range_needs_writeback(mapping, iocb->ki_pos,
-						iocb->ki_pos + count - 1))
-				return -EAGAIN;
+			if (filemap_range_needs_writeback(mapping, pos,
+							  pos + count - 1)) {
+				ret = -EAGAIN;
+				goto reexpand;
+			}
 		} else {
-			ret = filemap_write_and_wait_range(mapping,
-						iocb->ki_pos,
-					        iocb->ki_pos + count - 1);
+			ret = filemap_write_and_wait_range(mapping, pos,
+							   pos + count - 1);
 			if (ret < 0)
-				return ret;
+				goto reexpand;
 		}
 
 		file_accessed(iocb->ki_filp);
@@ -603,12 +606,14 @@ static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to)
 			iocb->ki_pos += ret;
 			count -= ret;
 		}
+		iov_iter_revert(to, count - iov_iter_count(to));
 		if (ret < 0 || !count)
-			return ret;
+			goto reexpand;
 	}
 
 	ret = filemap_read(iocb, to, ret);
 
+reexpand:
 	if (unlikely(shorted))
 		iov_iter_reexpand(to, iov_iter_count(to) + shorted);
 	return ret;
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] block: fix DIO handling regressions in blkdev_read_iter()
  2022-02-01 10:04 [PATCH] block: fix DIO handling regressions in blkdev_read_iter() Ilya Dryomov
@ 2022-02-02 14:12 ` Christoph Hellwig
  2022-02-02 14:48 ` Jens Axboe
  1 sibling, 0 replies; 3+ messages in thread
From: Christoph Hellwig @ 2022-02-02 14:12 UTC (permalink / raw)
  To: Ilya Dryomov; +Cc: linux-block, Jens Axboe, Christoph Hellwig, Pavel Begunkov

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] block: fix DIO handling regressions in blkdev_read_iter()
  2022-02-01 10:04 [PATCH] block: fix DIO handling regressions in blkdev_read_iter() Ilya Dryomov
  2022-02-02 14:12 ` Christoph Hellwig
@ 2022-02-02 14:48 ` Jens Axboe
  1 sibling, 0 replies; 3+ messages in thread
From: Jens Axboe @ 2022-02-02 14:48 UTC (permalink / raw)
  To: Ilya Dryomov, linux-block; +Cc: Pavel Begunkov, Christoph Hellwig

On Tue, 1 Feb 2022 11:04:20 +0100, Ilya Dryomov wrote:
> Commit ceaa762527f4 ("block: move direct_IO into our own read_iter
> handler") introduced several regressions for bdev DIO:
> 
> 1. read spanning EOF always returns 0 instead of the number of bytes
>    read.  This is because "count" is assigned early and isn't updated
>    when the iterator is truncated:
> 
> [...]

Applied, thanks!

[1/1] block: fix DIO handling regressions in blkdev_read_iter()
      commit: 3e1f941dd9f33776b3df4e30f741fe445ff773f3

Best regards,
-- 
Jens Axboe



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-02-02 14:48 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-01 10:04 [PATCH] block: fix DIO handling regressions in blkdev_read_iter() Ilya Dryomov
2022-02-02 14:12 ` Christoph Hellwig
2022-02-02 14:48 ` Jens Axboe

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.