Commit 95389c8681d4e52f9192fb15e12dba29c6807545

Authored by bellard
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
block-qcow.c
@@ -552,25 +552,28 @@ static int qcow_create(const char *filename, int64_t total_size, @@ -552,25 +552,28 @@ static int qcow_create(const char *filename, int64_t total_size,
552 header_size = sizeof(header); 552 header_size = sizeof(header);
553 backing_filename_len = 0; 553 backing_filename_len = 0;
554 if (backing_file) { 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 header.mtime = cpu_to_be32(st.st_mtime); 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 header.cluster_bits = 9; /* 512 byte cluster to avoid copying 577 header.cluster_bits = 9; /* 512 byte cluster to avoid copying
575 unmodifyed sectors */ 578 unmodifyed sectors */
576 header.l2_bits = 12; /* 32 KB L2 tables */ 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,6 +606,24 @@ static int qcow_create(const char *filename, int64_t total_size,
603 return 0; 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 int qcow_get_cluster_size(BlockDriverState *bs) 627 int qcow_get_cluster_size(BlockDriverState *bs)
607 { 628 {
608 BDRVQcowState *s = bs->opaque; 629 BDRVQcowState *s = bs->opaque;
@@ -683,6 +704,7 @@ BlockDriver bdrv_qcow = { @@ -683,6 +704,7 @@ BlockDriver bdrv_qcow = {
683 qcow_create, 704 qcow_create,
684 qcow_is_allocated, 705 qcow_is_allocated,
685 qcow_set_key, 706 qcow_set_key,
  707 + qcow_make_empty
686 }; 708 };
687 709
688 710
@@ -150,13 +150,19 @@ int bdrv_create(BlockDriver *drv, @@ -150,13 +150,19 @@ int bdrv_create(BlockDriver *drv,
150 } 150 }
151 151
152 #ifdef _WIN32 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 /* XXX: find a better function */ 160 /* XXX: find a better function */
156 - tmpnam(filename); 161 + tmpnam(p);
  162 + *p = '/';
157 } 163 }
158 #else 164 #else
159 -static void get_tmp_filename(char *filename, int size) 165 +void get_tmp_filename(char *filename, int size)
160 { 166 {
161 int fd; 167 int fd;
162 /* XXX: race condition possible */ 168 /* XXX: race condition possible */
@@ -394,6 +400,10 @@ int bdrv_commit(BlockDriverState *bs) @@ -394,6 +400,10 @@ int bdrv_commit(BlockDriverState *bs)
394 i += n; 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 return 0; 407 return 0;
398 } 408 }
399 409
block_int.h
@@ -39,6 +39,7 @@ struct BlockDriver { @@ -39,6 +39,7 @@ struct BlockDriver {
39 int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num, 39 int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
40 int nb_sectors, int *pnum); 40 int nb_sectors, int *pnum);
41 int (*bdrv_set_key)(BlockDriverState *bs, const char *key); 41 int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
  42 + int (*bdrv_make_empty)(BlockDriverState *bs);
42 struct BlockDriver *next; 43 struct BlockDriver *next;
43 }; 44 };
44 45
@@ -74,4 +75,6 @@ struct BlockDriverState { @@ -74,4 +75,6 @@ struct BlockDriverState {
74 BlockDriverState *next; 75 BlockDriverState *next;
75 }; 76 };
76 77
  78 +void get_tmp_filename(char *filename, int size);
  79 +
77 #endif /* BLOCK_INT_H */ 80 #endif /* BLOCK_INT_H */