# 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
|