static int coroutine_fn cloop_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags) { BDRVCloopState *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++) { void *data; uint32_t sector_offset_in_block = ((sector_num + i) % s->sectors_per_block), block_num = (sector_num + i) / s->sectors_per_block; if (cloop_read_block(bs, block_num) != 0) { ret = -EIO; goto fail; } data = s->uncompressed_block + sector_offset_in_block * 512; qemu_iovec_from_buf(qiov, i * 512, data, 512); } ret = 0; fail: qemu_co_mutex_unlock(&s->lock); return ret; }
static int cloop_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors) { BDRVCloopState *s = (BDRVCloopState *)bs->opaque; int i; for(i=0;i<nb_sectors;i++) { uint32_t sector_offset_in_block=((sector_num+i)%s->sectors_per_block), block_num=(sector_num+i)/s->sectors_per_block; if(cloop_read_block(s, block_num) != 0) return -1; memcpy(buf+i*512,s->uncompressed_block+sector_offset_in_block*512,512); } return 0; }