cow: use qemu block API

Use bdrv_pwrite to access the backing device instead of pread, and
convert the driver to implementing the bdrv_open method which gives
it an already opened BlockDriverState for the underlying device.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Christoph Hellwig 2010-06-07 12:06:47 +02:00 committed by Kevin Wolf
parent 893a9cb47c
commit 2063392ae5
1 changed files with 13 additions and 26 deletions

View File

@ -42,7 +42,6 @@ struct cow_header_v2 {
}; };
typedef struct BDRVCowState { typedef struct BDRVCowState {
int fd;
int64_t cow_sectors_offset; int64_t cow_sectors_offset;
} BDRVCowState; } BDRVCowState;
@ -58,23 +57,16 @@ static int cow_probe(const uint8_t *buf, int buf_size, const char *filename)
return 0; return 0;
} }
static int cow_open(BlockDriverState *bs, const char *filename, int flags) static int cow_open(BlockDriverState *bs, int flags)
{ {
BDRVCowState *s = bs->opaque; BDRVCowState *s = bs->opaque;
int fd;
struct cow_header_v2 cow_header; struct cow_header_v2 cow_header;
int bitmap_size; int bitmap_size;
int64_t size; int64_t size;
fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
if (fd < 0) {
fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
if (fd < 0)
return -1;
}
s->fd = fd;
/* see if it is a cow image */ /* see if it is a cow image */
if (pread(fd, &cow_header, sizeof(cow_header), 0) != sizeof(cow_header)) { if (bdrv_pread(bs->file, 0, &cow_header, sizeof(cow_header)) !=
sizeof(cow_header)) {
goto fail; goto fail;
} }
@ -94,7 +86,6 @@ static int cow_open(BlockDriverState *bs, const char *filename, int flags)
s->cow_sectors_offset = (bitmap_size + 511) & ~511; s->cow_sectors_offset = (bitmap_size + 511) & ~511;
return 0; return 0;
fail: fail:
close(fd);
return -1; return -1;
} }
@ -104,18 +95,17 @@ static int cow_open(BlockDriverState *bs, const char *filename, int flags)
*/ */
static inline int cow_set_bit(BlockDriverState *bs, int64_t bitnum) static inline int cow_set_bit(BlockDriverState *bs, int64_t bitnum)
{ {
BDRVCowState *s = bs->opaque;
uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8; uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8;
uint8_t bitmap; uint8_t bitmap;
if (pread(s->fd, &bitmap, sizeof(bitmap), offset) != if (bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap)) !=
sizeof(bitmap)) { sizeof(bitmap)) {
return -errno; return -errno;
} }
bitmap |= (1 << (bitnum % 8)); bitmap |= (1 << (bitnum % 8));
if (pwrite(s->fd, &bitmap, sizeof(bitmap), offset) != if (bdrv_pwrite(bs->file, offset, &bitmap, sizeof(bitmap)) !=
sizeof(bitmap)) { sizeof(bitmap)) {
return -errno; return -errno;
} }
@ -124,11 +114,10 @@ static inline int cow_set_bit(BlockDriverState *bs, int64_t bitnum)
static inline int is_bit_set(BlockDriverState *bs, int64_t bitnum) static inline int is_bit_set(BlockDriverState *bs, int64_t bitnum)
{ {
BDRVCowState *s = bs->opaque;
uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8; uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8;
uint8_t bitmap; uint8_t bitmap;
if (pread(s->fd, &bitmap, sizeof(bitmap), offset) != if (bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap)) !=
sizeof(bitmap)) { sizeof(bitmap)) {
return -errno; return -errno;
} }
@ -186,8 +175,9 @@ static int cow_read(BlockDriverState *bs, int64_t sector_num,
while (nb_sectors > 0) { while (nb_sectors > 0) {
if (cow_is_allocated(bs, sector_num, nb_sectors, &n)) { if (cow_is_allocated(bs, sector_num, nb_sectors, &n)) {
ret = pread(s->fd, buf, n * 512, ret = bdrv_pread(bs->file,
s->cow_sectors_offset + sector_num * 512); s->cow_sectors_offset + sector_num * 512,
buf, n * 512);
if (ret != n * 512) if (ret != n * 512)
return -1; return -1;
} else { } else {
@ -213,8 +203,8 @@ static int cow_write(BlockDriverState *bs, int64_t sector_num,
BDRVCowState *s = bs->opaque; BDRVCowState *s = bs->opaque;
int ret; int ret;
ret = pwrite(s->fd, buf, nb_sectors * 512, ret = bdrv_pwrite(bs->file, s->cow_sectors_offset + sector_num * 512,
s->cow_sectors_offset + sector_num * 512); buf, nb_sectors * 512);
if (ret != nb_sectors * 512) if (ret != nb_sectors * 512)
return -1; return -1;
@ -223,8 +213,6 @@ static int cow_write(BlockDriverState *bs, int64_t sector_num,
static void cow_close(BlockDriverState *bs) static void cow_close(BlockDriverState *bs)
{ {
BDRVCowState *s = bs->opaque;
close(s->fd);
} }
static int cow_create(const char *filename, QEMUOptionParameter *options) static int cow_create(const char *filename, QEMUOptionParameter *options)
@ -294,8 +282,7 @@ exit:
static void cow_flush(BlockDriverState *bs) static void cow_flush(BlockDriverState *bs)
{ {
BDRVCowState *s = bs->opaque; bdrv_flush(bs->file);
qemu_fdatasync(s->fd);
} }
static QEMUOptionParameter cow_create_options[] = { static QEMUOptionParameter cow_create_options[] = {
@ -316,7 +303,7 @@ static BlockDriver bdrv_cow = {
.format_name = "cow", .format_name = "cow",
.instance_size = sizeof(BDRVCowState), .instance_size = sizeof(BDRVCowState),
.bdrv_probe = cow_probe, .bdrv_probe = cow_probe,
.bdrv_file_open = cow_open, .bdrv_open = cow_open,
.bdrv_read = cow_read, .bdrv_read = cow_read,
.bdrv_write = cow_write, .bdrv_write = cow_write,
.bdrv_close = cow_close, .bdrv_close = cow_close,