[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] blktap: re-enable O_DIRECT in block_qcow.c
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1224672933 -3600 # Node ID 008505c3c65a76917bbd40ba7c2619cbd2fbca53 # Parent 0978bdc056c88144553c2d441611545eced7bc4d blktap: re-enable O_DIRECT in block_qcow.c Turns out that only two reads and writes in block-qcow.c need to be fixed to work correctly with O_DIRECT. Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> --- tools/blktap/drivers/block-qcow.c | 24 +++++++++++++++--------- 1 files changed, 15 insertions(+), 9 deletions(-) diff -r 0978bdc056c8 -r 008505c3c65a tools/blktap/drivers/block-qcow.c --- a/tools/blktap/drivers/block-qcow.c Wed Oct 22 11:53:51 2008 +0100 +++ b/tools/blktap/drivers/block-qcow.c Wed Oct 22 11:55:33 2008 +0100 @@ -722,11 +722,11 @@ static inline void init_fds(struct disk_ /* Open the disk file and initialize qcow state. */ static int tdqcow_open (struct disk_driver *dd, const char *name, td_flag_t flags) { - int fd, len, i, shift, ret, size, l1_table_size, o_flags; + int fd, len, i, shift, ret, size, l1_table_size, o_flags, l1_table_block; int max_aio_reqs; struct td_state *bs = dd->td_state; struct tdqcow_state *s = (struct tdqcow_state *)dd->private; - char *buf; + char *buf, *buf2; QCowHeader *header; QCowHeader_ext *exthdr; uint32_t cksum; @@ -734,8 +734,8 @@ static int tdqcow_open (struct disk_driv DPRINTF("QCOW: Opening %s\n",name); - /* Since we don't handle O_DIRECT correctly, don't use it */ - o_flags = O_LARGEFILE | ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR); + o_flags = O_DIRECT | O_LARGEFILE | + ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR); fd = open(name, o_flags); if (fd < 0) { DPRINTF("Unable to open %s (%d)\n",name,0 - errno); @@ -819,9 +819,14 @@ static int tdqcow_open (struct disk_driv (int) (s->l1_size * sizeof(uint64_t)), l1_table_size); - lseek(fd, s->l1_table_offset, SEEK_SET); - if (read(fd, s->l1_table, l1_table_size) != l1_table_size) + lseek(fd, 0, SEEK_SET); + l1_table_block = l1_table_size + s->l1_table_offset; + l1_table_block = l1_table_block + 512 - (l1_table_block % 512); + ret = posix_memalign((void **)&buf2, 4096, l1_table_block); + if (ret != 0) goto fail; + if (read(fd, buf2, l1_table_block) != l1_table_block) goto fail; + memcpy(s->l1_table, buf2 + s->l1_table_offset, l1_table_size); for(i = 0; i < s->l1_size; i++) { be64_to_cpus(&s->l1_table[i]); @@ -871,8 +876,9 @@ static int tdqcow_open (struct disk_driv DPRINTF("qcow: Converting image to big endian L1 table\n"); - lseek(fd, s->l1_table_offset, SEEK_SET); - if (write(fd, s->l1_table, l1_table_size) != l1_table_size) { + memcpy(buf2 + s->l1_table_offset, s->l1_table, l1_table_size); + lseek(fd, 0, SEEK_SET); + if (write(fd, buf2, l1_table_block) != l1_table_block) { DPRINTF("qcow: Failed to write new L1 table\n"); goto fail; } @@ -917,7 +923,7 @@ static int tdqcow_open (struct disk_driv init_fds(dd); if (!final_cluster) - s->fd_end = s->l1_table_offset + l1_table_size; + s->fd_end = l1_table_block; else { s->fd_end = lseek(fd, 0, SEEK_END); if (s->fd_end == (off_t)-1) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |