From 95389c8681d4e52f9192fb15e12dba29c6807545 Mon Sep 17 00:00:00 2001 From: bellard Date: Sun, 18 Dec 2005 18:28:15 +0000 Subject: [PATCH] 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 | 58 ++++++++++++++++++++++++++++++++++++---------------- block.c | 16 ++++++++++++--- block_int.h | 3 +++ 3 files changed, 56 insertions(+), 21 deletions(-) diff --git a/block-qcow.c b/block-qcow.c index ca05be88b0..34026a4f2c 100644 --- a/block-qcow.c +++ b/block-qcow.c @@ -552,25 +552,28 @@ static int qcow_create(const char *filename, int64_t total_size, header_size = sizeof(header); backing_filename_len = 0; if (backing_file) { - const char *p; - /* XXX: this is a hack: we do not attempt to check for URL - like syntax */ - p = strchr(backing_file, ':'); - if (p && (p - backing_file) >= 2) { - /* URL like but exclude "c:" like filenames */ - pstrcpy(backing_filename, sizeof(backing_filename), - backing_file); - } else { - realpath(backing_file, backing_filename); - if (stat(backing_filename, &st) != 0) { - return -1; - } - } + if (strcmp(backing_file, "fat:")) { + const char *p; + /* XXX: this is a hack: we do not attempt to check for URL + like syntax */ + p = strchr(backing_file, ':'); + if (p && (p - backing_file) >= 2) { + /* URL like but exclude "c:" like filenames */ + pstrcpy(backing_filename, sizeof(backing_filename), + backing_file); + } else { + realpath(backing_file, backing_filename); + if (stat(backing_filename, &st) != 0) { + return -1; + } + } + header.backing_file_offset = cpu_to_be64(header_size); + backing_filename_len = strlen(backing_filename); + header.backing_file_size = cpu_to_be32(backing_filename_len); + header_size += backing_filename_len; + } else + backing_file = NULL; header.mtime = cpu_to_be32(st.st_mtime); - header.backing_file_offset = cpu_to_be64(header_size); - backing_filename_len = strlen(backing_filename); - header.backing_file_size = cpu_to_be32(backing_filename_len); - header_size += backing_filename_len; header.cluster_bits = 9; /* 512 byte cluster to avoid copying unmodifyed sectors */ header.l2_bits = 12; /* 32 KB L2 tables */ @@ -603,6 +606,24 @@ static int qcow_create(const char *filename, int64_t total_size, return 0; } +int qcow_make_empty(BlockDriverState *bs) +{ + BDRVQcowState *s = bs->opaque; + uint32_t l1_length = s->l1_size * sizeof(uint64_t); + + memset(s->l1_table, 0, l1_length); + lseek(s->fd, s->l1_table_offset, SEEK_SET); + if (write(s->fd, s->l1_table, l1_length) < 0) + return -1; + ftruncate(s->fd, s->l1_table_offset + l1_length); + + memset(s->l2_cache, 0, s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t)); + memset(s->l2_cache_offsets, 0, L2_CACHE_SIZE * sizeof(uint64_t)); + memset(s->l2_cache_counts, 0, L2_CACHE_SIZE * sizeof(uint32_t)); + + return 0; +} + int qcow_get_cluster_size(BlockDriverState *bs) { BDRVQcowState *s = bs->opaque; @@ -683,6 +704,7 @@ BlockDriver bdrv_qcow = { qcow_create, qcow_is_allocated, qcow_set_key, + qcow_make_empty }; diff --git a/block.c b/block.c index efd96e637f..6924cee67d 100644 --- a/block.c +++ b/block.c @@ -150,13 +150,19 @@ int bdrv_create(BlockDriver *drv, } #ifdef _WIN32 -static void get_tmp_filename(char *filename, int size) +void get_tmp_filename(char *filename, int size) { + char* p = strrchr(filename, '/'); + + if (p == NULL) + return; + /* XXX: find a better function */ - tmpnam(filename); + tmpnam(p); + *p = '/'; } #else -static void get_tmp_filename(char *filename, int size) +void get_tmp_filename(char *filename, int size) { int fd; /* XXX: race condition possible */ @@ -394,6 +400,10 @@ int bdrv_commit(BlockDriverState *bs) i += n; } } + + if (bs->drv->bdrv_make_empty) + return bs->drv->bdrv_make_empty(bs); + return 0; } diff --git a/block_int.h b/block_int.h index 03744f7340..e3038160e6 100644 --- a/block_int.h +++ b/block_int.h @@ -39,6 +39,7 @@ struct BlockDriver { int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum); int (*bdrv_set_key)(BlockDriverState *bs, const char *key); + int (*bdrv_make_empty)(BlockDriverState *bs); struct BlockDriver *next; }; @@ -74,4 +75,6 @@ struct BlockDriverState { BlockDriverState *next; }; +void get_tmp_filename(char *filename, int size); + #endif /* BLOCK_INT_H */