qcow2: Return real error code in qcow2_read_snapshots

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 11:43:28 +01:00
parent a968168c58
commit 42deb29fed
2 changed files with 23 additions and 7 deletions

View File

@ -68,6 +68,7 @@ int qcow2_read_snapshots(BlockDriverState *bs)
int i, id_str_size, name_size; int i, id_str_size, name_size;
int64_t offset; int64_t offset;
uint32_t extra_data_size; uint32_t extra_data_size;
int ret;
if (!s->nb_snapshots) { if (!s->nb_snapshots) {
s->snapshots = NULL; s->snapshots = NULL;
@ -77,10 +78,15 @@ int qcow2_read_snapshots(BlockDriverState *bs)
offset = s->snapshots_offset; offset = s->snapshots_offset;
s->snapshots = g_malloc0(s->nb_snapshots * sizeof(QCowSnapshot)); s->snapshots = g_malloc0(s->nb_snapshots * sizeof(QCowSnapshot));
for(i = 0; i < s->nb_snapshots; i++) { for(i = 0; i < s->nb_snapshots; i++) {
/* Read statically sized part of the snapshot header */
offset = align_offset(offset, 8); offset = align_offset(offset, 8);
if (bdrv_pread(bs->file, offset, &h, sizeof(h)) != sizeof(h)) ret = bdrv_pread(bs->file, offset, &h, sizeof(h));
if (ret < 0) {
goto fail; goto fail;
}
offset += sizeof(h); offset += sizeof(h);
sn = s->snapshots + i; sn = s->snapshots + i;
sn->l1_table_offset = be64_to_cpu(h.l1_table_offset); sn->l1_table_offset = be64_to_cpu(h.l1_table_offset);
@ -94,25 +100,34 @@ int qcow2_read_snapshots(BlockDriverState *bs)
id_str_size = be16_to_cpu(h.id_str_size); id_str_size = be16_to_cpu(h.id_str_size);
name_size = be16_to_cpu(h.name_size); name_size = be16_to_cpu(h.name_size);
/* Skip extra data */
offset += extra_data_size; offset += extra_data_size;
/* Read snapshot ID */
sn->id_str = g_malloc(id_str_size + 1); sn->id_str = g_malloc(id_str_size + 1);
if (bdrv_pread(bs->file, offset, sn->id_str, id_str_size) != id_str_size) ret = bdrv_pread(bs->file, offset, sn->id_str, id_str_size);
if (ret < 0) {
goto fail; goto fail;
}
offset += id_str_size; offset += id_str_size;
sn->id_str[id_str_size] = '\0'; sn->id_str[id_str_size] = '\0';
/* Read snapshot name */
sn->name = g_malloc(name_size + 1); sn->name = g_malloc(name_size + 1);
if (bdrv_pread(bs->file, offset, sn->name, name_size) != name_size) ret = bdrv_pread(bs->file, offset, sn->name, name_size);
if (ret < 0) {
goto fail; goto fail;
}
offset += name_size; offset += name_size;
sn->name[name_size] = '\0'; sn->name[name_size] = '\0';
} }
s->snapshots_size = offset - s->snapshots_offset; s->snapshots_size = offset - s->snapshots_offset;
return 0; return 0;
fail:
fail:
qcow2_free_snapshots(bs); qcow2_free_snapshots(bs);
return -1; return ret;
} }
/* add at the end of the file a new list of snapshots */ /* add at the end of the file a new list of snapshots */

View File

@ -273,8 +273,9 @@ static int qcow2_open(BlockDriverState *bs, int flags)
} }
bs->backing_file[len] = '\0'; bs->backing_file[len] = '\0';
} }
if (qcow2_read_snapshots(bs) < 0) {
ret = -EINVAL; ret = qcow2_read_snapshots(bs);
if (ret < 0) {
goto fail; goto fail;
} }