/*
 * 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) {
        return ret;
    }

    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) {
        return ret;
    }

    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);
