block: enhance QEMUIOVector structure
Add a possibility of embedded iovec, for cases when we need only one local iov. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-id: 20190218140926.333779-2-vsementsov@virtuozzo.com Message-Id: <20190218140926.333779-2-vsementsov@virtuozzo.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
fc3dbb90f2
commit
a1ca3ed5ec
@ -133,10 +133,70 @@ size_t iov_discard_back(struct iovec *iov, unsigned int *iov_cnt,
|
||||
typedef struct QEMUIOVector {
|
||||
struct iovec *iov;
|
||||
int niov;
|
||||
int nalloc;
|
||||
size_t size;
|
||||
|
||||
/*
|
||||
* For external @iov (qemu_iovec_init_external()) or allocated @iov
|
||||
* (qemu_iovec_init()), @size is the cumulative size of iovecs and
|
||||
* @local_iov is invalid and unused.
|
||||
*
|
||||
* For embedded @iov (QEMU_IOVEC_INIT_BUF() or qemu_iovec_init_buf()),
|
||||
* @iov is equal to &@local_iov, and @size is valid, as it has same
|
||||
* offset and type as @local_iov.iov_len, which is guaranteed by
|
||||
* static assertion below.
|
||||
*
|
||||
* @nalloc is always valid and is -1 both for embedded and external
|
||||
* cases. It is included in the union only to ensure the padding prior
|
||||
* to the @size field will not result in a 0-length array.
|
||||
*/
|
||||
union {
|
||||
struct {
|
||||
int nalloc;
|
||||
struct iovec local_iov;
|
||||
};
|
||||
struct {
|
||||
char __pad[sizeof(int) + offsetof(struct iovec, iov_len)];
|
||||
size_t size;
|
||||
};
|
||||
};
|
||||
} QEMUIOVector;
|
||||
|
||||
QEMU_BUILD_BUG_ON(offsetof(QEMUIOVector, size) !=
|
||||
offsetof(QEMUIOVector, local_iov.iov_len));
|
||||
|
||||
#define QEMU_IOVEC_INIT_BUF(self, buf, len) \
|
||||
{ \
|
||||
.iov = &(self).local_iov, \
|
||||
.niov = 1, \
|
||||
.nalloc = -1, \
|
||||
.local_iov = { \
|
||||
.iov_base = (void *)(buf), /* cast away const */ \
|
||||
.iov_len = (len), \
|
||||
}, \
|
||||
}
|
||||
|
||||
/*
|
||||
* qemu_iovec_init_buf
|
||||
*
|
||||
* Initialize embedded QEMUIOVector.
|
||||
*
|
||||
* Note: "const" is used over @buf pointer to make it simple to pass
|
||||
* const pointers, appearing in read functions. Then this "const" is
|
||||
* cast away by QEMU_IOVEC_INIT_BUF().
|
||||
*/
|
||||
static inline void qemu_iovec_init_buf(QEMUIOVector *qiov,
|
||||
const void *buf, size_t len)
|
||||
{
|
||||
*qiov = (QEMUIOVector) QEMU_IOVEC_INIT_BUF(*qiov, buf, len);
|
||||
}
|
||||
|
||||
static inline void *qemu_iovec_buf(QEMUIOVector *qiov)
|
||||
{
|
||||
/* Only supports embedded iov */
|
||||
assert(qiov->nalloc == -1 && qiov->iov == &qiov->local_iov);
|
||||
|
||||
return qiov->local_iov.iov_base;
|
||||
}
|
||||
|
||||
void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint);
|
||||
void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov);
|
||||
void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len);
|
||||
|
Loading…
Reference in New Issue
Block a user