bochs.c (84a5a8014801a83d1b8d15fa7f0fde03db081530) bochs.c (3b8fd3301147585765624cd733e6172a25efcb58)
1/*
2 * Block driver for the various disk image formats used by Bochs
3 * Currently only for "growing" type in read-only mode
4 *
5 * Copyright (c) 2005 Alex Beregszaszi
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal

--- 90 unchanged lines hidden (view full) ---

99 Error **errp)
100{
101 BDRVBochsState *s = bs->opaque;
102 uint32_t i;
103 struct bochs_header bochs;
104 int ret;
105
106 bs->read_only = 1; // no write support yet
1/*
2 * Block driver for the various disk image formats used by Bochs
3 * Currently only for "growing" type in read-only mode
4 *
5 * Copyright (c) 2005 Alex Beregszaszi
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal

--- 90 unchanged lines hidden (view full) ---

99 Error **errp)
100{
101 BDRVBochsState *s = bs->opaque;
102 uint32_t i;
103 struct bochs_header bochs;
104 int ret;
105
106 bs->read_only = 1; // no write support yet
107 bs->request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O supported */
107
108 ret = bdrv_pread(bs->file->bs, 0, &bochs, sizeof(bochs));
109 if (ret < 0) {
110 return ret;
111 }
112
113 if (strcmp(bochs.magic, HEADER_MAGIC) ||
114 strcmp(bochs.type, REDOLOG_TYPE) ||

--- 101 unchanged lines hidden (view full) ---

216
217 if (!((bitmap_entry >> (extent_offset % 8)) & 1)) {
218 return 0; /* not allocated */
219 }
220
221 return bitmap_offset + (512 * (s->bitmap_blocks + extent_offset));
222}
223
108
109 ret = bdrv_pread(bs->file->bs, 0, &bochs, sizeof(bochs));
110 if (ret < 0) {
111 return ret;
112 }
113
114 if (strcmp(bochs.magic, HEADER_MAGIC) ||
115 strcmp(bochs.type, REDOLOG_TYPE) ||

--- 101 unchanged lines hidden (view full) ---

217
218 if (!((bitmap_entry >> (extent_offset % 8)) & 1)) {
219 return 0; /* not allocated */
220 }
221
222 return bitmap_offset + (512 * (s->bitmap_blocks + extent_offset));
223}
224
224static int bochs_read(BlockDriverState *bs, int64_t sector_num,
225 uint8_t *buf, int nb_sectors)
225static int coroutine_fn
226bochs_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
227 QEMUIOVector *qiov, int flags)
226{
228{
229 BDRVBochsState *s = bs->opaque;
230 uint64_t sector_num = offset >> BDRV_SECTOR_BITS;
231 int nb_sectors = bytes >> BDRV_SECTOR_BITS;
232 uint64_t bytes_done = 0;
233 QEMUIOVector local_qiov;
227 int ret;
228
234 int ret;
235
236 assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
237 assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
238
239 qemu_iovec_init(&local_qiov, qiov->niov);
240 qemu_co_mutex_lock(&s->lock);
241
229 while (nb_sectors > 0) {
230 int64_t block_offset = seek_to_sector(bs, sector_num);
231 if (block_offset < 0) {
242 while (nb_sectors > 0) {
243 int64_t block_offset = seek_to_sector(bs, sector_num);
244 if (block_offset < 0) {
232 return block_offset;
233 } else if (block_offset > 0) {
234 ret = bdrv_pread(bs->file->bs, block_offset, buf, 512);
245 ret = block_offset;
246 goto fail;
247 }
248
249 qemu_iovec_reset(&local_qiov);
250 qemu_iovec_concat(&local_qiov, qiov, bytes_done, 512);
251
252 if (block_offset > 0) {
253 ret = bdrv_co_preadv(bs->file->bs, block_offset, 512,
254 &local_qiov, 0);
235 if (ret < 0) {
255 if (ret < 0) {
236 return ret;
256 goto fail;
237 }
238 } else {
257 }
258 } else {
239 memset(buf, 0, 512);
259 qemu_iovec_memset(&local_qiov, 0, 0, 512);
240 }
241 nb_sectors--;
242 sector_num++;
260 }
261 nb_sectors--;
262 sector_num++;
243 buf += 512;
263 bytes_done += 512;
244 }
264 }
245 return 0;
246}
247
265
248static coroutine_fn int bochs_co_read(BlockDriverState *bs, int64_t sector_num,
249 uint8_t *buf, int nb_sectors)
250{
251 int ret;
252 BDRVBochsState *s = bs->opaque;
253 qemu_co_mutex_lock(&s->lock);
254 ret = bochs_read(bs, sector_num, buf, nb_sectors);
266 ret = 0;
267fail:
255 qemu_co_mutex_unlock(&s->lock);
268 qemu_co_mutex_unlock(&s->lock);
269 qemu_iovec_destroy(&local_qiov);
270
256 return ret;
257}
258
259static void bochs_close(BlockDriverState *bs)
260{
261 BDRVBochsState *s = bs->opaque;
262 g_free(s->catalog_bitmap);
263}
264
265static BlockDriver bdrv_bochs = {
266 .format_name = "bochs",
267 .instance_size = sizeof(BDRVBochsState),
268 .bdrv_probe = bochs_probe,
269 .bdrv_open = bochs_open,
271 return ret;
272}
273
274static void bochs_close(BlockDriverState *bs)
275{
276 BDRVBochsState *s = bs->opaque;
277 g_free(s->catalog_bitmap);
278}
279
280static BlockDriver bdrv_bochs = {
281 .format_name = "bochs",
282 .instance_size = sizeof(BDRVBochsState),
283 .bdrv_probe = bochs_probe,
284 .bdrv_open = bochs_open,
270 .bdrv_read = bochs_co_read,
285 .bdrv_co_preadv = bochs_co_preadv,
271 .bdrv_close = bochs_close,
272};
273
274static void bdrv_bochs_init(void)
275{
276 bdrv_register(&bdrv_bochs);
277}
278
279block_init(bdrv_bochs_init);
286 .bdrv_close = bochs_close,
287};
288
289static void bdrv_bochs_init(void)
290{
291 bdrv_register(&bdrv_bochs);
292}
293
294block_init(bdrv_bochs_init);