mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:46:17 +00:00
io/channel: introduce qio_channel_pwrite{v,}_all()
Add positioned write helpers that retry on short writes, matching
the pread_all family from the previous patch.
qio_channel_pwritev_all() -- retry loop; returns 0 on success,
-1 on error.
qio_channel_pwrite_all() -- single-buffer convenience wrapper.
Signed-off-by: Junjie Cao <junjie.cao@intel.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Link: https://lore.kernel.org/qemu-devel/20260413214549.926435-3-junjie.cao@intel.com
Signed-off-by: Fabiano Rosas <farosas@suse.de>
This commit is contained in:
committed by
Fabiano Rosas
parent
2dd53f732b
commit
40bf7bbcf4
@@ -598,6 +598,47 @@ ssize_t qio_channel_pwritev(QIOChannel *ioc, const struct iovec *iov,
|
||||
ssize_t qio_channel_pwrite(QIOChannel *ioc, void *buf, size_t buflen,
|
||||
off_t offset, Error **errp);
|
||||
|
||||
/**
|
||||
* qio_channel_pwritev_all:
|
||||
* @ioc: the channel object
|
||||
* @iov: the array of memory regions to write data from
|
||||
* @niov: the length of the @iov array
|
||||
* @offset: the starting offset in the channel to write to
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Writes @iov, possibly blocking or (if the channel is non-blocking)
|
||||
* yielding from the current coroutine multiple times until the entire
|
||||
* content is written. Otherwise behaves as qio_channel_pwritev().
|
||||
*
|
||||
* Returns: 0 if all bytes were written, or -1 on error
|
||||
*/
|
||||
int coroutine_mixed_fn qio_channel_pwritev_all(QIOChannel *ioc,
|
||||
const struct iovec *iov,
|
||||
size_t niov,
|
||||
off_t offset,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qio_channel_pwrite_all:
|
||||
* @ioc: the channel object
|
||||
* @buf: the memory region to write data from
|
||||
* @buflen: the number of bytes to write from @buf
|
||||
* @offset: the starting offset in the channel to write to
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Writes @buflen bytes from @buf, possibly blocking or (if the
|
||||
* channel is non-blocking) yielding from the current coroutine
|
||||
* multiple times until the entire content is written. Otherwise
|
||||
* behaves as qio_channel_pwrite().
|
||||
*
|
||||
* Returns: 0 if all bytes were written, or -1 on error
|
||||
*/
|
||||
int coroutine_mixed_fn qio_channel_pwrite_all(QIOChannel *ioc,
|
||||
const void *buf,
|
||||
size_t buflen,
|
||||
off_t offset,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qio_channel_preadv
|
||||
* @ioc: the channel object
|
||||
|
||||
48
io/channel.c
48
io/channel.c
@@ -478,6 +478,54 @@ ssize_t qio_channel_pwrite(QIOChannel *ioc, void *buf, size_t buflen,
|
||||
return qio_channel_pwritev(ioc, &iov, 1, offset, errp);
|
||||
}
|
||||
|
||||
int coroutine_mixed_fn qio_channel_pwritev_all(QIOChannel *ioc,
|
||||
const struct iovec *iov,
|
||||
size_t niov,
|
||||
off_t offset,
|
||||
Error **errp)
|
||||
{
|
||||
int ret = -1;
|
||||
struct iovec *local_iov = g_new(struct iovec, niov);
|
||||
struct iovec *local_iov_head = local_iov;
|
||||
unsigned int nlocal_iov = niov;
|
||||
|
||||
nlocal_iov = iov_copy(local_iov, nlocal_iov,
|
||||
iov, niov,
|
||||
0, iov_size(iov, niov));
|
||||
|
||||
while (nlocal_iov > 0) {
|
||||
ssize_t len;
|
||||
|
||||
len = qio_channel_pwritev(ioc, local_iov, nlocal_iov, offset, errp);
|
||||
|
||||
if (len == QIO_CHANNEL_ERR_BLOCK) {
|
||||
qio_channel_wait_cond(ioc, G_IO_OUT);
|
||||
continue;
|
||||
}
|
||||
if (len < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
offset += len;
|
||||
iov_discard_front(&local_iov, &nlocal_iov, len);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
g_free(local_iov_head);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int coroutine_mixed_fn qio_channel_pwrite_all(QIOChannel *ioc,
|
||||
const void *buf,
|
||||
size_t buflen,
|
||||
off_t offset,
|
||||
Error **errp)
|
||||
{
|
||||
struct iovec iov = { .iov_base = (char *)buf, .iov_len = buflen };
|
||||
return qio_channel_pwritev_all(ioc, &iov, 1, offset, errp);
|
||||
}
|
||||
|
||||
ssize_t qio_channel_preadv(QIOChannel *ioc, const struct iovec *iov,
|
||||
size_t niov, off_t offset, Error **errp)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user