mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2025-07-16 14:19:36 +02:00
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;
|
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. */
|
/* Copy some bytes to/from the iovec. Returns num copied. */
|
||||||
static inline ssize_t vringh_iov_xfer(struct vringh *vrh,
|
static inline ssize_t vringh_iov_xfer(struct vringh *vrh,
|
||||||
struct vringh_kiov *iov,
|
struct vringh_kiov *iov,
|
||||||
|
@ -95,19 +123,8 @@ static inline ssize_t vringh_iov_xfer(struct vringh *vrh,
|
||||||
done += partlen;
|
done += partlen;
|
||||||
len -= partlen;
|
len -= partlen;
|
||||||
ptr += 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) {
|
vringh_kiov_advance(iov, partlen);
|
||||||
/* 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++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return done;
|
return done;
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,6 +199,8 @@ static inline void vringh_kiov_cleanup(struct vringh_kiov *kiov)
|
||||||
kiov->iov = NULL;
|
kiov->iov = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vringh_kiov_advance(struct vringh_kiov *kiov, size_t len);
|
||||||
|
|
||||||
int vringh_getdesc_kern(struct vringh *vrh,
|
int vringh_getdesc_kern(struct vringh *vrh,
|
||||||
struct vringh_kiov *riov,
|
struct vringh_kiov *riov,
|
||||||
struct vringh_kiov *wiov,
|
struct vringh_kiov *wiov,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user