fix return values of seq_read_iter()
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 12 Nov 2020 19:40:37 +0000 (14:40 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 16 Nov 2020 03:12:53 +0000 (22:12 -0500)
commit4bbf439b09c5ac3f8b3e9584fe080375d8d0ad2d
tree4c22e0ed68c83609d95949c7a7f2645b0513a8b2
parentd4d50710a8b46082224376ef119a4dbb75b25c56
fix return values of seq_read_iter()

Unlike ->read(), ->read_iter() instances *must* return the amount
of data they'd left in iterator.  For ->read() returning less than
it has actually copied is a QoI issue; read(fd, unmapped_page - 5, 8)
is allowed to fill all 5 bytes of destination and return 4; it's
not nice to caller, but POSIX allows pretty much anything in such
situation, up to and including a SIGSEGV.

generic_file_splice_read() uses pipe-backed iterator as destination;
there a short copy comes from pipe being full, not from running into
an un{mapped,writable} page in the middle of destination as we
have for iovec-backed iterators read(2) uses.  And there we rely
upon the ->read_iter() reporting the actual amount it has left
in destination.

Conversion of a ->read() instance into ->read_iter() has to watch
out for that.  If you really need an "all or nothing" kind of
behaviour somewhere, you need to do iov_iter_revert() to prune
the partial copy.

In case of seq_read_iter() we can handle short copy just fine;
the data is in m->buf and next call will fetch it from there.

Fixes: d4d50710a8b4 (seq_file: add seq_read_iter)
Tested-by: Nathan Chancellor <natechancellor@gmail.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/seq_file.c