ia64/xen-unstable

changeset 18654:0a09de68c541

blktap: Handle qcow backing files correctly.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Mon Oct 20 15:08:24 2008 +0100 (2008-10-20)
parents cbc254c59dd0
children 314df03b7d61
files tools/blktap/drivers/block-qcow.c tools/blktap/drivers/block-qcow2.c
line diff
     1.1 --- a/tools/blktap/drivers/block-qcow.c	Mon Oct 20 15:05:48 2008 +0100
     1.2 +++ b/tools/blktap/drivers/block-qcow.c	Mon Oct 20 15:08:24 2008 +0100
     1.3 @@ -734,8 +734,8 @@ static int tdqcow_open (struct disk_driv
     1.4  
     1.5   	DPRINTF("QCOW: Opening %s\n",name);
     1.6  
     1.7 -	o_flags = O_DIRECT | O_LARGEFILE | 
     1.8 -		((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
     1.9 +	/* Since we don't handle O_DIRECT correctly, don't use it */
    1.10 +	o_flags = O_LARGEFILE | ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
    1.11  	fd = open(name, o_flags);
    1.12  	if (fd < 0) {
    1.13  		DPRINTF("Unable to open %s (%d)\n",name,0 - errno);
    1.14 @@ -1385,7 +1385,7 @@ static int tdqcow_get_parent_id(struct d
    1.15  	filename[len]  = '\0';
    1.16  
    1.17  	id->name       = strdup(filename);
    1.18 -	id->drivertype = DISK_TYPE_QCOW;
    1.19 +	id->drivertype = DISK_TYPE_AIO;
    1.20  	err            = 0;
    1.21   out:
    1.22  	free(buf);
    1.23 @@ -1397,17 +1397,15 @@ static int tdqcow_validate_parent(struct
    1.24  {
    1.25  	struct stat stats;
    1.26  	uint64_t psize, csize;
    1.27 -	struct tdqcow_state *c = (struct tdqcow_state *)child->private;
    1.28 -	struct tdqcow_state *p = (struct tdqcow_state *)parent->private;
    1.29  	
    1.30 -	if (stat(p->name, &stats))
    1.31 +	if (stat(parent->name, &stats))
    1.32  		return -EINVAL;
    1.33 -	if (get_filesize(p->name, &psize, &stats))
    1.34 +	if (get_filesize(parent->name, &psize, &stats))
    1.35  		return -EINVAL;
    1.36  
    1.37 -	if (stat(c->name, &stats))
    1.38 +	if (stat(child->name, &stats))
    1.39  		return -EINVAL;
    1.40 -	if (get_filesize(c->name, &csize, &stats))
    1.41 +	if (get_filesize(child->name, &csize, &stats))
    1.42  		return -EINVAL;
    1.43  
    1.44  	if (csize != psize)
     2.1 --- a/tools/blktap/drivers/block-qcow2.c	Mon Oct 20 15:05:48 2008 +0100
     2.2 +++ b/tools/blktap/drivers/block-qcow2.c	Mon Oct 20 15:08:24 2008 +0100
     2.3 @@ -34,6 +34,7 @@
     2.4  #include "tapdisk.h"
     2.5  #include "tapaio.h"
     2.6  #include "bswap.h"
     2.7 +#include "blk.h"
     2.8  
     2.9  #define USE_AIO
    2.10  
    2.11 @@ -1902,6 +1903,42 @@ repeat:
    2.12  
    2.13  #endif	
    2.14  
    2.15 +static int get_filesize(char *filename, uint64_t *size, struct stat *st)
    2.16 +{
    2.17 +	int fd;
    2.18 +	QCowHeader header;
    2.19 +
    2.20 +	/*Set to the backing file size*/
    2.21 +	fd = open(filename, O_RDONLY);
    2.22 +	if (fd < 0)
    2.23 +		return -1;
    2.24 +	if (read(fd, &header, sizeof(header)) < sizeof(header)) {
    2.25 +		close(fd);
    2.26 +		return -1;
    2.27 +	}
    2.28 +	close(fd);
    2.29 +	
    2.30 +	be32_to_cpus(&header.magic);
    2.31 +	be32_to_cpus(&header.version);
    2.32 +	be64_to_cpus(&header.size);
    2.33 +	if (header.magic == QCOW_MAGIC && header.version == QCOW_VERSION) {
    2.34 +		*size = header.size >> SECTOR_SHIFT;
    2.35 +		return 0;
    2.36 +	}
    2.37 +
    2.38 +	if(S_ISBLK(st->st_mode)) {
    2.39 +		fd = open(filename, O_RDONLY);
    2.40 +		if (fd < 0)
    2.41 +			return -1;
    2.42 +		if (blk_getimagesize(fd, size) != 0) {
    2.43 +			close(fd);
    2.44 +			return -1;
    2.45 +		}
    2.46 +		close(fd);
    2.47 +	} else *size = (st->st_size >> SECTOR_SHIFT);	
    2.48 +	return 0;
    2.49 +}
    2.50 +
    2.51  /**
    2.52   * @return 
    2.53   *	   0 if parent id successfully retrieved;
    2.54 @@ -1916,7 +1953,7 @@ static int qcow_get_parent_id(struct dis
    2.55  		return TD_NO_PARENT;
    2.56  
    2.57  	id->name = strdup(s->backing_file);
    2.58 -	id->drivertype = DISK_TYPE_QCOW2;
    2.59 +	id->drivertype = DISK_TYPE_AIO;
    2.60  
    2.61  	return 0;
    2.62  }
    2.63 @@ -1924,15 +1961,22 @@ static int qcow_get_parent_id(struct dis
    2.64  static int qcow_validate_parent(struct disk_driver *child, 
    2.65  		struct disk_driver *parent, td_flag_t flags)
    2.66  {
    2.67 -	struct BDRVQcowState *cs = (struct BDRVQcowState*) child->private;
    2.68 -	struct BDRVQcowState *ps = (struct BDRVQcowState*) parent->private;
    2.69 +	struct stat stats;
    2.70 +	uint64_t psize, csize;
    2.71 +	
    2.72 +	if (stat(parent->name, &stats))
    2.73 +		return -EINVAL;
    2.74 +	if (get_filesize(parent->name, &psize, &stats))
    2.75 +		return -EINVAL;
    2.76  
    2.77 -	if (ps->total_sectors != cs->total_sectors) {
    2.78 -		DPRINTF("qcow_validate_parent(): %#"PRIx64" != %#"PRIx64"\n",
    2.79 -			ps->total_sectors, cs->total_sectors);
    2.80 +	if (stat(child->name, &stats))
    2.81  		return -EINVAL;
    2.82 -	}
    2.83 -	
    2.84 +	if (get_filesize(child->name, &csize, &stats))
    2.85 +		return -EINVAL;
    2.86 +
    2.87 +	if (csize != psize)
    2.88 +		return -EINVAL;
    2.89 +
    2.90  	return 0;
    2.91  }
    2.92