static int dmg_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors) { BDRVDMGState *s = bs->opaque; int i; for(i=0;i<nb_sectors;i++) { uint32_t sector_offset_in_chunk; if(dmg_read_chunk(bs, sector_num+i) != 0) return -1; sector_offset_in_chunk = sector_num+i-s->sectors[s->current_chunk]; memcpy(buf+i*512,s->uncompressed_chunk+sector_offset_in_chunk*512,512); } return 0; }
int dmg_read(bdev_desc_t *bdev, u8 *buf, int nb_bytes) { BDRVDMGState *s = DMG_PRIV(bdev); int i; int nb_sectors = ceil(nb_bytes / 512); for(i=0;i<nb_sectors;i++) { u32 sector_offset_in_chunk; if(dmg_read_chunk(s, s->seek_sector+i) != 0) return -1; sector_offset_in_chunk = s->seek_sector+i-s->sectors[s->current_chunk]; memcpy(buf+i*512, s->uncompressed_chunk+sector_offset_in_chunk*512, 512); } return nb_bytes; }
static int coroutine_fn dmg_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags) { BDRVDMGState *s = bs->opaque; uint64_t sector_num = offset >> BDRV_SECTOR_BITS; int nb_sectors = bytes >> BDRV_SECTOR_BITS; int ret, i; assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0); assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0); qemu_co_mutex_lock(&s->lock); for (i = 0; i < nb_sectors; i++) { uint32_t sector_offset_in_chunk; void *data; if (dmg_read_chunk(bs, sector_num + i) != 0) { ret = -EIO; goto fail; } /* Special case: current chunk is all zeroes. Do not perform a memcpy as * s->uncompressed_chunk may be too small to cover the large all-zeroes * section. dmg_read_chunk is called to find s->current_chunk */ if (s->types[s->current_chunk] == 2) { /* all zeroes block entry */ qemu_iovec_memset(qiov, i * 512, 0, 512); continue; } sector_offset_in_chunk = sector_num + i - s->sectors[s->current_chunk]; data = s->uncompressed_chunk + sector_offset_in_chunk * 512; qemu_iovec_from_buf(qiov, i * 512, data, 512); } ret = 0; fail: qemu_co_mutex_unlock(&s->lock); return ret; }
static int dmg_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors) { BDRVDMGState *s = bs->opaque; int i; for (i = 0; i < nb_sectors; i++) { uint32_t sector_offset_in_chunk; if (dmg_read_chunk(bs, sector_num + i) != 0) { return -1; } /* Special case: current chunk is all zeroes. Do not perform a memcpy as * s->uncompressed_chunk may be too small to cover the large all-zeroes * section. dmg_read_chunk is called to find s->current_chunk */ if (s->types[s->current_chunk] == 2) { /* all zeroes block entry */ memset(buf + i * 512, 0, 512); continue; } sector_offset_in_chunk = sector_num + i - s->sectors[s->current_chunk]; memcpy(buf + i * 512, s->uncompressed_chunk + sector_offset_in_chunk * 512, 512); } return 0; }