static int sd_create(const char *filename, QemuOpts *opts,

                     Error **errp)

{

    int ret = 0;

    uint32_t vid = 0;

    char *backing_file = NULL;

    char *buf = NULL;

    BDRVSheepdogState *s;

    char tag[SD_MAX_VDI_TAG_LEN];

    uint32_t snapid;

    bool prealloc = false;



    s = g_malloc0(sizeof(BDRVSheepdogState));



    memset(tag, 0, sizeof(tag));

    if (strstr(filename, "://")) {

        ret = sd_parse_uri(s, filename, s->name, &snapid, tag);

    } else {

        ret = parse_vdiname(s, filename, s->name, &snapid, tag);

    }

    if (ret < 0) {

        error_setg(errp, "Can't parse filename");

        goto out;

    }



    s->inode.vdi_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);

    backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);

    buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);

    if (!buf || !strcmp(buf, "off")) {

        prealloc = false;

    } else if (!strcmp(buf, "full")) {

        prealloc = true;

    } else {

        error_setg(errp, "Invalid preallocation mode: '%s'", buf);

        ret = -EINVAL;

        goto out;

    }



    g_free(buf);

    buf = qemu_opt_get_del(opts, BLOCK_OPT_REDUNDANCY);

    if (buf) {

        ret = parse_redundancy(s, buf);

        if (ret < 0) {

            error_setg(errp, "Invalid redundancy mode: '%s'", buf);

            goto out;

        }

    }



    if (s->inode.vdi_size > SD_MAX_VDI_SIZE) {

        error_setg(errp, "too big image size");

        ret = -EINVAL;

        goto out;

    }



    if (backing_file) {

        BlockDriverState *bs;

        BDRVSheepdogState *base;

        BlockDriver *drv;



        /* Currently, only Sheepdog backing image is supported. */

        drv = bdrv_find_protocol(backing_file, true);

        if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) {

            error_setg(errp, "backing_file must be a sheepdog image");

            ret = -EINVAL;

            goto out;

        }



        bs = NULL;

        ret = bdrv_open(&bs, backing_file, NULL, NULL, BDRV_O_PROTOCOL, NULL,

                        errp);

        if (ret < 0) {

            goto out;

        }



        base = bs->opaque;



        if (!is_snapshot(&base->inode)) {

            error_setg(errp, "cannot clone from a non snapshot vdi");

            bdrv_unref(bs);

            ret = -EINVAL;

            goto out;

        }

        s->inode.vdi_id = base->inode.vdi_id;

        bdrv_unref(bs);

    }



    s->aio_context = qemu_get_aio_context();

    ret = do_sd_create(s, &vid, 0, errp);

    if (ret) {

        goto out;

    }



    if (prealloc) {

        ret = sd_prealloc(filename, errp);

    }

out:

    g_free(backing_file);

    g_free(buf);

    g_free(s);

    return ret;

}

static int sd_create(const char *filename, QemuOpts *opts,

                     Error **errp)

{

    int ret = 0;

    uint32_t vid = 0;

    char *backing_file = NULL;

    char *buf = NULL;

    BDRVSheepdogState *s;

    char tag[SD_MAX_VDI_TAG_LEN];

    uint32_t snapid;

    bool prealloc = false;



    s = g_malloc0(sizeof(BDRVSheepdogState));



    memset(tag, 0, sizeof(tag));

    if (strstr(filename, ":

        ret = sd_parse_uri(s, filename, s->name, &snapid, tag);

    } else {

        ret = parse_vdiname(s, filename, s->name, &snapid, tag);

    }

    if (ret < 0) {

        error_setg(errp, "Can't parse filename");

        goto out;

    }



    s->inode.vdi_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);

    backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);

    buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);

    if (!buf || !strcmp(buf, "off")) {

        prealloc = false;

    } else if (!strcmp(buf, "full")) {

        prealloc = true;

    } else {

        error_setg(errp, "Invalid preallocation mode: '%s'", buf);

        ret = -EINVAL;

        goto out;

    }



    g_free(buf);

    buf = qemu_opt_get_del(opts, BLOCK_OPT_REDUNDANCY);

    if (buf) {

        ret = parse_redundancy(s, buf);

        if (ret < 0) {

            error_setg(errp, "Invalid redundancy mode: '%s'", buf);

            goto out;

        }

    }



    if (s->inode.vdi_size > SD_MAX_VDI_SIZE) {

        error_setg(errp, "too big image size");

        ret = -EINVAL;

        goto out;

    }



    if (backing_file) {

        BlockDriverState *bs;

        BDRVSheepdogState *base;

        BlockDriver *drv;



        

        drv = bdrv_find_protocol(backing_file, true);

        if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) {

            error_setg(errp, "backing_file must be a sheepdog image");

            ret = -EINVAL;

            goto out;

        }



        bs = NULL;

        ret = bdrv_open(&bs, backing_file, NULL, NULL, BDRV_O_PROTOCOL, NULL,

                        errp);

        if (ret < 0) {

            goto out;

        }



        base = bs->opaque;



        if (!is_snapshot(&base->inode)) {

            error_setg(errp, "cannot clone from a non snapshot vdi");

            bdrv_unref(bs);

            ret = -EINVAL;

            goto out;

        }

        s->inode.vdi_id = base->inode.vdi_id;

        bdrv_unref(bs);

    }



    s->aio_context = qemu_get_aio_context();

    ret = do_sd_create(s, &vid, 0, errp);

    if (ret) {

        goto out;

    }



    if (prealloc) {

        ret = sd_prealloc(filename, errp);

    }

out:

    g_free(backing_file);

    g_free(buf);

    g_free(s);

    return ret;

}

    s = g_malloc0(sizeof(BDRVSheepdogState));
static int FUNC_0(const char *VAR_0, QemuOpts *VAR_1,

                     Error **VAR_2)

{

    int VAR_3 = 0;

    uint32_t vid = 0;

    char *VAR_4 = NULL;

    char *VAR_5 = NULL;

    BDRVSheepdogState *s;

    char VAR_6[SD_MAX_VDI_TAG_LEN];

    uint32_t snapid;

    bool prealloc = false;



    s = g_malloc0(sizeof(BDRVSheepdogState));



    memset(VAR_6, 0, sizeof(VAR_6));

    if (strstr(VAR_0, ":

        VAR_3 = sd_parse_uri(s, VAR_0, s->name, &snapid, VAR_6);

    } else {

        VAR_3 = parse_vdiname(s, VAR_0, s->name, &snapid, VAR_6);

    }

    if (VAR_3 < 0) {

        error_setg(VAR_2, "Can't parse VAR_0");

        goto out;

    }



    s->inode.vdi_size = qemu_opt_get_size_del(VAR_1, BLOCK_OPT_SIZE, 0);

    VAR_4 = qemu_opt_get_del(VAR_1, BLOCK_OPT_BACKING_FILE);

    VAR_5 = qemu_opt_get_del(VAR_1, BLOCK_OPT_PREALLOC);

    if (!VAR_5 || !strcmp(VAR_5, "off")) {

        prealloc = false;

    } else if (!strcmp(VAR_5, "full")) {

        prealloc = true;

    } else {

        error_setg(VAR_2, "Invalid preallocation mode: '%s'", VAR_5);

        VAR_3 = -EINVAL;

        goto out;

    }



    g_free(VAR_5);

    VAR_5 = qemu_opt_get_del(VAR_1, BLOCK_OPT_REDUNDANCY);

    if (VAR_5) {

        VAR_3 = parse_redundancy(s, VAR_5);

        if (VAR_3 < 0) {

            error_setg(VAR_2, "Invalid redundancy mode: '%s'", VAR_5);

            goto out;

        }

    }



    if (s->inode.vdi_size > SD_MAX_VDI_SIZE) {

        error_setg(VAR_2, "too big image size");

        VAR_3 = -EINVAL;

        goto out;

    }



    if (VAR_4) {

        BlockDriverState *bs;

        BDRVSheepdogState *base;

        BlockDriver *drv;



        

        drv = bdrv_find_protocol(VAR_4, true);

        if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) {

            error_setg(VAR_2, "VAR_4 must be a sheepdog image");

            VAR_3 = -EINVAL;

            goto out;

        }



        bs = NULL;

        VAR_3 = bdrv_open(&bs, VAR_4, NULL, NULL, BDRV_O_PROTOCOL, NULL,

                        VAR_2);

        if (VAR_3 < 0) {

            goto out;

        }



        base = bs->opaque;



        if (!is_snapshot(&base->inode)) {

            error_setg(VAR_2, "cannot clone from a non snapshot vdi");

            bdrv_unref(bs);

            VAR_3 = -EINVAL;

            goto out;

        }

        s->inode.vdi_id = base->inode.vdi_id;

        bdrv_unref(bs);

    }



    s->aio_context = qemu_get_aio_context();

    VAR_3 = do_sd_create(s, &vid, 0, VAR_2);

    if (VAR_3) {

        goto out;

    }



    if (prealloc) {

        VAR_3 = sd_prealloc(VAR_0, VAR_2);

    }

out:

    g_free(VAR_4);

    g_free(VAR_5);

    g_free(s);

    return VAR_3;

}

static int FUNC_0(const char *VAR_0, QemuOpts *VAR_1,
Error **VAR_2)
{ int VAR_3 = 0; uint32_t vid = 0; char *VAR_4 = NULL; char *VAR_5 = NULL; BDRVSheepdogState *s; char VAR_6[SD_MAX_VDI_TAG_LEN]; uint32_t snapid; bool prealloc = false; s = g_malloc0(sizeof(BDRVSheepdogState)); memset(VAR_6, 0, sizeof(VAR_6)); if (strstr(VAR_0, ":
VAR_3 = sd_parse_uri(s, VAR_0, s->name, &snapid, VAR_6); } else { VAR_3 = parse_vdiname(s, VAR_0, s->name, &snapid, VAR_6); } if (VAR_3 < 0) { error_setg(VAR_2, "Can't parse VAR_0"); goto out; } s->inode.vdi_size = qemu_opt_get_size_del(VAR_1, BLOCK_OPT_SIZE, 0); VAR_4 = qemu_opt_get_del(VAR_1, BLOCK_OPT_BACKING_FILE); VAR_5 = qemu_opt_get_del(VAR_1, BLOCK_OPT_PREALLOC); if (!VAR_5 || !strcmp(VAR_5, "off")) { prealloc = false; } else if (!strcmp(VAR_5, "full")) { prealloc = true; } else { error_setg(VAR_2, "Invalid preallocation mode: '%s'", VAR_5); VAR_3 = -EINVAL; goto out; } g_free(VAR_5); VAR_5 = qemu_opt_get_del(VAR_1, BLOCK_OPT_REDUNDANCY); if (VAR_5) { VAR_3 = parse_redundancy(s, VAR_5); if (VAR_3 < 0) { error_setg(VAR_2, "Invalid redundancy mode: '%s'", VAR_5); goto out; } } if (s->inode.vdi_size > SD_MAX_VDI_SIZE) { error_setg(VAR_2, "too big image size"); VAR_3 = -EINVAL; goto out; } if (VAR_4) { BlockDriverState *bs; BDRVSheepdogState *base; BlockDriver *drv; drv = bdrv_find_protocol(VAR_4, true); if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) { error_setg(VAR_2, "VAR_4 must be a sheepdog image"); VAR_3 = -EINVAL; goto out; } bs = NULL; VAR_3 = bdrv_open(&bs, VAR_4, NULL, NULL, BDRV_O_PROTOCOL, NULL,
VAR_2); if (VAR_3 < 0) { goto out; } base = bs->opaque; if (!is_snapshot(&base->inode)) { error_setg(VAR_2, "cannot clone from a non snapshot vdi"); bdrv_unref(bs); VAR_3 = -EINVAL; goto out; } s->inode.vdi_id = base->inode.vdi_id; bdrv_unref(bs); } s->aio_context = qemu_get_aio_context(); VAR_3 = do_sd_create(s, &vid, 0, VAR_2); if (VAR_3) { goto out; } if (prealloc) { VAR_3 = sd_prealloc(VAR_0, VAR_2); } out:
g_free(VAR_4); g_free(VAR_5); g_free(s); return VAR_3; }