Skip to content

Commit

Permalink
Merge remote-tracking branch 'stefanha/block' into staging
Browse files Browse the repository at this point in the history
# By Kevin Wolf (7) and others
# Via Stefan Hajnoczi
* stefanha/block:
  block/raw-posix: Build fix for O_ASYNC
  vmdk: Allow space in file name
  parallels: Fix bdrv_open() error handling
  dmg: Use g_free instead of free
  dmg: Fix bdrv_open() error handling
  vpc: Fix bdrv_open() error handling
  cloop: Fix bdrv_open() error handling
  bochs: Fix bdrv_open() error handling
  sheepdog: pass vdi_id to sheep daemon for sd_close()
  vmdk: Allow selecting SCSI adapter in image creation
  block: Adds mirroring tests for resized images
  block: Fix is_allocated_above with resized files
  qemu-iotests: Add regression test for b7ab0fe
  • Loading branch information
Anthony Liguori committed Feb 1, 2013
2 parents 3e3648b + fdf263f commit 77a5f4f
Show file tree
Hide file tree
Showing 15 changed files with 379 additions and 102 deletions.
4 changes: 3 additions & 1 deletion block.c
Expand Up @@ -2800,7 +2800,9 @@ int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top,
*
* [sector_num+x, nr_sectors] allocated.
*/
if (n > pnum_inter) {
if (n > pnum_inter &&
(intermediate == top ||
sector_num + pnum_inter < intermediate->total_sectors)) {
n = pnum_inter;
}

Expand Down
22 changes: 15 additions & 7 deletions block/bochs.c
Expand Up @@ -114,11 +114,13 @@ static int bochs_open(BlockDriverState *bs, int flags)
int i;
struct bochs_header bochs;
struct bochs_header_v1 header_v1;
int ret;

bs->read_only = 1; // no write support yet

if (bdrv_pread(bs->file, 0, &bochs, sizeof(bochs)) != sizeof(bochs)) {
goto fail;
ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
if (ret < 0) {
return ret;
}

if (strcmp(bochs.magic, HEADER_MAGIC) ||
Expand All @@ -138,9 +140,13 @@ static int bochs_open(BlockDriverState *bs, int flags)

s->catalog_size = le32_to_cpu(bochs.extra.redolog.catalog);
s->catalog_bitmap = g_malloc(s->catalog_size * 4);
if (bdrv_pread(bs->file, le32_to_cpu(bochs.header), s->catalog_bitmap,
s->catalog_size * 4) != s->catalog_size * 4)
goto fail;

ret = bdrv_pread(bs->file, le32_to_cpu(bochs.header), s->catalog_bitmap,
s->catalog_size * 4);
if (ret < 0) {
goto fail;
}

for (i = 0; i < s->catalog_size; i++)
le32_to_cpus(&s->catalog_bitmap[i]);

Expand All @@ -153,8 +159,10 @@ static int bochs_open(BlockDriverState *bs, int flags)

qemu_co_mutex_init(&s->lock);
return 0;
fail:
return -1;

fail:
g_free(s->catalog_bitmap);
return ret;
}

static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
Expand Down
29 changes: 19 additions & 10 deletions block/cloop.c
Expand Up @@ -57,27 +57,32 @@ static int cloop_open(BlockDriverState *bs, int flags)
{
BDRVCloopState *s = bs->opaque;
uint32_t offsets_size, max_compressed_block_size = 1, i;
int ret;

bs->read_only = 1;

/* read header */
if (bdrv_pread(bs->file, 128, &s->block_size, 4) < 4) {
goto cloop_close;
ret = bdrv_pread(bs->file, 128, &s->block_size, 4);
if (ret < 0) {
return ret;
}
s->block_size = be32_to_cpu(s->block_size);

if (bdrv_pread(bs->file, 128 + 4, &s->n_blocks, 4) < 4) {
goto cloop_close;
ret = bdrv_pread(bs->file, 128 + 4, &s->n_blocks, 4);
if (ret < 0) {
return ret;
}
s->n_blocks = be32_to_cpu(s->n_blocks);

/* read offsets */
offsets_size = s->n_blocks * sizeof(uint64_t);
s->offsets = g_malloc(offsets_size);
if (bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size) <
offsets_size) {
goto cloop_close;

ret = bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size);
if (ret < 0) {
goto fail;
}

for(i=0;i<s->n_blocks;i++) {
s->offsets[i] = be64_to_cpu(s->offsets[i]);
if (i > 0) {
Expand All @@ -92,7 +97,8 @@ static int cloop_open(BlockDriverState *bs, int flags)
s->compressed_block = g_malloc(max_compressed_block_size + 1);
s->uncompressed_block = g_malloc(s->block_size);
if (inflateInit(&s->zstream) != Z_OK) {
goto cloop_close;
ret = -EINVAL;
goto fail;
}
s->current_block = s->n_blocks;

Expand All @@ -101,8 +107,11 @@ static int cloop_open(BlockDriverState *bs, int flags)
qemu_co_mutex_init(&s->lock);
return 0;

cloop_close:
return -1;
fail:
g_free(s->offsets);
g_free(s->compressed_block);
g_free(s->uncompressed_block);
return ret;
}

static inline int cloop_read_block(BlockDriverState *bs, int block_num)
Expand Down
153 changes: 106 additions & 47 deletions block/dmg.c
Expand Up @@ -57,29 +57,42 @@ static int dmg_probe(const uint8_t *buf, int buf_size, const char *filename)
return 0;
}

static off_t read_off(BlockDriverState *bs, int64_t offset)
static int read_uint64(BlockDriverState *bs, int64_t offset, uint64_t *result)
{
uint64_t buffer;
if (bdrv_pread(bs->file, offset, &buffer, 8) < 8)
return 0;
return be64_to_cpu(buffer);
uint64_t buffer;
int ret;

ret = bdrv_pread(bs->file, offset, &buffer, 8);
if (ret < 0) {
return ret;
}

*result = be64_to_cpu(buffer);
return 0;
}

static off_t read_uint32(BlockDriverState *bs, int64_t offset)
static int read_uint32(BlockDriverState *bs, int64_t offset, uint32_t *result)
{
uint32_t buffer;
if (bdrv_pread(bs->file, offset, &buffer, 4) < 4)
return 0;
return be32_to_cpu(buffer);
uint32_t buffer;
int ret;

ret = bdrv_pread(bs->file, offset, &buffer, 4);
if (ret < 0) {
return ret;
}

*result = be32_to_cpu(buffer);
return 0;
}

static int dmg_open(BlockDriverState *bs, int flags)
{
BDRVDMGState *s = bs->opaque;
off_t info_begin,info_end,last_in_offset,last_out_offset;
uint32_t count;
uint64_t info_begin,info_end,last_in_offset,last_out_offset;
uint32_t count, tmp;
uint32_t max_compressed_size=1,max_sectors_per_chunk=1,i;
int64_t offset;
int ret;

bs->read_only = 1;
s->n_chunks = 0;
Expand All @@ -88,21 +101,32 @@ static int dmg_open(BlockDriverState *bs, int flags)
/* read offset of info blocks */
offset = bdrv_getlength(bs->file);
if (offset < 0) {
ret = offset;
goto fail;
}
offset -= 0x1d8;

info_begin = read_off(bs, offset);
if (info_begin == 0) {
goto fail;
ret = read_uint64(bs, offset, &info_begin);
if (ret < 0) {
goto fail;
} else if (info_begin == 0) {
ret = -EINVAL;
goto fail;
}

if (read_uint32(bs, info_begin) != 0x100) {
ret = read_uint32(bs, info_begin, &tmp);
if (ret < 0) {
goto fail;
} else if (tmp != 0x100) {
ret = -EINVAL;
goto fail;
}

count = read_uint32(bs, info_begin + 4);
if (count == 0) {
ret = read_uint32(bs, info_begin + 4, &count);
if (ret < 0) {
goto fail;
} else if (count == 0) {
ret = -EINVAL;
goto fail;
}
info_end = info_begin + count;
Expand All @@ -114,12 +138,20 @@ static int dmg_open(BlockDriverState *bs, int flags)
while (offset < info_end) {
uint32_t type;

count = read_uint32(bs, offset);
if(count==0)
goto fail;
ret = read_uint32(bs, offset, &count);
if (ret < 0) {
goto fail;
} else if (count == 0) {
ret = -EINVAL;
goto fail;
}
offset += 4;

type = read_uint32(bs, offset);
ret = read_uint32(bs, offset, &type);
if (ret < 0) {
goto fail;
}

if (type == 0x6d697368 && count >= 244) {
int new_size, chunk_count;

Expand All @@ -134,8 +166,11 @@ static int dmg_open(BlockDriverState *bs, int flags)
s->sectors = g_realloc(s->sectors, new_size);
s->sectorcounts = g_realloc(s->sectorcounts, new_size);

for(i=s->n_chunks;i<s->n_chunks+chunk_count;i++) {
s->types[i] = read_uint32(bs, offset);
for (i = s->n_chunks; i < s->n_chunks + chunk_count; i++) {
ret = read_uint32(bs, offset, &s->types[i]);
if (ret < 0) {
goto fail;
}
offset += 4;
if(s->types[i]!=0x80000005 && s->types[i]!=1 && s->types[i]!=2) {
if(s->types[i]==0xffffffff) {
Expand All @@ -149,17 +184,31 @@ static int dmg_open(BlockDriverState *bs, int flags)
}
offset += 4;

s->sectors[i] = last_out_offset+read_off(bs, offset);
offset += 8;

s->sectorcounts[i] = read_off(bs, offset);
offset += 8;

s->offsets[i] = last_in_offset+read_off(bs, offset);
offset += 8;

s->lengths[i] = read_off(bs, offset);
offset += 8;
ret = read_uint64(bs, offset, &s->sectors[i]);
if (ret < 0) {
goto fail;
}
s->sectors[i] += last_out_offset;
offset += 8;

ret = read_uint64(bs, offset, &s->sectorcounts[i]);
if (ret < 0) {
goto fail;
}
offset += 8;

ret = read_uint64(bs, offset, &s->offsets[i]);
if (ret < 0) {
goto fail;
}
s->offsets[i] += last_in_offset;
offset += 8;

ret = read_uint64(bs, offset, &s->lengths[i]);
if (ret < 0) {
goto fail;
}
offset += 8;

if(s->lengths[i]>max_compressed_size)
max_compressed_size = s->lengths[i];
Expand All @@ -173,15 +222,25 @@ static int dmg_open(BlockDriverState *bs, int flags)
/* initialize zlib engine */
s->compressed_chunk = g_malloc(max_compressed_size+1);
s->uncompressed_chunk = g_malloc(512*max_sectors_per_chunk);
if(inflateInit(&s->zstream) != Z_OK)
goto fail;
if(inflateInit(&s->zstream) != Z_OK) {
ret = -EINVAL;
goto fail;
}

s->current_chunk = s->n_chunks;

qemu_co_mutex_init(&s->lock);
return 0;

fail:
return -1;
g_free(s->types);
g_free(s->offsets);
g_free(s->lengths);
g_free(s->sectors);
g_free(s->sectorcounts);
g_free(s->compressed_chunk);
g_free(s->uncompressed_chunk);
return ret;
}

static inline int is_sector_in_chunk(BDRVDMGState* s,
Expand Down Expand Up @@ -296,15 +355,15 @@ static coroutine_fn int dmg_co_read(BlockDriverState *bs, int64_t sector_num,
static void dmg_close(BlockDriverState *bs)
{
BDRVDMGState *s = bs->opaque;
if(s->n_chunks>0) {
free(s->types);
free(s->offsets);
free(s->lengths);
free(s->sectors);
free(s->sectorcounts);
}
free(s->compressed_chunk);
free(s->uncompressed_chunk);

g_free(s->types);
g_free(s->offsets);
g_free(s->lengths);
g_free(s->sectors);
g_free(s->sectorcounts);
g_free(s->compressed_chunk);
g_free(s->uncompressed_chunk);

inflateEnd(&s->zstream);
}

Expand Down
23 changes: 15 additions & 8 deletions block/parallels.c
Expand Up @@ -73,14 +73,18 @@ static int parallels_open(BlockDriverState *bs, int flags)
BDRVParallelsState *s = bs->opaque;
int i;
struct parallels_header ph;
int ret;

bs->read_only = 1; // no write support yet

if (bdrv_pread(bs->file, 0, &ph, sizeof(ph)) != sizeof(ph))
ret = bdrv_pread(bs->file, 0, &ph, sizeof(ph));
if (ret < 0) {
goto fail;
}

if (memcmp(ph.magic, HEADER_MAGIC, 16) ||
(le32_to_cpu(ph.version) != HEADER_VERSION)) {
(le32_to_cpu(ph.version) != HEADER_VERSION)) {
ret = -EMEDIUMTYPE;
goto fail;
}

Expand All @@ -90,18 +94,21 @@ static int parallels_open(BlockDriverState *bs, int flags)

s->catalog_size = le32_to_cpu(ph.catalog_entries);
s->catalog_bitmap = g_malloc(s->catalog_size * 4);
if (bdrv_pread(bs->file, 64, s->catalog_bitmap, s->catalog_size * 4) !=
s->catalog_size * 4)
goto fail;

ret = bdrv_pread(bs->file, 64, s->catalog_bitmap, s->catalog_size * 4);
if (ret < 0) {
goto fail;
}

for (i = 0; i < s->catalog_size; i++)
le32_to_cpus(&s->catalog_bitmap[i]);

qemu_co_mutex_init(&s->lock);
return 0;

fail:
if (s->catalog_bitmap)
g_free(s->catalog_bitmap);
return -1;
g_free(s->catalog_bitmap);
return ret;
}

static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
Expand Down

0 comments on commit 77a5f4f

Please sign in to comment.