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 */ | ... | ... |