Commit 95389c8681d4e52f9192fb15e12dba29c6807545
1 parent
1658b44b
qcow_make_empty() support (Johannes Schindelin)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1716 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
56 additions
and
21 deletions
block-qcow.c
| ... | ... | @@ -552,25 +552,28 @@ static int qcow_create(const char *filename, int64_t total_size, |
| 552 | 552 | header_size = sizeof(header); |
| 553 | 553 | backing_filename_len = 0; |
| 554 | 554 | if (backing_file) { |
| 555 | - const char *p; | |
| 556 | - /* XXX: this is a hack: we do not attempt to check for URL | |
| 557 | - like syntax */ | |
| 558 | - p = strchr(backing_file, ':'); | |
| 559 | - if (p && (p - backing_file) >= 2) { | |
| 560 | - /* URL like but exclude "c:" like filenames */ | |
| 561 | - pstrcpy(backing_filename, sizeof(backing_filename), | |
| 562 | - backing_file); | |
| 563 | - } else { | |
| 564 | - realpath(backing_file, backing_filename); | |
| 565 | - if (stat(backing_filename, &st) != 0) { | |
| 566 | - return -1; | |
| 567 | - } | |
| 568 | - } | |
| 555 | + if (strcmp(backing_file, "fat:")) { | |
| 556 | + const char *p; | |
| 557 | + /* XXX: this is a hack: we do not attempt to check for URL | |
| 558 | + like syntax */ | |
| 559 | + p = strchr(backing_file, ':'); | |
| 560 | + if (p && (p - backing_file) >= 2) { | |
| 561 | + /* URL like but exclude "c:" like filenames */ | |
| 562 | + pstrcpy(backing_filename, sizeof(backing_filename), | |
| 563 | + backing_file); | |
| 564 | + } else { | |
| 565 | + realpath(backing_file, backing_filename); | |
| 566 | + if (stat(backing_filename, &st) != 0) { | |
| 567 | + return -1; | |
| 568 | + } | |
| 569 | + } | |
| 570 | + header.backing_file_offset = cpu_to_be64(header_size); | |
| 571 | + backing_filename_len = strlen(backing_filename); | |
| 572 | + header.backing_file_size = cpu_to_be32(backing_filename_len); | |
| 573 | + header_size += backing_filename_len; | |
| 574 | + } else | |
| 575 | + backing_file = NULL; | |
| 569 | 576 | header.mtime = cpu_to_be32(st.st_mtime); |
| 570 | - header.backing_file_offset = cpu_to_be64(header_size); | |
| 571 | - backing_filename_len = strlen(backing_filename); | |
| 572 | - header.backing_file_size = cpu_to_be32(backing_filename_len); | |
| 573 | - header_size += backing_filename_len; | |
| 574 | 577 | header.cluster_bits = 9; /* 512 byte cluster to avoid copying |
| 575 | 578 | unmodifyed sectors */ |
| 576 | 579 | header.l2_bits = 12; /* 32 KB L2 tables */ |
| ... | ... | @@ -603,6 +606,24 @@ static int qcow_create(const char *filename, int64_t total_size, |
| 603 | 606 | return 0; |
| 604 | 607 | } |
| 605 | 608 | |
| 609 | +int qcow_make_empty(BlockDriverState *bs) | |
| 610 | +{ | |
| 611 | + BDRVQcowState *s = bs->opaque; | |
| 612 | + uint32_t l1_length = s->l1_size * sizeof(uint64_t); | |
| 613 | + | |
| 614 | + memset(s->l1_table, 0, l1_length); | |
| 615 | + lseek(s->fd, s->l1_table_offset, SEEK_SET); | |
| 616 | + if (write(s->fd, s->l1_table, l1_length) < 0) | |
| 617 | + return -1; | |
| 618 | + ftruncate(s->fd, s->l1_table_offset + l1_length); | |
| 619 | + | |
| 620 | + memset(s->l2_cache, 0, s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t)); | |
| 621 | + memset(s->l2_cache_offsets, 0, L2_CACHE_SIZE * sizeof(uint64_t)); | |
| 622 | + memset(s->l2_cache_counts, 0, L2_CACHE_SIZE * sizeof(uint32_t)); | |
| 623 | + | |
| 624 | + return 0; | |
| 625 | +} | |
| 626 | + | |
| 606 | 627 | int qcow_get_cluster_size(BlockDriverState *bs) |
| 607 | 628 | { |
| 608 | 629 | BDRVQcowState *s = bs->opaque; |
| ... | ... | @@ -683,6 +704,7 @@ BlockDriver bdrv_qcow = { |
| 683 | 704 | qcow_create, |
| 684 | 705 | qcow_is_allocated, |
| 685 | 706 | qcow_set_key, |
| 707 | + qcow_make_empty | |
| 686 | 708 | }; |
| 687 | 709 | |
| 688 | 710 | ... | ... |
block.c
| ... | ... | @@ -150,13 +150,19 @@ int bdrv_create(BlockDriver *drv, |
| 150 | 150 | } |
| 151 | 151 | |
| 152 | 152 | #ifdef _WIN32 |
| 153 | -static void get_tmp_filename(char *filename, int size) | |
| 153 | +void get_tmp_filename(char *filename, int size) | |
| 154 | 154 | { |
| 155 | + char* p = strrchr(filename, '/'); | |
| 156 | + | |
| 157 | + if (p == NULL) | |
| 158 | + return; | |
| 159 | + | |
| 155 | 160 | /* XXX: find a better function */ |
| 156 | - tmpnam(filename); | |
| 161 | + tmpnam(p); | |
| 162 | + *p = '/'; | |
| 157 | 163 | } |
| 158 | 164 | #else |
| 159 | -static void get_tmp_filename(char *filename, int size) | |
| 165 | +void get_tmp_filename(char *filename, int size) | |
| 160 | 166 | { |
| 161 | 167 | int fd; |
| 162 | 168 | /* XXX: race condition possible */ |
| ... | ... | @@ -394,6 +400,10 @@ int bdrv_commit(BlockDriverState *bs) |
| 394 | 400 | i += n; |
| 395 | 401 | } |
| 396 | 402 | } |
| 403 | + | |
| 404 | + if (bs->drv->bdrv_make_empty) | |
| 405 | + return bs->drv->bdrv_make_empty(bs); | |
| 406 | + | |
| 397 | 407 | return 0; |
| 398 | 408 | } |
| 399 | 409 | ... | ... |
block_int.h
| ... | ... | @@ -39,6 +39,7 @@ struct BlockDriver { |
| 39 | 39 | int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num, |
| 40 | 40 | int nb_sectors, int *pnum); |
| 41 | 41 | int (*bdrv_set_key)(BlockDriverState *bs, const char *key); |
| 42 | + int (*bdrv_make_empty)(BlockDriverState *bs); | |
| 42 | 43 | struct BlockDriver *next; |
| 43 | 44 | }; |
| 44 | 45 | |
| ... | ... | @@ -74,4 +75,6 @@ struct BlockDriverState { |
| 74 | 75 | BlockDriverState *next; |
| 75 | 76 | }; |
| 76 | 77 | |
| 78 | +void get_tmp_filename(char *filename, int size); | |
| 79 | + | |
| 77 | 80 | #endif /* BLOCK_INT_H */ | ... | ... |