mirror of https://gitee.com/openkylin/qemu.git
dmg: fix ->open failure
Currently the dmg image format driver simply opens the images as raw if any kind of failure happens. This is contrarty to the behaviour of all other image formats which just return an error and let the block core deal with it. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
49e75cf388
commit
1559ca00bc
28
block/dmg.c
28
block/dmg.c
|
@ -90,24 +90,21 @@ static int dmg_open(BlockDriverState *bs, const char *filename, int flags)
|
||||||
|
|
||||||
/* read offset of info blocks */
|
/* read offset of info blocks */
|
||||||
if(lseek(s->fd,-0x1d8,SEEK_END)<0) {
|
if(lseek(s->fd,-0x1d8,SEEK_END)<0) {
|
||||||
dmg_close:
|
goto fail;
|
||||||
close(s->fd);
|
|
||||||
/* open raw instead */
|
|
||||||
bs->drv=bdrv_find_format("raw");
|
|
||||||
return bs->drv->bdrv_open(bs, filename, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
info_begin=read_off(s->fd);
|
info_begin=read_off(s->fd);
|
||||||
if(info_begin==0)
|
if(info_begin==0)
|
||||||
goto dmg_close;
|
goto fail;
|
||||||
if(lseek(s->fd,info_begin,SEEK_SET)<0)
|
if(lseek(s->fd,info_begin,SEEK_SET)<0)
|
||||||
goto dmg_close;
|
goto fail;
|
||||||
if(read_uint32(s->fd)!=0x100)
|
if(read_uint32(s->fd)!=0x100)
|
||||||
goto dmg_close;
|
goto fail;
|
||||||
if((count = read_uint32(s->fd))==0)
|
if((count = read_uint32(s->fd))==0)
|
||||||
goto dmg_close;
|
goto fail;
|
||||||
info_end = info_begin+count;
|
info_end = info_begin+count;
|
||||||
if(lseek(s->fd,0xf8,SEEK_CUR)<0)
|
if(lseek(s->fd,0xf8,SEEK_CUR)<0)
|
||||||
goto dmg_close;
|
goto fail;
|
||||||
|
|
||||||
/* read offsets */
|
/* read offsets */
|
||||||
last_in_offset = last_out_offset = 0;
|
last_in_offset = last_out_offset = 0;
|
||||||
|
@ -116,14 +113,14 @@ dmg_close:
|
||||||
|
|
||||||
count = read_uint32(s->fd);
|
count = read_uint32(s->fd);
|
||||||
if(count==0)
|
if(count==0)
|
||||||
goto dmg_close;
|
goto fail;
|
||||||
type = read_uint32(s->fd);
|
type = read_uint32(s->fd);
|
||||||
if(type!=0x6d697368 || count<244)
|
if(type!=0x6d697368 || count<244)
|
||||||
lseek(s->fd,count-4,SEEK_CUR);
|
lseek(s->fd,count-4,SEEK_CUR);
|
||||||
else {
|
else {
|
||||||
int new_size, chunk_count;
|
int new_size, chunk_count;
|
||||||
if(lseek(s->fd,200,SEEK_CUR)<0)
|
if(lseek(s->fd,200,SEEK_CUR)<0)
|
||||||
goto dmg_close;
|
goto fail;
|
||||||
chunk_count = (count-204)/40;
|
chunk_count = (count-204)/40;
|
||||||
new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);
|
new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);
|
||||||
s->types = qemu_realloc(s->types, new_size/2);
|
s->types = qemu_realloc(s->types, new_size/2);
|
||||||
|
@ -142,7 +139,7 @@ dmg_close:
|
||||||
chunk_count--;
|
chunk_count--;
|
||||||
i--;
|
i--;
|
||||||
if(lseek(s->fd,36,SEEK_CUR)<0)
|
if(lseek(s->fd,36,SEEK_CUR)<0)
|
||||||
goto dmg_close;
|
goto fail;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
read_uint32(s->fd);
|
read_uint32(s->fd);
|
||||||
|
@ -163,11 +160,14 @@ dmg_close:
|
||||||
s->compressed_chunk = qemu_malloc(max_compressed_size+1);
|
s->compressed_chunk = qemu_malloc(max_compressed_size+1);
|
||||||
s->uncompressed_chunk = qemu_malloc(512*max_sectors_per_chunk);
|
s->uncompressed_chunk = qemu_malloc(512*max_sectors_per_chunk);
|
||||||
if(inflateInit(&s->zstream) != Z_OK)
|
if(inflateInit(&s->zstream) != Z_OK)
|
||||||
goto dmg_close;
|
goto fail;
|
||||||
|
|
||||||
s->current_chunk = s->n_chunks;
|
s->current_chunk = s->n_chunks;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
fail:
|
||||||
|
close(s->fd);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int is_sector_in_chunk(BDRVDMGState* s,
|
static inline int is_sector_in_chunk(BDRVDMGState* s,
|
||||||
|
|
Loading…
Reference in New Issue