/*
 * Live block commit
 *
 * Copyright Red Hat, Inc. 2012
 *
 * Authors:
 *  Jeff Cody   <jcody@redhat.com>
 *  Based on stream.c by Stefan Hajnoczi
 *
 * This work is licensed under the terms of the GNU LGPL, version 2 or later.
 * See the COPYING.LIB file in the top-level directory.
 *
 */

#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "trace.h"
#include "block/block-common.h"
#include "block/coroutines.h"
#include "block/block_int.h"
#include "block/blockjob_int.h"
#include "qapi/error.h"
#include "qemu/ratelimit.h"
#include "qemu/memalign.h"
#include "system/block-backend.h"

enum {
    /*
     * Size of data buffer for populating the image file.  This should be large
     * enough to process multiple clusters in a single call, so that populating
     * contiguous regions of the image is efficient.
     */
    COMMIT_BUFFER_SIZE = 512 * 1024, /* in bytes */
};

typedef struct CommitBlockJob {
    BlockJob common;
    BlockDriverState *commit_top_bs;
    BlockBackend *top;
    BlockBackend *base;
    BlockDriverState *base_bs;
    BlockDriverState *base_overlay;
    BlockdevOnError on_error;
    bool base_read_only;
    bool chain_frozen;
    char *backing_file_str;
    bool backing_mask_protocol;
} CommitBlockJob;

static int commit_prepare(Job *job)
{
    CommitBlockJob *s = container_of(job, CommitBlockJob, common.job);

    bdrv_graph_rdlock_main_loop();
    bdrv_unfreeze_backing_chain(s->commit_top_bs, s->base_bs);
    s->chain_frozen = false;
    bdrv_graph_rdunlock_main_loop();

    /* Remove base node parent that still uses BLK_PERM_WRITE/RESIZE before
     * the normal backing chain can be restored. */
    blk_unref(s->base);
    s->base = NULL;

    /* FIXME: bdrv_drop_intermediate treats total failures and partial failures
     * identically. Further work is needed to disambiguate these cases. */
    return bdrv_drop_intermediate(s->commit_top_bs, s->base_bs,
                                  s->backing_file_str,
                                  s->backing_mask_protocol);
}

static void GRAPH_UNLOCKED commit_abort(Job *job)
{
    CommitBlockJob *s = container_of(job, CommitBlockJob, common.job);
    BlockDriverState *top_bs = blk_bs(s->top);
    BlockDriverState *commit_top_backing_bs;

    if (s->chain_frozen) {
        bdrv_graph_rdlock_main_loop();
        bdrv_unfreeze_backing_chain(s->commit_top_bs, s->base_bs);
        bdrv_graph_rdunlock_main_loop();
    }

    /* Make sure commit_top_bs and top stay around until bdrv_replace_node() */
    bdrv_ref(top_bs);
    bdrv_ref(s->commit_top_bs);

    if (s->base) {
        blk_unref(s->base);
    }

    /* free the blockers on the intermediate nodes so that bdrv_replace_nodes
     * can succeed */
    block_job_remove_all_bdrv(&s->common);

    /* If bdrv_drop_intermediate() failed (or was not invoked), remove the
     * commit filter driver from the backing chain now. Do this as the final
     * step so that the 'consistent read' permission can be granted.
     *
     * XXX Can (or should) we somehow keep 'consistent read' blocked even
     * after the failed/cancelled commit job is gone? If we already wrote
     * something to base, the intermediate images aren't valid any more. */
    bdrv_graph_rdlock_main_loop();
    commit_top_backing_bs = s->commit_top_bs->backing->bs;
    bdrv_graph_rdunlock_main_loop();

    bdrv_drained_begin(commit_top_backing_bs);
    bdrv_graph_wrlock();
    bdrv_replace_node(s->commit_top_bs, commit_top_backing_bs, &error_abort);
    bdrv_graph_wrunlock();
    bdrv_drained_end(commit_top_backing_bs);

    bdrv_unref(s->commit_top_bs);
    bdrv_unref(top_bs);
}

static void commit_clean(Job *job)
{
    CommitBlockJob *s = container_of(job, CommitBlockJob, common.job);

    /* restore base open flags here if appropriate (e.g., change the base back
     * to r/o). These reopens do not need to be atomic, since we won't abort
     * even on failure here */
    if (s->base_read_only) {
        bdrv_reopen_set_read_only(s->base_bs, true, NULL);
    }

    g_free(s->backing_file_str);
    blk_unref(s->top);
}

static int coroutine_fn
commit_iteration(CommitBlockJob *s, int64_t offset,
                 int64_t *requested_bytes, void *buf)
{
    BlockErrorAction action;
    int64_t bytes = *requested_bytes;
    int ret = 0;
    bool error_in_source = true;

    /* Copy if allocated above the base */
    WITH_GRAPH_RDLOCK_GUARD() {
        ret = bdrv_co_common_block_status_above(blk_bs(s->top),
            s->base_overlay, true, true, offset, COMMIT_BUFFER_SIZE,
            &bytes, NULL, NULL, NULL);
    }

    trace_commit_one_iteration(s, offset, bytes, ret);

    if (ret < 0) {
        goto fail;
    }

    if (ret & BDRV_BLOCK_ALLOCATED) {
        if (ret & BDRV_BLOCK_ZERO) {
            /*
             * If the top (sub)clusters are smaller than the base
             * (sub)clusters, this will not unmap unless the underlying device
             * does some tracking of these requests. Ideally, we would find
             * the maximal extent of the zero clusters.
             */
            ret = blk_co_pwrite_zeroes(s->base, offset, bytes,
                                       BDRV_REQ_MAY_UNMAP);
            if (ret < 0) {
                error_in_source = false;
                goto fail;
            }
        } else {
            assert(bytes < SIZE_MAX);

            ret = blk_co_pread(s->top, offset, bytes, buf, 0);
            if (ret < 0) {
                goto fail;
            }

            ret = blk_co_pwrite(s->base, offset, bytes, buf, 0);
            if (ret < 0) {
                error_in_source = false;
                goto fail;
            }
        }

        /*
         * Whether zeroes actually end up on disk depends on the details of
         * the underlying driver. Therefore, this might rate limit more than
         * is necessary.
         */
        block_job_ratelimit_processed_bytes(&s->common, bytes);
    }

    /* Publish progress */

    job_progress_update(&s->common.job, bytes);

    *requested_bytes = bytes;

    return 0;

fail:
    action = block_job_error_action(&s->common, s->on_error,
                                    error_in_source, -ret);
    if (action == BLOCK_ERROR_ACTION_REPORT) {
        return ret;
    }

    *requested_bytes = 0;

    return 0;
}

static int coroutine_fn commit_run(Job *job, Error **errp)
{
    CommitBlockJob *s = container_of(job, CommitBlockJob, common.job);
    int64_t offset;
    int ret = 0;
    int64_t n = 0; /* bytes */
    QEMU_AUTO_VFREE void *buf = NULL;
    int64_t len, base_len;

    len = blk_co_getlength(s->top);
    if (len < 0) {
        return len;
    }
    job_progress_set_remaining(&s->common.job, len);

    base_len = blk_co_getlength(s->base);
    if (base_len < 0) {
        return base_len;
    }

    if (base_len < len) {
        ret = blk_co_truncate(s->base, len, false, PREALLOC_MODE_OFF, 0, NULL);
        if (ret) {
            return ret;
        }
    }

    buf = blk_blockalign(s->top, COMMIT_BUFFER_SIZE);

    for (offset = 0; offset < len; offset += n) {
        /* Note that even when no rate limit is applied we need to yield
         * with no pending I/O here so that bdrv_drain_all() returns.
         */
        block_job_ratelimit_sleep(&s->common);
        if (job_is_cancelled(&s->common.job)) {
            break;
        }

        ret = commit_iteration(s, offset, &n, buf);

        if (ret < 0) {
            return ret;
        }
    }

    return 0;
}

static const BlockJobDriver commit_job_driver = {
    .job_driver = {
        .instance_size = sizeof(CommitBlockJob),
        .job_type      = JOB_TYPE_COMMIT,
        .free          = block_job_free,
        .user_resume   = block_job_user_resume,
        .run           = commit_run,
        .prepare       = commit_prepare,
        .abort         = commit_abort,
        .clean         = commit_clean
    },
};

static int coroutine_fn GRAPH_RDLOCK
bdrv_commit_top_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
                       QEMUIOVector *qiov, BdrvRequestFlags flags)
{
    return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
}

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

static void bdrv_commit_top_child_perm(BlockDriverState *bs, BdrvChild *c,
                                       BdrvChildRole role,
                                       BlockReopenQueue *reopen_queue,
                                       uint64_t perm, uint64_t shared,
                                       uint64_t *nperm, uint64_t *nshared)
{
    *nperm = 0;
    *nshared = BLK_PERM_ALL;
}

/* Dummy node that provides consistent read to its users without requiring it
 * from its backing file and that allows writes on the backing file chain. */
static BlockDriver bdrv_commit_top = {
    .format_name                = "commit_top",
    .bdrv_co_preadv             = bdrv_commit_top_preadv,
    .bdrv_refresh_filename      = bdrv_commit_top_refresh_filename,
    .bdrv_child_perm            = bdrv_commit_top_child_perm,

    .is_filter                  = true,
    .filtered_child_is_backing  = true,
};

void commit_start(const char *job_id, BlockDriverState *bs,
                  BlockDriverState *base, BlockDriverState *top,
                  int creation_flags, int64_t speed,
                  BlockdevOnError on_error, const char *backing_file_str,
                  bool backing_mask_protocol,
                  const char *filter_node_name, Error **errp)
{
    CommitBlockJob *s;
    BlockDriverState *iter;
    BlockDriverState *commit_top_bs = NULL;
    BlockDriverState *filtered_base;
    int64_t base_size, top_size;
    uint64_t base_perms, iter_shared_perms;
    int ret;

    GLOBAL_STATE_CODE();

    assert(top != bs);
    bdrv_graph_rdlock_main_loop();
    if (bdrv_skip_filters(top) == bdrv_skip_filters(base)) {
        error_setg(errp, "Invalid files for merge: top and base are the same");
        bdrv_graph_rdunlock_main_loop();
        return;
    }
    bdrv_graph_rdunlock_main_loop();

    base_size = bdrv_getlength(base);
    if (base_size < 0) {
        error_setg_errno(errp, -base_size, "Could not inquire base image size");
        return;
    }

    top_size = bdrv_getlength(top);
    if (top_size < 0) {
        error_setg_errno(errp, -top_size, "Could not inquire top image size");
        return;
    }

    base_perms = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE;
    if (base_size < top_size) {
        base_perms |= BLK_PERM_RESIZE;
    }

    s = block_job_create(job_id, &commit_job_driver, NULL, bs, 0, BLK_PERM_ALL,
                         speed, creation_flags, NULL, NULL, errp);
    if (!s) {
        return;
    }

    /* convert base to r/w, if necessary */
    s->base_read_only = bdrv_is_read_only(base);
    if (s->base_read_only) {
        if (bdrv_reopen_set_read_only(base, false, errp) != 0) {
            goto fail;
        }
    }

    /* Insert commit_top block node above top, so we can block consistent read
     * on the backing chain below it */
    commit_top_bs = bdrv_new_open_driver(&bdrv_commit_top, filter_node_name, 0,
                                         errp);
    if (commit_top_bs == NULL) {
        goto fail;
    }
    if (!filter_node_name) {
        commit_top_bs->implicit = true;
    }

    /* So that we can always drop this node */
    commit_top_bs->never_freeze = true;

    commit_top_bs->total_sectors = top->total_sectors;

    ret = bdrv_append(commit_top_bs, top, errp);
    bdrv_unref(commit_top_bs); /* referenced by new parents or failed */
    if (ret < 0) {
        commit_top_bs = NULL;
        goto fail;
    }

    s->commit_top_bs = commit_top_bs;

    /*
     * Block all nodes between top and base, because they will
     * disappear from the chain after this operation.
     * Note that this assumes that the user is fine with removing all
     * nodes (including R/W filters) between top and base.  Assuring
     * this is the responsibility of the interface (i.e. whoever calls
     * commit_start()).
     */
    bdrv_graph_wrlock_drained();
    s->base_overlay = bdrv_find_overlay(top, base);
    assert(s->base_overlay);

    /*
     * The topmost node with
     * bdrv_skip_filters(filtered_base) == bdrv_skip_filters(base)
     */
    filtered_base = bdrv_cow_bs(s->base_overlay);
    assert(bdrv_skip_filters(filtered_base) == bdrv_skip_filters(base));

    /*
     * XXX BLK_PERM_WRITE needs to be allowed so we don't block ourselves
     * at s->base (if writes are blocked for a node, they are also blocked
     * for its backing file). The other options would be a second filter
     * driver above s->base.
     */
    iter_shared_perms = BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE;

    for (iter = top; iter != base; iter = bdrv_filter_or_cow_bs(iter)) {
        if (iter == filtered_base) {
            /*
             * From here on, all nodes are filters on the base.  This
             * allows us to share BLK_PERM_CONSISTENT_READ.
             */
            iter_shared_perms |= BLK_PERM_CONSISTENT_READ;
        }

        ret = block_job_add_bdrv(&s->common, "intermediate node", iter, 0,
                                 iter_shared_perms, errp);
        if (ret < 0) {
            bdrv_graph_wrunlock();
            goto fail;
        }
    }

    if (bdrv_freeze_backing_chain(commit_top_bs, base, errp) < 0) {
        bdrv_graph_wrunlock();
        goto fail;
    }
    s->chain_frozen = true;

    ret = block_job_add_bdrv(&s->common, "base", base, 0, BLK_PERM_ALL, errp);
    bdrv_graph_wrunlock();

    if (ret < 0) {
        goto fail;
    }

    s->base = blk_new(s->common.job.aio_context,
                      base_perms,
                      BLK_PERM_CONSISTENT_READ
                      | BLK_PERM_WRITE_UNCHANGED);
    ret = blk_insert_bs(s->base, base, errp);
    if (ret < 0) {
        goto fail;
    }
    blk_set_disable_request_queuing(s->base, true);
    s->base_bs = base;

    /* Required permissions are already taken with block_job_add_bdrv() */
    s->top = blk_new(s->common.job.aio_context, 0, BLK_PERM_ALL);
    ret = blk_insert_bs(s->top, top, errp);
    if (ret < 0) {
        goto fail;
    }
    blk_set_disable_request_queuing(s->top, true);

    s->backing_file_str = g_strdup(backing_file_str);
    s->backing_mask_protocol = backing_mask_protocol;
    s->on_error = on_error;

    trace_commit_start(bs, base, top, s);
    job_start(&s->common.job);
    return;

fail:
    if (s->chain_frozen) {
        bdrv_graph_rdlock_main_loop();
        bdrv_unfreeze_backing_chain(commit_top_bs, base);
        bdrv_graph_rdunlock_main_loop();
    }
    if (s->base) {
        blk_unref(s->base);
    }
    if (s->top) {
        blk_unref(s->top);
    }
    if (s->base_read_only) {
        bdrv_reopen_set_read_only(base, true, NULL);
    }
    job_early_fail(&s->common.job);
    /* commit_top_bs has to be replaced after deleting the block job,
     * otherwise this would fail because of lack of permissions. */
    if (commit_top_bs) {
        bdrv_drained_begin(top);
        bdrv_graph_wrlock();
        bdrv_replace_node(commit_top_bs, top, &error_abort);
        bdrv_graph_wrunlock();
        bdrv_drained_end(top);
    }
}


#define COMMIT_BUF_SIZE (2048 * BDRV_SECTOR_SIZE)

/* commit COW file into the raw image */
int bdrv_commit(BlockDriverState *bs)
{
    BlockBackend *src, *backing;
    BlockDriverState *backing_file_bs = NULL;
    BlockDriverState *commit_top_bs = NULL;
    BlockDriver *drv = bs->drv;
    AioContext *ctx;
    int64_t offset, length, backing_length;
    int ro;
    int64_t n;
    int ret = 0;
    QEMU_AUTO_VFREE uint8_t *buf = NULL;
    Error *local_err = NULL;

    GLOBAL_STATE_CODE();

    if (!drv)
        return -ENOMEDIUM;

    bdrv_drain_all_begin();
    bdrv_graph_rdlock_main_loop();

    backing_file_bs = bdrv_cow_bs(bs);

    if (!backing_file_bs) {
        ret = -ENOTSUP;
        goto out;
    }

    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_COMMIT_SOURCE, NULL) ||
        bdrv_op_is_blocked(backing_file_bs, BLOCK_OP_TYPE_COMMIT_TARGET, NULL))
    {
        ret = -EBUSY;
        goto out;
    }

    ro = bdrv_is_read_only(backing_file_bs);

    if (ro) {
        if (bdrv_reopen_set_read_only(backing_file_bs, false, NULL)) {
            ret = -EACCES;
            goto out;
        }
    }

    ctx = bdrv_get_aio_context(bs);
    /* WRITE_UNCHANGED is required for bdrv_make_empty() */
    src = blk_new(ctx, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED,
                  BLK_PERM_ALL);
    backing = blk_new(ctx, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);

    /* We drained all nodes, but still make requests through BlockBackends */
    blk_set_disable_request_queuing(src, true);
    blk_set_disable_request_queuing(backing, true);

    ret = blk_insert_bs(src, bs, &local_err);
    if (ret < 0) {
        error_report_err(local_err);
        goto ro_cleanup;
    }

    /* Insert commit_top block node above backing, so we can write to it */
    commit_top_bs = bdrv_new_open_driver(&bdrv_commit_top, NULL, BDRV_O_RDWR,
                                         &local_err);
    if (commit_top_bs == NULL) {
        error_report_err(local_err);
        goto ro_cleanup;
    }

    bdrv_graph_rdunlock_main_loop();

    bdrv_graph_wrlock();
    bdrv_set_backing_hd(commit_top_bs, backing_file_bs, &error_abort);
    bdrv_set_backing_hd(bs, commit_top_bs, &error_abort);
    bdrv_graph_wrunlock();

    bdrv_graph_rdlock_main_loop();

    ret = blk_insert_bs(backing, backing_file_bs, &local_err);
    if (ret < 0) {
        error_report_err(local_err);
        goto ro_cleanup;
    }

    length = blk_getlength(src);
    if (length < 0) {
        ret = length;
        goto ro_cleanup;
    }

    backing_length = blk_getlength(backing);
    if (backing_length < 0) {
        ret = backing_length;
        goto ro_cleanup;
    }

    /* If our top snapshot is larger than the backing file image,
     * grow the backing file image if possible.  If not possible,
     * we must return an error */
    if (length > backing_length) {
        ret = blk_truncate(backing, length, false, PREALLOC_MODE_OFF, 0,
                           &local_err);
        if (ret < 0) {
            error_report_err(local_err);
            goto ro_cleanup;
        }
    }

    /* blk_try_blockalign() for src will choose an alignment that works for
     * backing as well, so no need to compare the alignment manually. */
    buf = blk_try_blockalign(src, COMMIT_BUF_SIZE);
    if (buf == NULL) {
        ret = -ENOMEM;
        goto ro_cleanup;
    }

    for (offset = 0; offset < length; offset += n) {
        ret = bdrv_is_allocated(bs, offset, COMMIT_BUF_SIZE, &n);
        if (ret < 0) {
            goto ro_cleanup;
        }
        if (ret) {
            ret = blk_pread(src, offset, n, buf, 0);
            if (ret < 0) {
                goto ro_cleanup;
            }

            ret = blk_pwrite(backing, offset, n, buf, 0);
            if (ret < 0) {
                goto ro_cleanup;
            }
        }
    }

    ret = blk_make_empty(src, NULL);
    /* Ignore -ENOTSUP */
    if (ret < 0 && ret != -ENOTSUP) {
        goto ro_cleanup;
    }

    blk_flush(src);

    /*
     * Make sure all data we wrote to the backing device is actually
     * stable on disk.
     */
    blk_flush(backing);

    ret = 0;
ro_cleanup:
    blk_unref(backing);

    bdrv_graph_rdunlock_main_loop();
    bdrv_graph_wrlock();
    if (bdrv_cow_bs(bs) != backing_file_bs) {
        bdrv_set_backing_hd(bs, backing_file_bs, &error_abort);
    }
    bdrv_graph_wrunlock();
    bdrv_graph_rdlock_main_loop();
    bdrv_unref(commit_top_bs);
    blk_unref(src);

    if (ro) {
        /* ignoring error return here */
        bdrv_reopen_set_read_only(backing_file_bs, true, NULL);
    }

out:
    bdrv_graph_rdunlock_main_loop();
    bdrv_drain_all_end();

    return ret;
}
