Commit b8c06ad4 authored by Stefano Garzarella's avatar Stefano Garzarella Committed by Michael S. Tsirkin
Browse files

vringh: implement vringh_kiov_advance()



In some cases, it may be useful to provide a way to skip a number
of bytes in a vringh_kiov.

Let's implement vringh_kiov_advance() for this purpose, reusing the
code from vringh_iov_xfer().
We replace that code calling the new vringh_kiov_advance().

Acked-by: default avatarJason Wang <jasowang@redhat.com>
Signed-off-by: default avatarStefano Garzarella <sgarzare@redhat.com>
Link: https://lore.kernel.org/r/20210315163450.254396-6-sgarzare@redhat.com


Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 69c13c58
Loading
Loading
Loading
Loading
+29 −12
Original line number Diff line number Diff line
@@ -75,6 +75,34 @@ static inline int __vringh_get_head(const struct vringh *vrh,
	return head;
}

/**
 * vringh_kiov_advance - skip bytes from vring_kiov
 * @iov: an iov passed to vringh_getdesc_*() (updated as we consume)
 * @len: the maximum length to advance
 */
void vringh_kiov_advance(struct vringh_kiov *iov, size_t len)
{
	while (len && iov->i < iov->used) {
		size_t partlen = min(iov->iov[iov->i].iov_len, len);

		iov->consumed += partlen;
		iov->iov[iov->i].iov_len -= partlen;
		iov->iov[iov->i].iov_base += partlen;

		if (!iov->iov[iov->i].iov_len) {
			/* Fix up old iov element then increment. */
			iov->iov[iov->i].iov_len = iov->consumed;
			iov->iov[iov->i].iov_base -= iov->consumed;

			iov->consumed = 0;
			iov->i++;
		}

		len -= partlen;
	}
}
EXPORT_SYMBOL(vringh_kiov_advance);

/* Copy some bytes to/from the iovec.  Returns num copied. */
static inline ssize_t vringh_iov_xfer(struct vringh *vrh,
				      struct vringh_kiov *iov,
@@ -95,19 +123,8 @@ static inline ssize_t vringh_iov_xfer(struct vringh *vrh,
		done += partlen;
		len -= partlen;
		ptr += partlen;
		iov->consumed += partlen;
		iov->iov[iov->i].iov_len -= partlen;
		iov->iov[iov->i].iov_base += partlen;

		if (!iov->iov[iov->i].iov_len) {
			/* Fix up old iov element then increment. */
			iov->iov[iov->i].iov_len = iov->consumed;
			iov->iov[iov->i].iov_base -= iov->consumed;

			
			iov->consumed = 0;
			iov->i++;
		}
		vringh_kiov_advance(iov, partlen);
	}
	return done;
}
+2 −0
Original line number Diff line number Diff line
@@ -199,6 +199,8 @@ static inline void vringh_kiov_cleanup(struct vringh_kiov *kiov)
	kiov->iov = NULL;
}

void vringh_kiov_advance(struct vringh_kiov *kiov, size_t len);

int vringh_getdesc_kern(struct vringh *vrh,
			struct vringh_kiov *riov,
			struct vringh_kiov *wiov,