diff options
author | David 'Digit' Turner <digit@android.com> | 2010-12-23 02:54:08 +0100 |
---|---|---|
committer | David 'Digit' Turner <digit@android.com> | 2011-01-02 22:31:27 +0100 |
commit | cb42a1b1461e02efb034582ac5d8f71534723b92 (patch) | |
tree | 5dbd619671d4591d33834488f1c15690dabf50ba /block/qcow2-snapshot.c | |
parent | ca6a2e034bce665a08d9d748ac11d6a7cfcd7c48 (diff) | |
download | external_qemu-cb42a1b1461e02efb034582ac5d8f71534723b92.zip external_qemu-cb42a1b1461e02efb034582ac5d8f71534723b92.tar.gz external_qemu-cb42a1b1461e02efb034582ac5d8f71534723b92.tar.bz2 |
upstream: integrate block changes
This large patch upgrades the block support code to the upstream
version available in ba5e7f82169f32ab8163c707d97c799ca09f8924
dated 2010-08-08
Change-Id: I8b24df0c287e72f6620650a4d6a62e1bb315453e
Diffstat (limited to 'block/qcow2-snapshot.c')
-rw-r--r-- | block/qcow2-snapshot.c | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index e1e4d89..6228612 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -79,7 +79,7 @@ int qcow2_read_snapshots(BlockDriverState *bs) s->snapshots = qemu_mallocz(s->nb_snapshots * sizeof(QCowSnapshot)); for(i = 0; i < s->nb_snapshots; i++) { offset = align_offset(offset, 8); - if (bdrv_pread(s->hd, offset, &h, sizeof(h)) != sizeof(h)) + if (bdrv_pread(bs->file, offset, &h, sizeof(h)) != sizeof(h)) goto fail; offset += sizeof(h); sn = s->snapshots + i; @@ -97,13 +97,13 @@ int qcow2_read_snapshots(BlockDriverState *bs) offset += extra_data_size; sn->id_str = qemu_malloc(id_str_size + 1); - if (bdrv_pread(s->hd, offset, sn->id_str, id_str_size) != id_str_size) + if (bdrv_pread(bs->file, 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 (bdrv_pread(s->hd, offset, sn->name, name_size) != name_size) + if (bdrv_pread(bs->file, offset, sn->name, name_size) != name_size) goto fail; offset += name_size; sn->name[name_size] = '\0'; @@ -139,6 +139,9 @@ static int qcow_write_snapshots(BlockDriverState *bs) snapshots_offset = qcow2_alloc_clusters(bs, snapshots_size); offset = snapshots_offset; + if (offset < 0) { + return offset; + } for(i = 0; i < s->nb_snapshots; i++) { sn = s->snapshots + i; @@ -155,25 +158,25 @@ static int qcow_write_snapshots(BlockDriverState *bs) 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)) + if (bdrv_pwrite_sync(bs->file, offset, &h, sizeof(h)) < 0) goto fail; offset += sizeof(h); - if (bdrv_pwrite(s->hd, offset, sn->id_str, id_str_size) != id_str_size) + if (bdrv_pwrite_sync(bs->file, offset, sn->id_str, id_str_size) < 0) goto fail; offset += id_str_size; - if (bdrv_pwrite(s->hd, offset, sn->name, name_size) != name_size) + if (bdrv_pwrite_sync(bs->file, offset, sn->name, name_size) < 0) 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)) + if (bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, snapshots_offset), + &data64, sizeof(data64)) < 0) goto fail; data32 = cpu_to_be32(s->nb_snapshots); - if (bdrv_pwrite(s->hd, offsetof(QCowHeader, nb_snapshots), - &data32, sizeof(data32)) != sizeof(data32)) + if (bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, nb_snapshots), + &data32, sizeof(data32)) < 0) goto fail; /* free the old snapshot table */ @@ -235,6 +238,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) QCowSnapshot *snapshots1, sn1, *sn = &sn1; int i, ret; uint64_t *l1_table = NULL; + int64_t l1_table_offset; memset(sn, 0, sizeof(*sn)); @@ -263,16 +267,25 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) goto fail; /* create the L1 table of the snapshot */ - sn->l1_table_offset = qcow2_alloc_clusters(bs, s->l1_size * sizeof(uint64_t)); + l1_table_offset = qcow2_alloc_clusters(bs, s->l1_size * sizeof(uint64_t)); + if (l1_table_offset < 0) { + goto fail; + } + + sn->l1_table_offset = l1_table_offset; sn->l1_size = s->l1_size; - l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t)); + if (s->l1_size != 0) { + l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t)); + } else { + l1_table = NULL; + } + 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))) + if (bdrv_pwrite_sync(bs->file, sn->l1_table_offset, + l1_table, s->l1_size * sizeof(uint64_t)) < 0) goto fail; qemu_free(l1_table); l1_table = NULL; @@ -288,7 +301,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) if (qcow_write_snapshots(bs) < 0) goto fail; #ifdef DEBUG_ALLOC - check_refcounts(bs); + qcow2_check_refcounts(bs); #endif return 0; fail: @@ -318,11 +331,11 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) s->l1_size = sn->l1_size; l1_size2 = s->l1_size * sizeof(uint64_t); /* copy the snapshot l1 table to the current l1 table */ - if (bdrv_pread(s->hd, sn->l1_table_offset, + if (bdrv_pread(bs->file, sn->l1_table_offset, s->l1_table, l1_size2) != l1_size2) goto fail; - if (bdrv_pwrite(s->hd, s->l1_table_offset, - s->l1_table, l1_size2) != l1_size2) + if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, + s->l1_table, l1_size2) < 0) goto fail; for(i = 0;i < s->l1_size; i++) { be64_to_cpus(&s->l1_table[i]); @@ -332,7 +345,7 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) goto fail; #ifdef DEBUG_ALLOC - check_refcounts(bs); + qcow2_check_refcounts(bs); #endif return 0; fail: @@ -369,7 +382,7 @@ int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) return ret; } #ifdef DEBUG_ALLOC - check_refcounts(bs); + qcow2_check_refcounts(bs); #endif return 0; } |