Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1730541

Re: iov_iter_pipe warning.

From Al Viro <viro@ZenIV.linux.org.uk>
Newsgroups linux.kernel
Subject Re: iov_iter_pipe warning.
Date 2017-09-11 22:20 +0200
Message-ID <uoDlw-87V-33@gated-at.bofh.it> (permalink)
References (5 earlier) <uojww-2ru-13@gated-at.bofh.it> <uokVz-3kc-1@gated-at.bofh.it> <uonJL-5sB-1@gated-at.bofh.it> <uoqHD-7zH-1@gated-at.bofh.it> <uoDbQ-84z-27@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


On Mon, Sep 11, 2017 at 09:07:13PM +0100, Al Viro wrote:
> Strictly speaking that behaviour doesn't violate POSIX.  It is, however,
> atrocious from the QoI standpoint, and for no good reason whatsoever.
> It's quite easy to do better, and doing so would've eliminated the problems
> in pipe-backed case as well (see below).  In addition to that, I would
> consider teaching bio_iov_iter_get_pages() to take the maximal bio size
> as an explict argument.  That would've killed the need of copying the
> iterator and calling iov_iter_advance() in iomap_dio_actor() at all.
> Anyway, the minimal candidate fix follows; it won't do anything about
> the WARN_ON() in there, seeing that those are deliberate "program is
> doing something bogus" things, but it should eliminate all crap with
> ->splice_read() misreporting the amount of data it has copied.

... and after minimal testing and fixing a braino in "found an IO error"
case, that's

diff --git a/fs/iomap.c b/fs/iomap.c
index 269b24a01f32..012e1f247e13 100644
--- a/fs/iomap.c
+++ b/fs/iomap.c
@@ -832,6 +832,7 @@ iomap_dio_actor(struct inode *inode, loff_t pos, loff_t length,
 	struct bio *bio;
 	bool need_zeroout = false;
 	int nr_pages, ret;
+	size_t copied = 0;
 
 	if ((pos | length | align) & ((1 << blkbits) - 1))
 		return -EINVAL;
@@ -843,7 +844,7 @@ iomap_dio_actor(struct inode *inode, loff_t pos, loff_t length,
 		/*FALLTHRU*/
 	case IOMAP_UNWRITTEN:
 		if (!(dio->flags & IOMAP_DIO_WRITE)) {
-			iov_iter_zero(length, dio->submit.iter);
+			length = iov_iter_zero(length, dio->submit.iter);
 			dio->size += length;
 			return length;
 		}
@@ -880,8 +881,11 @@ iomap_dio_actor(struct inode *inode, loff_t pos, loff_t length,
 	}
 
 	do {
-		if (dio->error)
+		size_t n;
+		if (dio->error) {
+			iov_iter_revert(dio->submit.iter, copied);
 			return 0;
+		}
 
 		bio = bio_alloc(GFP_KERNEL, nr_pages);
 		bio_set_dev(bio, iomap->bdev);
@@ -894,20 +898,24 @@ iomap_dio_actor(struct inode *inode, loff_t pos, loff_t length,
 		ret = bio_iov_iter_get_pages(bio, &iter);
 		if (unlikely(ret)) {
 			bio_put(bio);
-			return ret;
+			return copied ? copied : ret;
 		}
 
+		n = bio->bi_iter.bi_size;
 		if (dio->flags & IOMAP_DIO_WRITE) {
 			bio_set_op_attrs(bio, REQ_OP_WRITE, REQ_SYNC | REQ_IDLE);
-			task_io_account_write(bio->bi_iter.bi_size);
+			task_io_account_write(n);
 		} else {
 			bio_set_op_attrs(bio, REQ_OP_READ, 0);
 			if (dio->flags & IOMAP_DIO_DIRTY)
 				bio_set_pages_dirty(bio);
 		}
 
-		dio->size += bio->bi_iter.bi_size;
-		pos += bio->bi_iter.bi_size;
+		iov_iter_advance(dio->submit.iter, n);
+
+		dio->size += n;
+		pos += n;
+		copied += n;
 
 		nr_pages = iov_iter_npages(&iter, BIO_MAX_PAGES);
 
@@ -923,9 +931,7 @@ iomap_dio_actor(struct inode *inode, loff_t pos, loff_t length,
 		if (pad)
 			iomap_dio_zero(dio, iomap, pos, fs_block_size - pad);
 	}
-
-	iov_iter_advance(dio->submit.iter, length);
-	return length;
+	return copied;
 }
 
 ssize_t

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Re: iov_iter_pipe warning. Dave Chinner <david@fromorbit.com> - 2017-09-10 23:20 +0200
  Re: iov_iter_pipe warning. Al Viro <viro@ZenIV.linux.org.uk> - 2017-09-10 23:20 +0200
    Re: iov_iter_pipe warning. Dave Chinner <david@fromorbit.com> - 2017-09-11 00:10 +0200
      Re: iov_iter_pipe warning. Al Viro <viro@ZenIV.linux.org.uk> - 2017-09-11 01:10 +0200
        Re: iov_iter_pipe warning. Al Viro <viro@ZenIV.linux.org.uk> - 2017-09-11 01:20 +0200
        Re: iov_iter_pipe warning. Dave Chinner <david@fromorbit.com> - 2017-09-11 02:40 +0200
          Re: iov_iter_pipe warning. Al Viro <viro@ZenIV.linux.org.uk> - 2017-09-11 05:40 +0200
            Re: iov_iter_pipe warning. Dave Chinner <david@fromorbit.com> - 2017-09-11 08:50 +0200
              Re: iov_iter_pipe warning. Al Viro <viro@ZenIV.linux.org.uk> - 2017-09-11 22:10 +0200
                Re: iov_iter_pipe warning. Al Viro <viro@ZenIV.linux.org.uk> - 2017-09-11 22:20 +0200
                Re: iov_iter_pipe warning. Dave Chinner <david@fromorbit.com> - 2017-09-12 08:10 +0200
                Re: iov_iter_pipe warning. Al Viro <viro@ZenIV.linux.org.uk> - 2017-09-12 13:20 +0200
        Re: iov_iter_pipe warning. Christoph Hellwig <hch@infradead.org> - 2017-09-11 14:10 +0200
          Re: iov_iter_pipe warning. Al Viro <viro@ZenIV.linux.org.uk> - 2017-09-11 15:00 +0200

csiph-web