/*
 * QEMU I/O channels block driver
 *
 * Copyright (c) 2022 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "qemu/osdep.h"
#include "migration/channel-block.h"
#include "qapi/error.h"
#include "block/block.h"
#include "trace.h"

QIOChannelBlock *
qio_channel_block_new(BlockDriverState *bs)
{
    QIOChannelBlock *ioc;

    ioc = QIO_CHANNEL_BLOCK(object_new(TYPE_QIO_CHANNEL_BLOCK));

    bdrv_ref(bs);
    ioc->bs = bs;

    return ioc;
}


static void
qio_channel_block_finalize(Object *obj)
{
    QIOChannelBlock *ioc = QIO_CHANNEL_BLOCK(obj);

    g_clear_pointer(&ioc->bs, bdrv_unref);
}


static ssize_t
qio_channel_block_readv(QIOChannel *ioc,
                        const struct iovec *iov,
                        size_t niov,
                        int **fds,
                        size_t *nfds,
                        Error **errp)
{
    QIOChannelBlock *bioc = QIO_CHANNEL_BLOCK(ioc);
    QEMUIOVector qiov;
    int ret;

    qemu_iovec_init_external(&qiov, (struct iovec *)iov, niov);
    ret = bdrv_readv_vmstate(bioc->bs, &qiov, bioc->offset);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "bdrv_readv_vmstate failed");
        return -1;
    }

    bioc->offset += qiov.size;
    return qiov.size;
}


static ssize_t
qio_channel_block_writev(QIOChannel *ioc,
                         const struct iovec *iov,
                         size_t niov,
                         int *fds,
                         size_t nfds,
                         int flags,
                         Error **errp)
{
    QIOChannelBlock *bioc = QIO_CHANNEL_BLOCK(ioc);
    QEMUIOVector qiov;
    int ret;

    qemu_iovec_init_external(&qiov, (struct iovec *)iov, niov);
    ret = bdrv_writev_vmstate(bioc->bs, &qiov, bioc->offset);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "bdrv_writev_vmstate failed");
        return -1;
    }

    bioc->offset += qiov.size;
    return qiov.size;
}


static int
qio_channel_block_set_blocking(QIOChannel *ioc,
                               bool enabled,
                               Error **errp)
{
    if (!enabled) {
        error_setg(errp, "Non-blocking mode not supported for block devices");
        return -1;
    }
    return 0;
}


static off_t
qio_channel_block_seek(QIOChannel *ioc,
                       off_t offset,
                       int whence,
                       Error **errp)
{
    QIOChannelBlock *bioc = QIO_CHANNEL_BLOCK(ioc);

    switch (whence) {
    case SEEK_SET:
        bioc->offset = offset;
        break;
    case SEEK_CUR:
        bioc->offset += whence;
        break;
    case SEEK_END:
        error_setg(errp, "Size of VMstate region is unknown");
        return (off_t)-1;
    default:
        g_assert_not_reached();
    }

    return bioc->offset;
}


static int
qio_channel_block_close(QIOChannel *ioc,
                        Error **errp)
{
    QIOChannelBlock *bioc = QIO_CHANNEL_BLOCK(ioc);
    int rv = bdrv_flush(bioc->bs);

    if (rv < 0) {
        error_setg_errno(errp, -rv,
                         "Unable to flush VMState");
        return -1;
    }

    g_clear_pointer(&bioc->bs, bdrv_unref);
    bioc->offset = 0;

    return 0;
}


static void
qio_channel_block_set_aio_fd_handler(QIOChannel *ioc,
                                     AioContext *ctx,
                                     IOHandler *io_read,
                                     IOHandler *io_write,
                                     void *opaque)
{
    /* XXX anything we can do here ? */
}


static void
qio_channel_block_class_init(ObjectClass *klass,
                             void *class_data G_GNUC_UNUSED)
{
    QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass);

    ioc_klass->io_writev = qio_channel_block_writev;
    ioc_klass->io_readv = qio_channel_block_readv;
    ioc_klass->io_set_blocking = qio_channel_block_set_blocking;
    ioc_klass->io_seek = qio_channel_block_seek;
    ioc_klass->io_close = qio_channel_block_close;
    ioc_klass->io_set_aio_fd_handler = qio_channel_block_set_aio_fd_handler;
}

static const TypeInfo qio_channel_block_info = {
    .parent = TYPE_QIO_CHANNEL,
    .name = TYPE_QIO_CHANNEL_BLOCK,
    .instance_size = sizeof(QIOChannelBlock),
    .instance_finalize = qio_channel_block_finalize,
    .class_init = qio_channel_block_class_init,
};

static void
qio_channel_block_register_types(void)
{
    type_register_static(&qio_channel_block_info);
}

type_init(qio_channel_block_register_types);
