qcow2: Return real error code in qcow2_write_snapshots

Doesn't immediately fix anything as the callers don't use the return
value, but they will be fixed next.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
This commit is contained in:
Kevin Wolf 2011-11-16 12:00:59 +01:00
parent 42deb29fed
commit 07fd877900
1 changed files with 38 additions and 10 deletions

View File

@ -140,6 +140,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
uint64_t data64; uint64_t data64;
uint32_t data32; uint32_t data32;
int64_t offset, snapshots_offset; int64_t offset, snapshots_offset;
int ret;
/* compute the size of the snapshots */ /* compute the size of the snapshots */
offset = 0; offset = 0;
@ -152,6 +153,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
} }
snapshots_size = offset; snapshots_size = offset;
/* Allocate space for the new snapshot list */
snapshots_offset = qcow2_alloc_clusters(bs, snapshots_size); snapshots_offset = qcow2_alloc_clusters(bs, snapshots_size);
bdrv_flush(bs->file); bdrv_flush(bs->file);
offset = snapshots_offset; offset = snapshots_offset;
@ -159,6 +161,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
return offset; return offset;
} }
/* Write all snapshots to the new list */
for(i = 0; i < s->nb_snapshots; i++) { for(i = 0; i < s->nb_snapshots; i++) {
sn = s->snapshots + i; sn = s->snapshots + i;
memset(&h, 0, sizeof(h)); memset(&h, 0, sizeof(h));
@ -174,34 +177,59 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
h.id_str_size = cpu_to_be16(id_str_size); h.id_str_size = cpu_to_be16(id_str_size);
h.name_size = cpu_to_be16(name_size); h.name_size = cpu_to_be16(name_size);
offset = align_offset(offset, 8); offset = align_offset(offset, 8);
if (bdrv_pwrite_sync(bs->file, offset, &h, sizeof(h)) < 0)
ret = bdrv_pwrite(bs->file, offset, &h, sizeof(h));
if (ret < 0) {
goto fail; goto fail;
}
offset += sizeof(h); offset += sizeof(h);
if (bdrv_pwrite_sync(bs->file, offset, sn->id_str, id_str_size) < 0)
ret = bdrv_pwrite(bs->file, offset, sn->id_str, id_str_size);
if (ret < 0) {
goto fail; goto fail;
}
offset += id_str_size; offset += id_str_size;
if (bdrv_pwrite_sync(bs->file, offset, sn->name, name_size) < 0)
ret = bdrv_pwrite(bs->file, offset, sn->name, name_size);
if (ret < 0) {
goto fail; goto fail;
}
offset += name_size; offset += name_size;
} }
/* update the various header fields */ /*
* Update the header to point to the new snapshot table. This requires the
* new table and its refcounts to be stable on disk.
*
* FIXME This should be done with a single write
*/
ret = bdrv_flush(bs);
if (ret < 0) {
goto fail;
}
data64 = cpu_to_be64(snapshots_offset); data64 = cpu_to_be64(snapshots_offset);
if (bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, snapshots_offset), ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, snapshots_offset),
&data64, sizeof(data64)) < 0) &data64, sizeof(data64));
if (ret < 0) {
goto fail; goto fail;
}
data32 = cpu_to_be32(s->nb_snapshots); data32 = cpu_to_be32(s->nb_snapshots);
if (bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, nb_snapshots), ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, nb_snapshots),
&data32, sizeof(data32)) < 0) &data32, sizeof(data32));
if (ret < 0) {
goto fail; goto fail;
}
/* free the old snapshot table */ /* free the old snapshot table */
qcow2_free_clusters(bs, s->snapshots_offset, s->snapshots_size); qcow2_free_clusters(bs, s->snapshots_offset, s->snapshots_size);
s->snapshots_offset = snapshots_offset; s->snapshots_offset = snapshots_offset;
s->snapshots_size = snapshots_size; s->snapshots_size = snapshots_size;
return 0; return 0;
fail:
return -1; fail:
return ret;
} }
static void find_new_snapshot_id(BlockDriverState *bs, static void find_new_snapshot_id(BlockDriverState *bs,