mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
io: implement io_pwritev/preadv for QIOChannelFile
The upcoming 'mapped-ram' feature will require qemu to write data to (and restore from) specific offsets of the migration file. Add a minimal implementation of pwritev/preadv and expose them via the io_pwritev and io_preadv interfaces. Signed-off-by: Nikolay Borisov <nborisov@suse.com> Reviewed-by: "Daniel P. Berrangé" <berrange@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Signed-off-by: Fabiano Rosas <farosas@suse.de> Link: https://lore.kernel.org/r/20240229153017.2221-5-farosas@suse.de Signed-off-by: Peter Xu <peterx@redhat.com>
This commit is contained in:
parent
f1cfe39418
commit
0478b030fa
1 changed files with 56 additions and 0 deletions
|
@ -146,6 +146,58 @@ static ssize_t qio_channel_file_writev(QIOChannel *ioc,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PREADV
|
||||||
|
static ssize_t qio_channel_file_preadv(QIOChannel *ioc,
|
||||||
|
const struct iovec *iov,
|
||||||
|
size_t niov,
|
||||||
|
off_t offset,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
retry:
|
||||||
|
ret = preadv(fioc->fd, iov, niov, offset);
|
||||||
|
if (ret < 0) {
|
||||||
|
if (errno == EAGAIN) {
|
||||||
|
return QIO_CHANNEL_ERR_BLOCK;
|
||||||
|
}
|
||||||
|
if (errno == EINTR) {
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_setg_errno(errp, errno, "Unable to read from file");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t qio_channel_file_pwritev(QIOChannel *ioc,
|
||||||
|
const struct iovec *iov,
|
||||||
|
size_t niov,
|
||||||
|
off_t offset,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
retry:
|
||||||
|
ret = pwritev(fioc->fd, iov, niov, offset);
|
||||||
|
if (ret <= 0) {
|
||||||
|
if (errno == EAGAIN) {
|
||||||
|
return QIO_CHANNEL_ERR_BLOCK;
|
||||||
|
}
|
||||||
|
if (errno == EINTR) {
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
error_setg_errno(errp, errno, "Unable to write to file");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_PREADV */
|
||||||
|
|
||||||
static int qio_channel_file_set_blocking(QIOChannel *ioc,
|
static int qio_channel_file_set_blocking(QIOChannel *ioc,
|
||||||
bool enabled,
|
bool enabled,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
|
@ -231,6 +283,10 @@ static void qio_channel_file_class_init(ObjectClass *klass,
|
||||||
ioc_klass->io_writev = qio_channel_file_writev;
|
ioc_klass->io_writev = qio_channel_file_writev;
|
||||||
ioc_klass->io_readv = qio_channel_file_readv;
|
ioc_klass->io_readv = qio_channel_file_readv;
|
||||||
ioc_klass->io_set_blocking = qio_channel_file_set_blocking;
|
ioc_klass->io_set_blocking = qio_channel_file_set_blocking;
|
||||||
|
#ifdef CONFIG_PREADV
|
||||||
|
ioc_klass->io_pwritev = qio_channel_file_pwritev;
|
||||||
|
ioc_klass->io_preadv = qio_channel_file_preadv;
|
||||||
|
#endif
|
||||||
ioc_klass->io_seek = qio_channel_file_seek;
|
ioc_klass->io_seek = qio_channel_file_seek;
|
||||||
ioc_klass->io_close = qio_channel_file_close;
|
ioc_klass->io_close = qio_channel_file_close;
|
||||||
ioc_klass->io_create_watch = qio_channel_file_create_watch;
|
ioc_klass->io_create_watch = qio_channel_file_create_watch;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue