[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.