qcow_make_empty() support (Johannes Schindelin)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1716 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
1658b44bf5
commit
95389c8681
58
block-qcow.c
58
block-qcow.c
@ -552,25 +552,28 @@ static int qcow_create(const char *filename, int64_t total_size,
|
|||||||
header_size = sizeof(header);
|
header_size = sizeof(header);
|
||||||
backing_filename_len = 0;
|
backing_filename_len = 0;
|
||||||
if (backing_file) {
|
if (backing_file) {
|
||||||
const char *p;
|
if (strcmp(backing_file, "fat:")) {
|
||||||
/* XXX: this is a hack: we do not attempt to check for URL
|
const char *p;
|
||||||
like syntax */
|
/* XXX: this is a hack: we do not attempt to check for URL
|
||||||
p = strchr(backing_file, ':');
|
like syntax */
|
||||||
if (p && (p - backing_file) >= 2) {
|
p = strchr(backing_file, ':');
|
||||||
/* URL like but exclude "c:" like filenames */
|
if (p && (p - backing_file) >= 2) {
|
||||||
pstrcpy(backing_filename, sizeof(backing_filename),
|
/* URL like but exclude "c:" like filenames */
|
||||||
backing_file);
|
pstrcpy(backing_filename, sizeof(backing_filename),
|
||||||
} else {
|
backing_file);
|
||||||
realpath(backing_file, backing_filename);
|
} else {
|
||||||
if (stat(backing_filename, &st) != 0) {
|
realpath(backing_file, backing_filename);
|
||||||
return -1;
|
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.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
|
header.cluster_bits = 9; /* 512 byte cluster to avoid copying
|
||||||
unmodifyed sectors */
|
unmodifyed sectors */
|
||||||
header.l2_bits = 12; /* 32 KB L2 tables */
|
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;
|
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)
|
int qcow_get_cluster_size(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState *s = bs->opaque;
|
||||||
@ -683,6 +704,7 @@ BlockDriver bdrv_qcow = {
|
|||||||
qcow_create,
|
qcow_create,
|
||||||
qcow_is_allocated,
|
qcow_is_allocated,
|
||||||
qcow_set_key,
|
qcow_set_key,
|
||||||
|
qcow_make_empty
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
16
block.c
16
block.c
@ -150,13 +150,19 @@ int bdrv_create(BlockDriver *drv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#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 */
|
/* XXX: find a better function */
|
||||||
tmpnam(filename);
|
tmpnam(p);
|
||||||
|
*p = '/';
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void get_tmp_filename(char *filename, int size)
|
void get_tmp_filename(char *filename, int size)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
/* XXX: race condition possible */
|
/* XXX: race condition possible */
|
||||||
@ -394,6 +400,10 @@ int bdrv_commit(BlockDriverState *bs)
|
|||||||
i += n;
|
i += n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bs->drv->bdrv_make_empty)
|
||||||
|
return bs->drv->bdrv_make_empty(bs);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ struct BlockDriver {
|
|||||||
int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
|
int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
|
||||||
int nb_sectors, int *pnum);
|
int nb_sectors, int *pnum);
|
||||||
int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
|
int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
|
||||||
|
int (*bdrv_make_empty)(BlockDriverState *bs);
|
||||||
struct BlockDriver *next;
|
struct BlockDriver *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -74,4 +75,6 @@ struct BlockDriverState {
|
|||||||
BlockDriverState *next;
|
BlockDriverState *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void get_tmp_filename(char *filename, int size);
|
||||||
|
|
||||||
#endif /* BLOCK_INT_H */
|
#endif /* BLOCK_INT_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user