/*
 * snapshot_access block driver
 *
 * Copyright (c) 2022 Virtuozzo International GmbH.
 *
 * Author:
 *  Sementsov-Ogievskiy Vladimir <vsementsov@virtuozzo.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 of the License, or
 * (at your option) any later version.
 *
 * 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 "system/block-backend.h"
#include "qemu/cutils.h"
#include "block/block_int.h"

static int coroutine_fn GRAPH_RDLOCK
snapshot_access_co_preadv_part(BlockDriverState *bs,
                               int64_t offset, int64_t bytes,
                               QEMUIOVector *qiov, size_t qiov_offset,
                               BdrvRequestFlags flags)
{
    if (flags) {
        return -ENOTSUP;
    }

    return bdrv_co_preadv_snapshot(bs->file, offset, bytes, qiov, qiov_offset);
}

static int coroutine_fn GRAPH_RDLOCK
snapshot_access_co_block_status(BlockDriverState *bs,
                                unsigned int mode, int64_t offset,
                                int64_t bytes, int64_t *pnum,
                                int64_t *map, BlockDriverState **file)
{
    return bdrv_co_snapshot_block_status(bs->file->bs, mode, offset,
                                         bytes, pnum, map, file);
}

static int coroutine_fn GRAPH_RDLOCK
snapshot_access_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
    return bdrv_co_pdiscard_snapshot(bs->file->bs, offset, bytes);
}

static int coroutine_fn
snapshot_access_co_pwrite_zeroes(BlockDriverState *bs,
                                 int64_t offset, int64_t bytes,
                                 BdrvRequestFlags flags)
{
    return -ENOTSUP;
}

static coroutine_fn int
snapshot_access_co_pwritev_part(BlockDriverState *bs,
                                int64_t offset, int64_t bytes,
                                QEMUIOVector *qiov, size_t qiov_offset,
                                BdrvRequestFlags flags)
{
    return -ENOTSUP;
}


static void GRAPH_RDLOCK snapshot_access_refresh_filename(BlockDriverState *bs)
{
    pstrcpy(bs->exact_filename, sizeof(bs->exact_filename),
            bs->file->bs->filename);
}

static int snapshot_access_open(BlockDriverState *bs, QDict *options, int flags,
                                Error **errp)
{
    bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
                    BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY,
                    false, errp);

    GRAPH_RDLOCK_GUARD_MAINLOOP();

    if (!bs->file) {
        return -EINVAL;
    }

    bs->total_sectors = bs->file->bs->total_sectors;

    return 0;
}

static void snapshot_access_child_perm(BlockDriverState *bs, BdrvChild *c,
                                BdrvChildRole role,
                                BlockReopenQueue *reopen_queue,
                                uint64_t perm, uint64_t shared,
                                uint64_t *nperm, uint64_t *nshared)
{
    /*
     * Currently, we don't need any permissions. If bs->file provides
     * snapshot-access API, we can use it.
     */
    *nperm = 0;
    *nshared = BLK_PERM_ALL;
}

static BlockDriver bdrv_snapshot_access_drv = {
    .format_name = "snapshot-access",

    .bdrv_open                  = snapshot_access_open,

    .bdrv_co_preadv_part        = snapshot_access_co_preadv_part,
    .bdrv_co_pwritev_part       = snapshot_access_co_pwritev_part,
    .bdrv_co_pwrite_zeroes      = snapshot_access_co_pwrite_zeroes,
    .bdrv_co_pdiscard           = snapshot_access_co_pdiscard,
    .bdrv_co_block_status       = snapshot_access_co_block_status,

    .bdrv_refresh_filename      = snapshot_access_refresh_filename,

    .bdrv_child_perm            = snapshot_access_child_perm,
};

static void snapshot_access_init(void)
{
    bdrv_register(&bdrv_snapshot_access_drv);
}

block_init(snapshot_access_init);
