mirror of https://gitee.com/openkylin/linux.git
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: Jason Wang <jasowang@redhat.com> Signed-off-by: Stefano Garzarella <sgarzare@redhat.com> Link: https://lore.kernel.org/r/20210315163450.254396-6-sgarzare@redhat.com Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
69c13c58bd
commit
b8c06ad4d6
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue