ia64/xen-unstable

changeset 18698:008505c3c65a

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@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Oct 22 11:55:33 2008 +0100 (2008-10-22)
parents 0978bdc056c8
children 066c84c7018a
files tools/blktap/drivers/block-qcow.c
line diff
     1.1 --- a/tools/blktap/drivers/block-qcow.c	Wed Oct 22 11:53:51 2008 +0100
     1.2 +++ b/tools/blktap/drivers/block-qcow.c	Wed Oct 22 11:55:33 2008 +0100
     1.3 @@ -722,11 +722,11 @@ static inline void init_fds(struct disk_
     1.4  /* Open the disk file and initialize qcow state. */
     1.5  static int tdqcow_open (struct disk_driver *dd, const char *name, td_flag_t flags)
     1.6  {
     1.7 -	int fd, len, i, shift, ret, size, l1_table_size, o_flags;
     1.8 +	int fd, len, i, shift, ret, size, l1_table_size, o_flags, l1_table_block;
     1.9  	int max_aio_reqs;
    1.10  	struct td_state     *bs = dd->td_state;
    1.11  	struct tdqcow_state *s  = (struct tdqcow_state *)dd->private;
    1.12 -	char *buf;
    1.13 +	char *buf, *buf2;
    1.14  	QCowHeader *header;
    1.15  	QCowHeader_ext *exthdr;
    1.16  	uint32_t cksum;
    1.17 @@ -734,8 +734,8 @@ static int tdqcow_open (struct disk_driv
    1.18  
    1.19   	DPRINTF("QCOW: Opening %s\n",name);
    1.20  
    1.21 -	/* Since we don't handle O_DIRECT correctly, don't use it */
    1.22 -	o_flags = O_LARGEFILE | ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
    1.23 +	o_flags = O_DIRECT | O_LARGEFILE | 
    1.24 +		((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
    1.25  	fd = open(name, o_flags);
    1.26  	if (fd < 0) {
    1.27  		DPRINTF("Unable to open %s (%d)\n",name,0 - errno);
    1.28 @@ -819,9 +819,14 @@ static int tdqcow_open (struct disk_driv
    1.29  		(int) (s->l1_size * sizeof(uint64_t)), 
    1.30  		l1_table_size);
    1.31  
    1.32 -	lseek(fd, s->l1_table_offset, SEEK_SET);
    1.33 -	if (read(fd, s->l1_table, l1_table_size) != l1_table_size)
    1.34 +	lseek(fd, 0, SEEK_SET);
    1.35 +	l1_table_block = l1_table_size + s->l1_table_offset;
    1.36 +	l1_table_block = l1_table_block + 512 - (l1_table_block % 512); 
    1.37 +	ret = posix_memalign((void **)&buf2, 4096, l1_table_block);
    1.38 +	if (ret != 0) goto fail;
    1.39 +	if (read(fd, buf2, l1_table_block) != l1_table_block)
    1.40  		goto fail;
    1.41 +	memcpy(s->l1_table, buf2 + s->l1_table_offset, l1_table_size);
    1.42  
    1.43  	for(i = 0; i < s->l1_size; i++) {
    1.44  		be64_to_cpus(&s->l1_table[i]);
    1.45 @@ -871,8 +876,9 @@ static int tdqcow_open (struct disk_driv
    1.46  
    1.47  			DPRINTF("qcow: Converting image to big endian L1 table\n");
    1.48  
    1.49 -			lseek(fd, s->l1_table_offset, SEEK_SET);
    1.50 -			if (write(fd, s->l1_table, l1_table_size) != l1_table_size) {
    1.51 +			memcpy(buf2 + s->l1_table_offset, s->l1_table, l1_table_size);
    1.52 +			lseek(fd, 0, SEEK_SET);
    1.53 +			if (write(fd, buf2, l1_table_block) != l1_table_block) {
    1.54  				DPRINTF("qcow: Failed to write new L1 table\n");
    1.55  				goto fail;
    1.56  			}
    1.57 @@ -917,7 +923,7 @@ static int tdqcow_open (struct disk_driv
    1.58  	init_fds(dd);
    1.59  
    1.60  	if (!final_cluster)
    1.61 -		s->fd_end = s->l1_table_offset + l1_table_size;
    1.62 +		s->fd_end = l1_table_block;
    1.63  	else {
    1.64  		s->fd_end = lseek(fd, 0, SEEK_END);
    1.65  		if (s->fd_end == (off_t)-1)