static int qcow2_update_ext_header(BlockDriverState *bs,

    const char *backing_file, const char *backing_fmt)

{

    size_t backing_file_len = 0;

    size_t backing_fmt_len = 0;

    BDRVQcowState *s = bs->opaque;

    QCowExtension ext_backing_fmt = {0, 0};

    int ret;



    /* Backing file format doesn't make sense without a backing file */

    if (backing_fmt && !backing_file) {

        return -EINVAL;

    }



    /* Prepare the backing file format extension if needed */

    if (backing_fmt) {

        ext_backing_fmt.len = cpu_to_be32(strlen(backing_fmt));

        ext_backing_fmt.magic = cpu_to_be32(QCOW_EXT_MAGIC_BACKING_FORMAT);

        backing_fmt_len = ((sizeof(ext_backing_fmt)

            + strlen(backing_fmt) + 7) & ~7);

    }



    /* Check if we can fit the new header into the first cluster */

    if (backing_file) {

        backing_file_len = strlen(backing_file);

    }



    size_t header_size = sizeof(QCowHeader) + backing_file_len

        + backing_fmt_len;



    if (header_size > s->cluster_size) {

        return -ENOSPC;

    }



    /* Rewrite backing file name and qcow2 extensions */

    size_t ext_size = header_size - sizeof(QCowHeader);

    uint8_t buf[ext_size];

    size_t offset = 0;

    size_t backing_file_offset = 0;



    if (backing_file) {

        if (backing_fmt) {

            int padding = backing_fmt_len -

                (sizeof(ext_backing_fmt) + strlen(backing_fmt));



            memcpy(buf + offset, &ext_backing_fmt, sizeof(ext_backing_fmt));

            offset += sizeof(ext_backing_fmt);



            memcpy(buf + offset, backing_fmt, strlen(backing_fmt));

            offset += strlen(backing_fmt);



            memset(buf + offset, 0, padding);

            offset += padding;

        }



        memcpy(buf + offset, backing_file, backing_file_len);

        backing_file_offset = sizeof(QCowHeader) + offset;

    }



    ret = bdrv_pwrite(bs->file, sizeof(QCowHeader), buf, ext_size);

    if (ret < 0) {

        goto fail;

    }



    /* Update header fields */

    uint64_t be_backing_file_offset = cpu_to_be64(backing_file_offset);

    uint32_t be_backing_file_size = cpu_to_be32(backing_file_len);



    ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, backing_file_offset),

        &be_backing_file_offset, sizeof(uint64_t));

    if (ret < 0) {

        goto fail;

    }



    ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, backing_file_size),

        &be_backing_file_size, sizeof(uint32_t));

    if (ret < 0) {

        goto fail;

    }



    ret = 0;

fail:

    return ret;

}

static int qcow2_update_ext_header(BlockDriverState *bs,

    const char *backing_file, const char *backing_fmt)

{

    size_t backing_file_len = 0;

    size_t backing_fmt_len = 0;

    BDRVQcowState *s = bs->opaque;

    QCowExtension ext_backing_fmt = {0, 0};

    int ret;



    

    if (backing_fmt && !backing_file) {

        return -EINVAL;

    }



    

    if (backing_fmt) {

        ext_backing_fmt.len = cpu_to_be32(strlen(backing_fmt));

        ext_backing_fmt.magic = cpu_to_be32(QCOW_EXT_MAGIC_BACKING_FORMAT);

        backing_fmt_len = ((sizeof(ext_backing_fmt)

            + strlen(backing_fmt) + 7) & ~7);

    }



    

    if (backing_file) {

        backing_file_len = strlen(backing_file);

    }



    size_t header_size = sizeof(QCowHeader) + backing_file_len

        + backing_fmt_len;



    if (header_size > s->cluster_size) {

        return -ENOSPC;

    }



    

    size_t ext_size = header_size - sizeof(QCowHeader);

    uint8_t buf[ext_size];

    size_t offset = 0;

    size_t backing_file_offset = 0;



    if (backing_file) {

        if (backing_fmt) {

            int padding = backing_fmt_len -

                (sizeof(ext_backing_fmt) + strlen(backing_fmt));



            memcpy(buf + offset, &ext_backing_fmt, sizeof(ext_backing_fmt));

            offset += sizeof(ext_backing_fmt);



            memcpy(buf + offset, backing_fmt, strlen(backing_fmt));

            offset += strlen(backing_fmt);



            memset(buf + offset, 0, padding);

            offset += padding;

        }



        memcpy(buf + offset, backing_file, backing_file_len);

        backing_file_offset = sizeof(QCowHeader) + offset;

    }



    ret = bdrv_pwrite(bs->file, sizeof(QCowHeader), buf, ext_size);

    if (ret < 0) {

        goto fail;

    }



    

    uint64_t be_backing_file_offset = cpu_to_be64(backing_file_offset);

    uint32_t be_backing_file_size = cpu_to_be32(backing_file_len);



    ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, backing_file_offset),

        &be_backing_file_offset, sizeof(uint64_t));

    if (ret < 0) {

        goto fail;

    }



    ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, backing_file_size),

        &be_backing_file_size, sizeof(uint32_t));

    if (ret < 0) {

        goto fail;

    }



    ret = 0;

fail:

    return ret;

}

    ret = bdrv_pwrite(bs->file, sizeof(QCowHeader), buf, ext_size);     ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, backing_file_offset),     ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, backing_file_size),
static int FUNC_0(BlockDriverState *VAR_0,

    const char *VAR_1, const char *VAR_2)

{

    size_t backing_file_len = 0;

    size_t backing_fmt_len = 0;

    BDRVQcowState *s = VAR_0->opaque;

    QCowExtension ext_backing_fmt = {0, 0};

    int VAR_3;



    

    if (VAR_2 && !VAR_1) {

        return -EINVAL;

    }



    

    if (VAR_2) {

        ext_backing_fmt.len = cpu_to_be32(strlen(VAR_2));

        ext_backing_fmt.magic = cpu_to_be32(QCOW_EXT_MAGIC_BACKING_FORMAT);

        backing_fmt_len = ((sizeof(ext_backing_fmt)

            + strlen(VAR_2) + 7) & ~7);

    }



    

    if (VAR_1) {

        backing_file_len = strlen(VAR_1);

    }



    size_t header_size = sizeof(QCowHeader) + backing_file_len

        + backing_fmt_len;



    if (header_size > s->cluster_size) {

        return -ENOSPC;

    }



    

    size_t ext_size = header_size - sizeof(QCowHeader);

    uint8_t buf[ext_size];

    size_t offset = 0;

    size_t backing_file_offset = 0;



    if (VAR_1) {

        if (VAR_2) {

            int VAR_4 = backing_fmt_len -

                (sizeof(ext_backing_fmt) + strlen(VAR_2));



            memcpy(buf + offset, &ext_backing_fmt, sizeof(ext_backing_fmt));

            offset += sizeof(ext_backing_fmt);



            memcpy(buf + offset, VAR_2, strlen(VAR_2));

            offset += strlen(VAR_2);



            memset(buf + offset, 0, VAR_4);

            offset += VAR_4;

        }



        memcpy(buf + offset, VAR_1, backing_file_len);

        backing_file_offset = sizeof(QCowHeader) + offset;

    }



    VAR_3 = bdrv_pwrite(VAR_0->file, sizeof(QCowHeader), buf, ext_size);

    if (VAR_3 < 0) {

        goto fail;

    }



    

    uint64_t be_backing_file_offset = cpu_to_be64(backing_file_offset);

    uint32_t be_backing_file_size = cpu_to_be32(backing_file_len);



    VAR_3 = bdrv_pwrite(VAR_0->file, offsetof(QCowHeader, backing_file_offset),

        &be_backing_file_offset, sizeof(uint64_t));

    if (VAR_3 < 0) {

        goto fail;

    }



    VAR_3 = bdrv_pwrite(VAR_0->file, offsetof(QCowHeader, backing_file_size),

        &be_backing_file_size, sizeof(uint32_t));

    if (VAR_3 < 0) {

        goto fail;

    }



    VAR_3 = 0;

fail:

    return VAR_3;

}

static int FUNC_0(BlockDriverState *VAR_0,
const char *VAR_1, const char *VAR_2)
{ size_t backing_file_len = 0; size_t backing_fmt_len = 0; BDRVQcowState *s = VAR_0->opaque; QCowExtension ext_backing_fmt = {0, 0}; int VAR_3; if (VAR_2 && !VAR_1) { return -EINVAL; } if (VAR_2) { ext_backing_fmt.len = cpu_to_be32(strlen(VAR_2)); ext_backing_fmt.magic = cpu_to_be32(QCOW_EXT_MAGIC_BACKING_FORMAT); backing_fmt_len = ((sizeof(ext_backing_fmt)
+ strlen(VAR_2) + 7) & ~7); } if (VAR_1) { backing_file_len = strlen(VAR_1); } size_t header_size = sizeof(QCowHeader) + backing_file_len
+ backing_fmt_len; if (header_size > s->cluster_size) { return -ENOSPC; } size_t ext_size = header_size - sizeof(QCowHeader); uint8_t buf[ext_size]; size_t offset = 0; size_t backing_file_offset = 0; if (VAR_1) { if (VAR_2) { int VAR_4 = backing_fmt_len -
(sizeof(ext_backing_fmt) + strlen(VAR_2)); memcpy(buf + offset, &ext_backing_fmt, sizeof(ext_backing_fmt)); offset += sizeof(ext_backing_fmt); memcpy(buf + offset, VAR_2, strlen(VAR_2)); offset += strlen(VAR_2); memset(buf + offset, 0, VAR_4); offset += VAR_4; } memcpy(buf + offset, VAR_1, backing_file_len); backing_file_offset = sizeof(QCowHeader) + offset; } VAR_3 = bdrv_pwrite(VAR_0->file, sizeof(QCowHeader), buf, ext_size); if (VAR_3 < 0) { goto fail; } uint64_t be_backing_file_offset = cpu_to_be64(backing_file_offset); uint32_t be_backing_file_size = cpu_to_be32(backing_file_len); VAR_3 = bdrv_pwrite(VAR_0->file, offsetof(QCowHeader, backing_file_offset),
&be_backing_file_offset, sizeof(uint64_t)); if (VAR_3 < 0) { goto fail; } VAR_3 = bdrv_pwrite(VAR_0->file, offsetof(QCowHeader, backing_file_size),
&be_backing_file_size, sizeof(uint32_t)); if (VAR_3 < 0) { goto fail; } VAR_3 = 0; fail:
return VAR_3; }