(Thanks to report from Daniel Berrange.
Corresponds to my email to xen-devel of 2008-02-27
Subject: Re: [Xen-devel] [PATCH] ioemu block device extent checks.)
int len, i, shift, ret;
QCowHeader header;
- ret = bdrv_file_open(&s->hd, filename, flags);
+ ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_EXTENDABLE);
if (ret < 0)
return ret;
if (bdrv_pread(s->hd, 0, &header, sizeof(header)) != sizeof(header))
int len, i, shift, ret;
QCowHeader header;
- ret = bdrv_file_open(&s->hd, filename, flags);
+ ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_EXTENDABLE);
if (ret < 0)
return ret;
if (bdrv_pread(s->hd, 0, &header, sizeof(header)) != sizeof(header))
.bdrv_set_locked = raw_set_locked,
/* generic scsi device */
.bdrv_ioctl = raw_ioctl,
+
+ .bdrv_flags = BLOCK_DRIVER_FLAG_EXTENDABLE
};
.bdrv_pread = raw_pread,
.bdrv_pwrite = raw_pwrite,
.bdrv_getlength = raw_getlength,
+
+ .bdrv_flags = BLOCK_DRIVER_FLAG_EXTENDABLE;
};
flags = BDRV_O_RDONLY;
fprintf(stderr, "(VMDK) image open: flags=0x%x filename=%s\n", flags, bs->filename);
- ret = bdrv_file_open(&s->hd, filename, flags);
+ ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_EXTENDABLE);
if (ret < 0)
return ret;
if (bdrv_pread(s->hd, 0, &magic, sizeof(magic)) != sizeof(magic))
static int bdrv_rw_badreq_sectors(BlockDriverState *bs,
int64_t sector_num, int nb_sectors)
{
- return
+ return (
nb_sectors < 0 ||
nb_sectors > bs->total_sectors ||
- sector_num > bs->total_sectors - nb_sectors;
+ sector_num > bs->total_sectors - nb_sectors
+ ) && !bs->extendable;
}
static int bdrv_rw_badreq_bytes(BlockDriverState *bs,
int64_t offset, int count)
{
int64_t size = bs->total_sectors << SECTOR_BITS;
- return
+ return (
count < 0 ||
count > size ||
- offset > size - count;
+ offset > size - count
+ ) && !bs->extendable;
+
}
static void bdrv_register(BlockDriver *bdrv)
bs->is_temporary = 0;
bs->encrypted = 0;
+ if (flags & BDRV_O_EXTENDABLE) {
+ if (!(drv->bdrv_flags & BLOCK_DRIVER_FLAG_EXTENDABLE))
+ return -ENOSYS;
+ bs->extendable = 1;
+ }
+
if (flags & BDRV_O_SNAPSHOT) {
BlockDriverState *bs1;
int64_t total_size;
it (default for
bdrv_file_open()) */
#define BDRV_O_DIRECT 0x0020
+#define BDRV_O_EXTENDABLE 0x0080 /* allow writes out of original size range;
+ only effective for some drivers */
#ifndef QEMU_IMG
void bdrv_info(void);
#define BLOCK_FLAG_COMPRESS 2
#define BLOCK_FLAG_COMPAT6 4
+#define BLOCK_DRIVER_FLAG_EXTENDABLE 0x0001u
+
struct BlockDriver {
const char *format_name;
int instance_size;
/* to control generic scsi devices */
int (*bdrv_ioctl)(BlockDriverState *bs, unsigned long int req, void *buf);
+ unsigned bdrv_flags;
BlockDriverAIOCB *free_aiocb;
struct BlockDriver *next;
};
int locked; /* if true, the media cannot temporarily be ejected */
int encrypted; /* if true, the media is encrypted */
int sg; /* if true, the device is a /dev/sg* */
+ int extendable;/* if true, we may write out of original range */
/* event callback when inserting/removing */
void (*change_cb)(void *opaque);
void *change_opaque;