From 3535a9c6bef5234ab4df3f143763a0e89a1ad29c Mon Sep 17 00:00:00 2001 From: Li Zhi Hui Date: Tue, 8 Nov 2011 14:21:13 +0800 Subject: block: Use bdrv functions to replace file operation in cow.c Since common file operation functions lack of error detection, so change them to bdrv series functions. Signed-off-by: Li Zhi Hui Reviewed-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- block/cow.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) (limited to 'block/cow.c') diff --git a/block/cow.c b/block/cow.c index 089d395c40..9858d71f00 100644 --- a/block/cow.c +++ b/block/cow.c @@ -243,12 +243,12 @@ static void cow_close(BlockDriverState *bs) static int cow_create(const char *filename, QEMUOptionParameter *options) { - int fd, cow_fd; struct cow_header_v2 cow_header; struct stat st; int64_t image_sectors = 0; const char *image_filename = NULL; int ret; + BlockDriverState *cow_bs; /* Read out options */ while (options && options->name) { @@ -260,10 +260,16 @@ static int cow_create(const char *filename, QEMUOptionParameter *options) options++; } - cow_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, - 0644); - if (cow_fd < 0) - return -errno; + ret = bdrv_create_file(filename, options); + if (ret < 0) { + return ret; + } + + ret = bdrv_file_open(&cow_bs, filename, BDRV_O_RDWR); + if (ret < 0) { + return ret; + } + memset(&cow_header, 0, sizeof(cow_header)); cow_header.magic = cpu_to_be32(COW_MAGIC); cow_header.version = cpu_to_be32(COW_VERSION); @@ -271,16 +277,9 @@ static int cow_create(const char *filename, QEMUOptionParameter *options) /* Note: if no file, we put a dummy mtime */ cow_header.mtime = cpu_to_be32(0); - fd = open(image_filename, O_RDONLY | O_BINARY); - if (fd < 0) { - close(cow_fd); - goto mtime_fail; - } - if (fstat(fd, &st) != 0) { - close(fd); + if (stat(image_filename, &st) != 0) { goto mtime_fail; } - close(fd); cow_header.mtime = cpu_to_be32(st.st_mtime); mtime_fail: pstrcpy(cow_header.backing_file, sizeof(cow_header.backing_file), @@ -288,21 +287,20 @@ static int cow_create(const char *filename, QEMUOptionParameter *options) } cow_header.sectorsize = cpu_to_be32(512); cow_header.size = cpu_to_be64(image_sectors * 512); - ret = qemu_write_full(cow_fd, &cow_header, sizeof(cow_header)); + ret = bdrv_pwrite(cow_bs, 0, &cow_header, sizeof(cow_header)); if (ret != sizeof(cow_header)) { - ret = -errno; goto exit; } /* resize to include at least all the bitmap */ - ret = ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3)); + ret = bdrv_truncate(cow_bs, + sizeof(cow_header) + ((image_sectors + 7) >> 3)); if (ret) { - ret = -errno; goto exit; } exit: - close(cow_fd); + bdrv_delete(cow_bs); return ret; } -- cgit v1.2.1 From 81145834d39897c6f153ac26a4077f90f269c5fc Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Mon, 14 Nov 2011 12:44:24 +0000 Subject: cow: convert to .bdrv_co_is_allocated() The cow block driver does not keep internal state for cluster lookups. This means it is safe to perform cluster lookups in coroutine context without risk of race conditions that corrupt internal state. Signed-off-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- block/cow.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'block/cow.c') diff --git a/block/cow.c b/block/cow.c index 9858d71f00..7ae887b670 100644 --- a/block/cow.c +++ b/block/cow.c @@ -132,8 +132,8 @@ static inline int is_bit_set(BlockDriverState *bs, int64_t bitnum) /* Return true if first block has been changed (ie. current version is * in COW file). Set the number of continuous blocks for which that * is true. */ -static int cow_is_allocated(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, int *num_same) +static int coroutine_fn cow_co_is_allocated(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, int *num_same) { int changed; @@ -178,7 +178,7 @@ static int cow_read(BlockDriverState *bs, int64_t sector_num, int ret, n; while (nb_sectors > 0) { - if (cow_is_allocated(bs, sector_num, nb_sectors, &n)) { + if (bdrv_is_allocated(bs, sector_num, nb_sectors, &n)) { ret = bdrv_pread(bs->file, s->cow_sectors_offset + sector_num * 512, buf, n * 512); @@ -335,7 +335,7 @@ static BlockDriver bdrv_cow = { .bdrv_read = cow_co_read, .bdrv_write = cow_co_write, .bdrv_co_flush_to_disk = cow_co_flush, - .bdrv_is_allocated = cow_is_allocated, + .bdrv_co_is_allocated = cow_co_is_allocated, .create_options = cow_create_options, }; -- cgit v1.2.1 From e94d13873334b1880746feca59ce84c0eabc1021 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Wed, 23 Nov 2011 15:00:04 +0000 Subject: cow: use bdrv_co_is_allocated() Now that bdrv_co_is_allocated() is available we can use it instead of the synchronous bdrv_is_allocated() interface. This is a follow-up that Kevin Wolf pointed out after applying the series that introduces bdrv_co_is_allocated(). It is safe to make cow_read() a coroutine_fn because its only caller is a coroutine_fn. Signed-off-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- block/cow.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'block/cow.c') diff --git a/block/cow.c b/block/cow.c index 7ae887b670..586493c623 100644 --- a/block/cow.c +++ b/block/cow.c @@ -171,14 +171,14 @@ static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num, return error; } -static int cow_read(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors) +static int coroutine_fn cow_read(BlockDriverState *bs, int64_t sector_num, + uint8_t *buf, int nb_sectors) { BDRVCowState *s = bs->opaque; int ret, n; while (nb_sectors > 0) { - if (bdrv_is_allocated(bs, sector_num, nb_sectors, &n)) { + if (bdrv_co_is_allocated(bs, sector_num, nb_sectors, &n)) { ret = bdrv_pread(bs->file, s->cow_sectors_offset + sector_num * 512, buf, n * 512); -- cgit v1.2.1