/*
 * Copy-on-read filter block driver
 *
 * Copyright (c) 2018 Red Hat, Inc.
 *
 * Author:
 *   Max Reitz <mreitz@redhat.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 or
 * (at your option) version 3 of the License.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "block/block_int.h"


static int cor_open(BlockDriverState *bs, QDict *options, int flags,
                    Error **errp)
{
    bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, false,
                               errp);
    if (!bs->file) {
        return -EINVAL;
    }

    bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
                                (BDRV_REQ_FUA &
                                    bs->file->bs->supported_write_flags);

    bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
                               ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
                                    bs->file->bs->supported_zero_flags);

    return 0;
}


static void cor_close(BlockDriverState *bs)
{
}


#define PERM_PASSTHROUGH (BLK_PERM_CONSISTENT_READ \
                          | BLK_PERM_WRITE \
                          | BLK_PERM_RESIZE)
#define PERM_UNCHANGED (BLK_PERM_ALL & ~PERM_PASSTHROUGH)

static void cor_child_perm(BlockDriverState *bs, BdrvChild *c,
                           const BdrvChildRole *role,
                           BlockReopenQueue *reopen_queue,
                           uint64_t perm, uint64_t shared,
                           uint64_t *nperm, uint64_t *nshared)
{
    if (c == NULL) {
        *nperm = (perm & PERM_PASSTHROUGH) | BLK_PERM_WRITE_UNCHANGED;
        *nshared = (shared & PERM_PASSTHROUGH) | PERM_UNCHANGED;
        return;
    }

    *nperm = (perm & PERM_PASSTHROUGH) |
             (c->perm & PERM_UNCHANGED);
    *nshared = (shared & PERM_PASSTHROUGH) |
               (c->shared_perm & PERM_UNCHANGED);
}


static int64_t cor_getlength(BlockDriverState *bs)
{
    return bdrv_getlength(bs->file->bs);
}


static int cor_truncate(BlockDriverState *bs, int64_t offset,
                        PreallocMode prealloc, Error **errp)
{
    return bdrv_truncate(bs->file, offset, prealloc, errp);
}


static int coroutine_fn cor_co_preadv(BlockDriverState *bs,
                                      uint64_t offset, uint64_t bytes,
                                      QEMUIOVector *qiov, int flags)
{
    return bdrv_co_preadv(bs->file, offset, bytes, qiov,
                          flags | BDRV_REQ_COPY_ON_READ);
}


static int coroutine_fn cor_co_pwritev(BlockDriverState *bs,
                                       uint64_t offset, uint64_t bytes,
                                       QEMUIOVector *qiov, int flags)
{

    return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
}


static int coroutine_fn cor_co_pwrite_zeroes(BlockDriverState *bs,
                                             int64_t offset, int bytes,
                                             BdrvRequestFlags flags)
{
    return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
}


static int coroutine_fn cor_co_pdiscard(BlockDriverState *bs,
                                        int64_t offset, int bytes)
{
    return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
}


static void cor_eject(BlockDriverState *bs, bool eject_flag)
{
    bdrv_eject(bs->file->bs, eject_flag);
}


static void cor_lock_medium(BlockDriverState *bs, bool locked)
{
    bdrv_lock_medium(bs->file->bs, locked);
}


static bool cor_recurse_is_first_non_filter(BlockDriverState *bs,
                                            BlockDriverState *candidate)
{
    return bdrv_recurse_is_first_non_filter(bs->file->bs, candidate);
}


BlockDriver bdrv_copy_on_read = {
    .format_name                        = "copy-on-read",

    .bdrv_open                          = cor_open,
    .bdrv_close                         = cor_close,
    .bdrv_child_perm                    = cor_child_perm,

    .bdrv_getlength                     = cor_getlength,
    .bdrv_truncate                      = cor_truncate,

    .bdrv_co_preadv                     = cor_co_preadv,
    .bdrv_co_pwritev                    = cor_co_pwritev,
    .bdrv_co_pwrite_zeroes              = cor_co_pwrite_zeroes,
    .bdrv_co_pdiscard                   = cor_co_pdiscard,

    .bdrv_eject                         = cor_eject,
    .bdrv_lock_medium                   = cor_lock_medium,

    .bdrv_co_block_status               = bdrv_co_block_status_from_file,

    .bdrv_recurse_is_first_non_filter   = cor_recurse_is_first_non_filter,

    .has_variable_length                = true,
    .is_filter                          = true,
};

static void bdrv_copy_on_read_init(void)
{
    bdrv_register(&bdrv_copy_on_read);
}

block_init(bdrv_copy_on_read_init);
