⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 block-qcow2.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
            qemu_free(out_buf);            return -1;        }    }    qemu_free(out_buf);    return 0;}static void qcow_flush(BlockDriverState *bs){    BDRVQcowState *s = bs->opaque;    bdrv_flush(s->hd);}static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi){    BDRVQcowState *s = bs->opaque;    bdi->cluster_size = s->cluster_size;    bdi->vm_state_offset = (int64_t)s->l1_vm_state_index <<        (s->cluster_bits + s->l2_bits);    return 0;}/*********************************************************//* snapshot support *//* update the refcounts of snapshots and the copied flag */static int update_snapshot_refcount(BlockDriverState *bs,                                    int64_t l1_table_offset,                                    int l1_size,                                    int addend){    BDRVQcowState *s = bs->opaque;    uint64_t *l1_table, *l2_table, l2_offset, offset, l1_size2, l1_allocated;    int64_t old_offset, old_l2_offset;    int l2_size, i, j, l1_modified, l2_modified, nb_csectors, refcount;    l2_cache_reset(bs);    l2_table = NULL;    l1_table = NULL;    l1_size2 = l1_size * sizeof(uint64_t);    l1_allocated = 0;    if (l1_table_offset != s->l1_table_offset) {        l1_table = qemu_malloc(l1_size2);        if (!l1_table)            goto fail;        l1_allocated = 1;        if (bdrv_pread(s->hd, l1_table_offset,                       l1_table, l1_size2) != l1_size2)            goto fail;        for(i = 0;i < l1_size; i++)            be64_to_cpus(&l1_table[i]);    } else {        assert(l1_size == s->l1_size);        l1_table = s->l1_table;        l1_allocated = 0;    }    l2_size = s->l2_size * sizeof(uint64_t);    l2_table = qemu_malloc(l2_size);    if (!l2_table)        goto fail;    l1_modified = 0;    for(i = 0; i < l1_size; i++) {        l2_offset = l1_table[i];        if (l2_offset) {            old_l2_offset = l2_offset;            l2_offset &= ~QCOW_OFLAG_COPIED;            l2_modified = 0;            if (bdrv_pread(s->hd, l2_offset, l2_table, l2_size) != l2_size)                goto fail;            for(j = 0; j < s->l2_size; j++) {                offset = be64_to_cpu(l2_table[j]);                if (offset != 0) {                    old_offset = offset;                    offset &= ~QCOW_OFLAG_COPIED;                    if (offset & QCOW_OFLAG_COMPRESSED) {                        nb_csectors = ((offset >> s->csize_shift) &                                       s->csize_mask) + 1;                        if (addend != 0)                            update_refcount(bs, (offset & s->cluster_offset_mask) & ~511,                                            nb_csectors * 512, addend);                        /* compressed clusters are never modified */                        refcount = 2;                    } else {                        if (addend != 0) {                            refcount = update_cluster_refcount(bs, offset >> s->cluster_bits, addend);                        } else {                            refcount = get_refcount(bs, offset >> s->cluster_bits);                        }                    }                    if (refcount == 1) {                        offset |= QCOW_OFLAG_COPIED;                    }                    if (offset != old_offset) {                        l2_table[j] = cpu_to_be64(offset);                        l2_modified = 1;                    }                }            }            if (l2_modified) {                if (bdrv_pwrite(s->hd,                                l2_offset, l2_table, l2_size) != l2_size)                    goto fail;            }            if (addend != 0) {                refcount = update_cluster_refcount(bs, l2_offset >> s->cluster_bits, addend);            } else {                refcount = get_refcount(bs, l2_offset >> s->cluster_bits);            }            if (refcount == 1) {                l2_offset |= QCOW_OFLAG_COPIED;            }            if (l2_offset != old_l2_offset) {                l1_table[i] = l2_offset;                l1_modified = 1;            }        }    }    if (l1_modified) {        for(i = 0; i < l1_size; i++)            cpu_to_be64s(&l1_table[i]);        if (bdrv_pwrite(s->hd, l1_table_offset, l1_table,                        l1_size2) != l1_size2)            goto fail;        for(i = 0; i < l1_size; i++)            be64_to_cpus(&l1_table[i]);    }    if (l1_allocated)        qemu_free(l1_table);    qemu_free(l2_table);    return 0; fail:    if (l1_allocated)        qemu_free(l1_table);    qemu_free(l2_table);    return -EIO;}static void qcow_free_snapshots(BlockDriverState *bs){    BDRVQcowState *s = bs->opaque;    int i;    for(i = 0; i < s->nb_snapshots; i++) {        qemu_free(s->snapshots[i].name);        qemu_free(s->snapshots[i].id_str);    }    qemu_free(s->snapshots);    s->snapshots = NULL;    s->nb_snapshots = 0;}static int qcow_read_snapshots(BlockDriverState *bs){    BDRVQcowState *s = bs->opaque;    QCowSnapshotHeader h;    QCowSnapshot *sn;    int i, id_str_size, name_size;    int64_t offset;    uint32_t extra_data_size;    offset = s->snapshots_offset;    s->snapshots = qemu_mallocz(s->nb_snapshots * sizeof(QCowSnapshot));    if (!s->snapshots)        goto fail;    for(i = 0; i < s->nb_snapshots; i++) {        offset = align_offset(offset, 8);        if (bdrv_pread(s->hd, offset, &h, sizeof(h)) != sizeof(h))            goto fail;        offset += sizeof(h);        sn = s->snapshots + i;        sn->l1_table_offset = be64_to_cpu(h.l1_table_offset);        sn->l1_size = be32_to_cpu(h.l1_size);        sn->vm_state_size = be32_to_cpu(h.vm_state_size);        sn->date_sec = be32_to_cpu(h.date_sec);        sn->date_nsec = be32_to_cpu(h.date_nsec);        sn->vm_clock_nsec = be64_to_cpu(h.vm_clock_nsec);        extra_data_size = be32_to_cpu(h.extra_data_size);        id_str_size = be16_to_cpu(h.id_str_size);        name_size = be16_to_cpu(h.name_size);        offset += extra_data_size;        sn->id_str = qemu_malloc(id_str_size + 1);        if (!sn->id_str)            goto fail;        if (bdrv_pread(s->hd, offset, sn->id_str, id_str_size) != id_str_size)            goto fail;        offset += id_str_size;        sn->id_str[id_str_size] = '\0';        sn->name = qemu_malloc(name_size + 1);        if (!sn->name)            goto fail;        if (bdrv_pread(s->hd, offset, sn->name, name_size) != name_size)            goto fail;        offset += name_size;        sn->name[name_size] = '\0';    }    s->snapshots_size = offset - s->snapshots_offset;    return 0; fail:    qcow_free_snapshots(bs);    return -1;}/* add at the end of the file a new list of snapshots */static int qcow_write_snapshots(BlockDriverState *bs){    BDRVQcowState *s = bs->opaque;    QCowSnapshot *sn;    QCowSnapshotHeader h;    int i, name_size, id_str_size, snapshots_size;    uint64_t data64;    uint32_t data32;    int64_t offset, snapshots_offset;    /* compute the size of the snapshots */    offset = 0;    for(i = 0; i < s->nb_snapshots; i++) {        sn = s->snapshots + i;        offset = align_offset(offset, 8);        offset += sizeof(h);        offset += strlen(sn->id_str);        offset += strlen(sn->name);    }    snapshots_size = offset;    snapshots_offset = alloc_clusters(bs, snapshots_size);    offset = snapshots_offset;    for(i = 0; i < s->nb_snapshots; i++) {        sn = s->snapshots + i;        memset(&h, 0, sizeof(h));        h.l1_table_offset = cpu_to_be64(sn->l1_table_offset);        h.l1_size = cpu_to_be32(sn->l1_size);        h.vm_state_size = cpu_to_be32(sn->vm_state_size);        h.date_sec = cpu_to_be32(sn->date_sec);        h.date_nsec = cpu_to_be32(sn->date_nsec);        h.vm_clock_nsec = cpu_to_be64(sn->vm_clock_nsec);        id_str_size = strlen(sn->id_str);        name_size = strlen(sn->name);        h.id_str_size = cpu_to_be16(id_str_size);        h.name_size = cpu_to_be16(name_size);        offset = align_offset(offset, 8);        if (bdrv_pwrite(s->hd, offset, &h, sizeof(h)) != sizeof(h))            goto fail;        offset += sizeof(h);        if (bdrv_pwrite(s->hd, offset, sn->id_str, id_str_size) != id_str_size)            goto fail;        offset += id_str_size;        if (bdrv_pwrite(s->hd, offset, sn->name, name_size) != name_size)            goto fail;        offset += name_size;    }    /* update the various header fields */    data64 = cpu_to_be64(snapshots_offset);    if (bdrv_pwrite(s->hd, offsetof(QCowHeader, snapshots_offset),                    &data64, sizeof(data64)) != sizeof(data64))        goto fail;    data32 = cpu_to_be32(s->nb_snapshots);    if (bdrv_pwrite(s->hd, offsetof(QCowHeader, nb_snapshots),                    &data32, sizeof(data32)) != sizeof(data32))        goto fail;    /* free the old snapshot table */    free_clusters(bs, s->snapshots_offset, s->snapshots_size);    s->snapshots_offset = snapshots_offset;    s->snapshots_size = snapshots_size;    return 0; fail:    return -1;}static void find_new_snapshot_id(BlockDriverState *bs,                                 char *id_str, int id_str_size){    BDRVQcowState *s = bs->opaque;    QCowSnapshot *sn;    int i, id, id_max = 0;    for(i = 0; i < s->nb_snapshots; i++) {        sn = s->snapshots + i;        id = strtoul(sn->id_str, NULL, 10);        if (id > id_max)            id_max = id;    }    snprintf(id_str, id_str_size, "%d", id_max + 1);}static int find_snapshot_by_id(BlockDriverState *bs, const char *id_str){    BDRVQcowState *s = bs->opaque;    int i;    for(i = 0; i < s->nb_snapshots; i++) {        if (!strcmp(s->snapshots[i].id_str, id_str))            return i;    }    return -1;}static int find_snapshot_by_id_or_name(BlockDriverState *bs, const char *name){    BDRVQcowState *s = bs->opaque;    int i, ret;    ret = find_snapshot_by_id(bs, name);    if (ret >= 0)        return ret;    for(i = 0; i < s->nb_snapshots; i++) {        if (!strcmp(s->snapshots[i].name, name))            return i;    }    return -1;}/* if no id is provided, a new one is constructed */static int qcow_snapshot_create(BlockDriverState *bs,                                QEMUSnapshotInfo *sn_info){    BDRVQcowState *s = bs->opaque;    QCowSnapshot *snapshots1, sn1, *sn = &sn1;    int i, ret;    uint64_t *l1_table = NULL;    memset(sn, 0, sizeof(*sn));    if (sn_info->id_str[0] == '\0') {        /* compute a new id */        find_new_snapshot_id(bs, sn_info->id_str, sizeof(sn_info->id_str));    }    /* check that the ID is unique */    if (find_snapshot_by_id(bs, sn_info->id_str) >= 0)        return -ENOENT;    sn->id_str = qemu_strdup(sn_info->id_str);    if (!sn->id_str)        goto fail;    sn->name = qemu_strdup(sn_info->name);    if (!sn->name)        goto fail;    sn->vm_state_size = sn_info->vm_state_size;    sn->date_sec = sn_info->date_sec;    sn->date_nsec = sn_info->date_nsec;    sn->vm_clock_nsec = sn_info->vm_clock_nsec;    ret = update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 1);    if (ret < 0)        goto fail;    /* create the L1 table of the snapshot */    sn->l1_table_offset = alloc_clusters(bs, s->l1_size * sizeof(uint64_t));    sn->l1_size = s->l1_size;    l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));    if (!l1_table)        goto fail;    for(i = 0; i < s->l1_size; i++) {        l1_table[i] = cpu_to_be64(s->l1_table[i]);    }    if (bdrv_pwrite(s->hd, sn->l1_table_offset,                    l1_table, s->l1_size * sizeof(uint64_t)) !=        (s->l1_size * sizeof(uint64_t)))        goto fail;    qemu_free(l1_table);    l1_table = NULL;    snapshots1 = qemu_malloc((s->nb_snapshots + 1) * sizeof(QCowSnapshot));    if (!snapshots1)        goto fail;    memcpy(snapshots1, s->snapshots, s->nb_snapshots * sizeof(QCowSnapshot));    s->snapshots = snapshots1;    s->snapshots[s->nb_snapshots++] = *sn;    if (qcow_write_snapshots(bs) < 0)        goto fail;#ifdef DEBUG_ALLOC    check_refcounts(bs);#endif    return 0; fail:    qemu_free(sn->name);    qemu_free(l1_table);    return -1;}/* copy the snapshot 'snapshot_name' into the current disk image */static int qcow_snapshot_goto(BlockDriverState *bs,                              const char *snapshot_id){    BDRVQcowState *s = bs->opaque;    QCowSnapshot *sn;    int i, snapshot_index, l1_size2;    snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id);    if (snapshot_index < 0)        return -ENOENT;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -