Stefano Stabellini
2008-Oct-21 16:15 UTC
[Xen-devel] [PATCH] blktap: renable O_DIRECT in block_qcow.c
Enable O_DIRECT again 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@eu.citrix.com> --- diff -r 3b99705155c1 tools/blktap/drivers/block-qcow.c --- a/tools/blktap/drivers/block-qcow.c Tue Oct 21 11:44:39 2008 +0100 +++ b/tools/blktap/drivers/block-qcow.c Tue Oct 21 16:48:13 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-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel