return disk->ops->read_sector_iov(disk, sector, iov, iovcount);
while (iovcount--) {
- disk->ops->read_sector(disk, sector, iov->iov_base, iov->iov_len);
+ if (disk->ops->read_sector(disk, sector, iov->iov_base, iov->iov_len) < 0)
+ return -1;
+
sector += iov->iov_len >> SECTOR_SHIFT;
iov++;
}
return disk->ops->write_sector_iov(disk, sector, iov, iovcount);
while (iovcount--) {
- disk->ops->write_sector(disk, sector, iov->iov_base, iov->iov_len);
+ if (disk->ops->write_sector(disk, sector, iov->iov_base, iov->iov_len) < 0)
+ return -1;
+
sector += iov->iov_len >> SECTOR_SHIFT;
iov++;
}
return 0;
}
+static int qcow1_nowrite_sector(struct disk_image *disk, u64 sector, void *src, u32 src_len)
+{
+ /* I/O error */
+ return -1;
+}
+
static void qcow1_disk_close(struct disk_image *disk)
{
struct qcow *q;
free(q);
}
-struct disk_image_operations qcow1_disk_ops = {
+static struct disk_image_operations qcow1_disk_readonly_ops = {
+ .read_sector = qcow1_read_sector,
+ .write_sector = qcow1_nowrite_sector,
+ .close = qcow1_disk_close
+};
+
+static struct disk_image_operations qcow1_disk_ops = {
.read_sector = qcow1_read_sector,
.write_sector = qcow1_write_sector,
.close = qcow1_disk_close
return header;
}
-static struct disk_image *qcow2_probe(int fd)
+static struct disk_image *qcow2_probe(int fd, bool readonly)
{
struct qcow *q;
struct qcow_header *h;
if (qcow_read_l1_table(q) < 0)
goto error;
- disk_image = disk_image__new(fd, h->size, &qcow1_disk_ops);
+ if (readonly)
+ disk_image = disk_image__new(fd, h->size, &qcow1_disk_readonly_ops);
+ else
+ disk_image = disk_image__new(fd, h->size, &qcow1_disk_ops);
+
if (!disk_image)
goto error;
disk_image->priv = q;
return header;
}
-static struct disk_image *qcow1_probe(int fd)
+static struct disk_image *qcow1_probe(int fd, bool readonly)
{
struct qcow *q;
struct qcow_header *h;
if (qcow_read_l1_table(q) < 0)
goto error;
- disk_image = disk_image__new(fd, h->size, &qcow1_disk_ops);
+ if (readonly)
+ disk_image = disk_image__new(fd, h->size, &qcow1_disk_readonly_ops);
+ else
+ disk_image = disk_image__new(fd, h->size, &qcow1_disk_ops);
+
if (!disk_image)
goto error;
disk_image->priv = q;
return true;
}
-struct disk_image *qcow_probe(int fd)
+struct disk_image *qcow_probe(int fd, bool readonly)
{
if (qcow1_check_image(fd))
- return qcow1_probe(fd);
+ return qcow1_probe(fd, readonly);
if (qcow2_check_image(fd))
- return qcow2_probe(fd);
+ return qcow2_probe(fd, readonly);
return NULL;
}