vdi.c (95a2f9bc588c3f83375d87b0a9394f89a1bcfada) vdi.c (66f82ceed6781261c09e65fb440ca76842fd0500)
1/*
2 * Block driver for the Virtual Disk Image (VDI) format
3 *
4 * Copyright (c) 2009 Stefan Weil
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or

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

371 logout("no vdi image\n");
372 } else {
373 logout("%s", header->text);
374 }
375
376 return result;
377}
378
1/*
2 * Block driver for the Virtual Disk Image (VDI) format
3 *
4 * Copyright (c) 2009 Stefan Weil
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or

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

371 logout("no vdi image\n");
372 } else {
373 logout("%s", header->text);
374 }
375
376 return result;
377}
378
379static int vdi_open(BlockDriverState *bs, const char *filename, int flags)
379static int vdi_open(BlockDriverState *bs, int flags)
380{
381 BDRVVdiState *s = bs->opaque;
382 VdiHeader header;
383 size_t bmap_size;
380{
381 BDRVVdiState *s = bs->opaque;
382 VdiHeader header;
383 size_t bmap_size;
384 int ret;
385
386 logout("\n");
387
384
385 logout("\n");
386
388 ret = bdrv_file_open(&s->hd, filename, flags);
389 if (ret < 0) {
390 return ret;
391 }
392
393 if (bdrv_read(s->hd, 0, (uint8_t *)&header, 1) < 0) {
387 if (bdrv_read(bs->file, 0, (uint8_t *)&header, 1) < 0) {
394 goto fail;
395 }
396
397 vdi_header_to_cpu(&header);
398#if defined(CONFIG_VDI_DEBUG)
399 vdi_header_print(&header);
400#endif
401

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

437 s->block_size = header.block_size;
438 s->block_sectors = header.block_size / SECTOR_SIZE;
439 s->bmap_sector = header.offset_bmap / SECTOR_SIZE;
440 s->header = header;
441
442 bmap_size = header.blocks_in_image * sizeof(uint32_t);
443 bmap_size = (bmap_size + SECTOR_SIZE - 1) / SECTOR_SIZE;
444 s->bmap = qemu_malloc(bmap_size * SECTOR_SIZE);
388 goto fail;
389 }
390
391 vdi_header_to_cpu(&header);
392#if defined(CONFIG_VDI_DEBUG)
393 vdi_header_print(&header);
394#endif
395

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

431 s->block_size = header.block_size;
432 s->block_sectors = header.block_size / SECTOR_SIZE;
433 s->bmap_sector = header.offset_bmap / SECTOR_SIZE;
434 s->header = header;
435
436 bmap_size = header.blocks_in_image * sizeof(uint32_t);
437 bmap_size = (bmap_size + SECTOR_SIZE - 1) / SECTOR_SIZE;
438 s->bmap = qemu_malloc(bmap_size * SECTOR_SIZE);
445 if (bdrv_read(s->hd, s->bmap_sector, (uint8_t *)s->bmap, bmap_size) < 0) {
439 if (bdrv_read(bs->file, s->bmap_sector, (uint8_t *)s->bmap, bmap_size) < 0) {
446 goto fail_free_bmap;
447 }
448
449 return 0;
450
451 fail_free_bmap:
452 qemu_free(s->bmap);
453
454 fail:
440 goto fail_free_bmap;
441 }
442
443 return 0;
444
445 fail_free_bmap:
446 qemu_free(s->bmap);
447
448 fail:
455 bdrv_delete(s->hd);
456 return -1;
457}
458
459static int vdi_is_allocated(BlockDriverState *bs, int64_t sector_num,
460 int nb_sectors, int *pnum)
461{
462 /* TODO: Check for too large sector_num (in bdrv_is_allocated or here). */
463 BDRVVdiState *s = (BDRVVdiState *)bs->opaque;

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

602 }
603 } else {
604 uint64_t offset = s->header.offset_data / SECTOR_SIZE +
605 (uint64_t)bmap_entry * s->block_sectors +
606 sector_in_block;
607 acb->hd_iov.iov_base = (void *)acb->buf;
608 acb->hd_iov.iov_len = n_sectors * SECTOR_SIZE;
609 qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
449 return -1;
450}
451
452static int vdi_is_allocated(BlockDriverState *bs, int64_t sector_num,
453 int nb_sectors, int *pnum)
454{
455 /* TODO: Check for too large sector_num (in bdrv_is_allocated or here). */
456 BDRVVdiState *s = (BDRVVdiState *)bs->opaque;

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

595 }
596 } else {
597 uint64_t offset = s->header.offset_data / SECTOR_SIZE +
598 (uint64_t)bmap_entry * s->block_sectors +
599 sector_in_block;
600 acb->hd_iov.iov_base = (void *)acb->buf;
601 acb->hd_iov.iov_len = n_sectors * SECTOR_SIZE;
602 qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
610 acb->hd_aiocb = bdrv_aio_readv(s->hd, offset, &acb->hd_qiov,
603 acb->hd_aiocb = bdrv_aio_readv(bs->file, offset, &acb->hd_qiov,
611 n_sectors, vdi_aio_read_cb, acb);
612 if (acb->hd_aiocb == NULL) {
613 goto done;
614 }
615 }
616 return;
617done:
618 if (acb->qiov->niov > 1) {

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

665 logout("now writing modified header\n");
666 assert(acb->bmap_first != VDI_UNALLOCATED);
667 *header = s->header;
668 vdi_header_to_le(header);
669 acb->header_modified = 0;
670 acb->hd_iov.iov_base = acb->block_buffer;
671 acb->hd_iov.iov_len = SECTOR_SIZE;
672 qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
604 n_sectors, vdi_aio_read_cb, acb);
605 if (acb->hd_aiocb == NULL) {
606 goto done;
607 }
608 }
609 return;
610done:
611 if (acb->qiov->niov > 1) {

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

658 logout("now writing modified header\n");
659 assert(acb->bmap_first != VDI_UNALLOCATED);
660 *header = s->header;
661 vdi_header_to_le(header);
662 acb->header_modified = 0;
663 acb->hd_iov.iov_base = acb->block_buffer;
664 acb->hd_iov.iov_len = SECTOR_SIZE;
665 qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
673 acb->hd_aiocb = bdrv_aio_writev(s->hd, 0, &acb->hd_qiov, 1,
666 acb->hd_aiocb = bdrv_aio_writev(bs->file, 0, &acb->hd_qiov, 1,
674 vdi_aio_write_cb, acb);
675 if (acb->hd_aiocb == NULL) {
676 goto done;
677 }
678 return;
679 } else if (acb->bmap_first != VDI_UNALLOCATED) {
680 /* One or more new blocks were allocated. */
681 uint64_t offset;

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

694 offset = s->bmap_sector + bmap_first;
695 acb->bmap_first = VDI_UNALLOCATED;
696 acb->hd_iov.iov_base = (void *)((uint8_t *)&s->bmap[0] +
697 bmap_first * SECTOR_SIZE);
698 acb->hd_iov.iov_len = n_sectors * SECTOR_SIZE;
699 qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
700 logout("will write %u block map sectors starting from entry %u\n",
701 n_sectors, bmap_first);
667 vdi_aio_write_cb, acb);
668 if (acb->hd_aiocb == NULL) {
669 goto done;
670 }
671 return;
672 } else if (acb->bmap_first != VDI_UNALLOCATED) {
673 /* One or more new blocks were allocated. */
674 uint64_t offset;

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

687 offset = s->bmap_sector + bmap_first;
688 acb->bmap_first = VDI_UNALLOCATED;
689 acb->hd_iov.iov_base = (void *)((uint8_t *)&s->bmap[0] +
690 bmap_first * SECTOR_SIZE);
691 acb->hd_iov.iov_len = n_sectors * SECTOR_SIZE;
692 qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
693 logout("will write %u block map sectors starting from entry %u\n",
694 n_sectors, bmap_first);
702 acb->hd_aiocb = bdrv_aio_writev(s->hd, offset, &acb->hd_qiov,
695 acb->hd_aiocb = bdrv_aio_writev(bs->file, offset, &acb->hd_qiov,
703 n_sectors, vdi_aio_write_cb, acb);
704 if (acb->hd_aiocb == NULL) {
705 goto done;
706 }
707 return;
708 }
709 ret = 0;
710 goto done;

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

743 acb->header_modified = 1;
744 }
745 acb->bmap_last = block_index;
746 memcpy(block + sector_in_block * SECTOR_SIZE,
747 acb->buf, n_sectors * SECTOR_SIZE);
748 acb->hd_iov.iov_base = (void *)block;
749 acb->hd_iov.iov_len = s->block_size;
750 qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
696 n_sectors, vdi_aio_write_cb, acb);
697 if (acb->hd_aiocb == NULL) {
698 goto done;
699 }
700 return;
701 }
702 ret = 0;
703 goto done;

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

736 acb->header_modified = 1;
737 }
738 acb->bmap_last = block_index;
739 memcpy(block + sector_in_block * SECTOR_SIZE,
740 acb->buf, n_sectors * SECTOR_SIZE);
741 acb->hd_iov.iov_base = (void *)block;
742 acb->hd_iov.iov_len = s->block_size;
743 qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
751 acb->hd_aiocb = bdrv_aio_writev(s->hd, offset,
744 acb->hd_aiocb = bdrv_aio_writev(bs->file, offset,
752 &acb->hd_qiov, s->block_sectors,
753 vdi_aio_write_cb, acb);
754 if (acb->hd_aiocb == NULL) {
755 goto done;
756 }
757 } else {
758 uint64_t offset = s->header.offset_data / SECTOR_SIZE +
759 (uint64_t)bmap_entry * s->block_sectors +
760 sector_in_block;
761 acb->hd_iov.iov_base = (void *)acb->buf;
762 acb->hd_iov.iov_len = n_sectors * SECTOR_SIZE;
763 qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
745 &acb->hd_qiov, s->block_sectors,
746 vdi_aio_write_cb, acb);
747 if (acb->hd_aiocb == NULL) {
748 goto done;
749 }
750 } else {
751 uint64_t offset = s->header.offset_data / SECTOR_SIZE +
752 (uint64_t)bmap_entry * s->block_sectors +
753 sector_in_block;
754 acb->hd_iov.iov_base = (void *)acb->buf;
755 acb->hd_iov.iov_len = n_sectors * SECTOR_SIZE;
756 qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
764 acb->hd_aiocb = bdrv_aio_writev(s->hd, offset, &acb->hd_qiov,
757 acb->hd_aiocb = bdrv_aio_writev(bs->file, offset, &acb->hd_qiov,
765 n_sectors, vdi_aio_write_cb, acb);
766 if (acb->hd_aiocb == NULL) {
767 goto done;
768 }
769 }
770
771 return;
772

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

886 result = -errno;
887 }
888
889 return result;
890}
891
892static void vdi_close(BlockDriverState *bs)
893{
758 n_sectors, vdi_aio_write_cb, acb);
759 if (acb->hd_aiocb == NULL) {
760 goto done;
761 }
762 }
763
764 return;
765

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

879 result = -errno;
880 }
881
882 return result;
883}
884
885static void vdi_close(BlockDriverState *bs)
886{
894 BDRVVdiState *s = bs->opaque;
895 logout("\n");
896 bdrv_delete(s->hd);
897}
898
899static void vdi_flush(BlockDriverState *bs)
900{
887}
888
889static void vdi_flush(BlockDriverState *bs)
890{
901 BDRVVdiState *s = bs->opaque;
902 logout("\n");
891 logout("\n");
903 bdrv_flush(s->hd);
892 bdrv_flush(bs->file);
904}
905
906
907static QEMUOptionParameter vdi_create_options[] = {
908 {
909 .name = BLOCK_OPT_SIZE,
910 .type = OPT_SIZE,
911 .help = "Virtual disk size"

--- 48 unchanged lines hidden ---
893}
894
895
896static QEMUOptionParameter vdi_create_options[] = {
897 {
898 .name = BLOCK_OPT_SIZE,
899 .type = OPT_SIZE,
900 .help = "Virtual disk size"

--- 48 unchanged lines hidden ---