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 --- |