summaryrefslogtreecommitdiff
path: root/lib/iov_iter.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2022-06-15 16:03:25 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2022-08-08 22:37:18 -0400
commit2c855de93314e9573f31044976ffd89cb70a2dbd (patch)
tree1cec98a604162a4b3f752d0c15dc1f67d11dcd9c /lib/iov_iter.c
parentca591967543ab1af7e6e68bd505ef7869d3f2175 (diff)
ITER_PIPE: clean pipe_advance() up
instead of setting ->iov_offset for new position and calling pipe_truncate() to adjust ->len of the last buffer and discard everything after it, adjust ->len at the same time we set ->iov_offset and use pipe_discard_from() to deal with buffers past that. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'lib/iov_iter.c')
-rw-r--r--lib/iov_iter.c34
1 files changed, 17 insertions, 17 deletions
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index 95c56d42505b..402d49688a16 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -845,27 +845,27 @@ static inline void pipe_truncate(struct iov_iter *i)
static void pipe_advance(struct iov_iter *i, size_t size)
{
struct pipe_inode_info *pipe = i->pipe;
- if (size) {
- struct pipe_buffer *buf;
- unsigned int p_mask = pipe->ring_size - 1;
- unsigned int i_head = i->head;
- size_t off = i->iov_offset, left = size;
+ unsigned int off = i->iov_offset;
+ if (!off && !size) {
+ pipe_discard_from(pipe, i->start_head); // discard everything
+ return;
+ }
+ i->count -= size;
+ while (1) {
+ struct pipe_buffer *buf = pipe_buf(pipe, i->head);
if (off) /* make it relative to the beginning of buffer */
- left += off - pipe->bufs[i_head & p_mask].offset;
- while (1) {
- buf = &pipe->bufs[i_head & p_mask];
- if (left <= buf->len)
- break;
- left -= buf->len;
- i_head++;
+ size += off - buf->offset;
+ if (size <= buf->len) {
+ buf->len = size;
+ i->iov_offset = buf->offset + size;
+ break;
}
- i->head = i_head;
- i->iov_offset = buf->offset + left;
+ size -= buf->len;
+ i->head++;
+ off = 0;
}
- i->count -= size;
- /* ... and discard everything past that point */
- pipe_truncate(i);
+ pipe_discard_from(pipe, i->head + 1); // discard everything past this one
}
static void iov_iter_bvec_advance(struct iov_iter *i, size_t size)