This patch modifies the definition and usage of ops for read only, mmap and regular IO. There is no longer a mix between iov and mmap, and read only no longer implies mmap (although it will try to use it first). This allows for more flexibility defining different ops for different scenarios. Signed-off-by: Sasha Levin <levinsasha928@xxxxxxxxx> --- tools/kvm/disk/core.c | 6 ++++-- tools/kvm/disk/raw.c | 46 ++++++++++++++++++++++++++++++---------------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/tools/kvm/disk/core.c b/tools/kvm/disk/core.c index 78495cc..9a84f39 100644 --- a/tools/kvm/disk/core.c +++ b/tools/kvm/disk/core.c @@ -20,8 +20,10 @@ struct disk_image *disk_image__new(int fd, u64 size, struct disk_image_operation * The write to disk image will be discarded */ disk->priv = mmap(NULL, size, PROT_RW, MAP_PRIVATE | MAP_NORESERVE, fd, 0); - if (disk->priv == MAP_FAILED) - die("mmap() failed"); + if (disk->priv == MAP_FAILED) { + free(disk); + disk = NULL; + } } return disk; diff --git a/tools/kvm/disk/raw.c b/tools/kvm/disk/raw.c index 1c6a985..7255eb4 100644 --- a/tools/kvm/disk/raw.c +++ b/tools/kvm/disk/raw.c @@ -17,14 +17,15 @@ ssize_t raw_image__write_sector(struct disk_image *disk, u64 sector, const struc ssize_t raw_image__read_sector_mmap(struct disk_image *disk, u64 sector, const struct iovec *iov, int iovcount) { u64 offset = sector << SECTOR_SHIFT; - ssize_t nr, total = 0; + ssize_t total = 0; while (iovcount--) { memcpy(iov->iov_base, disk->priv + offset, iov->iov_len); sector += iov->iov_len >> SECTOR_SHIFT; + offset += iov->iov_len; + total += iov->iov_len; iov++; - total += nr; } return total; @@ -33,14 +34,15 @@ ssize_t raw_image__read_sector_mmap(struct disk_image *disk, u64 sector, const s ssize_t raw_image__write_sector_mmap(struct disk_image *disk, u64 sector, const struct iovec *iov, int iovcount) { u64 offset = sector << SECTOR_SHIFT; - ssize_t nr, total = 0; + ssize_t total = 0; while (iovcount--) { memcpy(disk->priv + offset, iov->iov_base, iov->iov_len); sector += iov->iov_len >> SECTOR_SHIFT; + offset += iov->iov_len; + total += iov->iov_len; iov++; - total += nr; } return total; @@ -60,31 +62,43 @@ int raw_image__close(struct disk_image *disk) * multiple buffer based disk image operations */ static struct disk_image_operations raw_image_regular_ops = { - .read_sector = raw_image__read_sector, - .write_sector = raw_image__write_sector, + .read_sector = raw_image__read_sector, + .write_sector = raw_image__write_sector, }; -/* - * mmap() based disk image operations - */ -static struct disk_image_operations raw_image_mmap_ops = { - .read_sector = raw_image__read_sector_mmap, - .write_sector = raw_image__write_sector_mmap, - .close = raw_image__close, +struct disk_image_operations ro_ops = { + .read_sector = raw_image__read_sector_mmap, + .write_sector = raw_image__write_sector_mmap, + .close = raw_image__close, +}; + +struct disk_image_operations ro_ops_nowrite = { + .read_sector = raw_image__read_sector, + .write_sector = raw_image__write_sector, }; struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly) { - if (readonly) + if (readonly) { /* * Use mmap's MAP_PRIVATE to implement non-persistent write * FIXME: This does not work on 32-bit host. */ - return disk_image__new(fd, st->st_size, &raw_image_mmap_ops, DISK_IMAGE_MMAP); - else + struct disk_image *disk; + + disk = disk_image__new(fd, st->st_size, &ro_ops, DISK_IMAGE_MMAP); + if (disk == NULL) { + ro_ops = raw_image_regular_ops; + ro_ops.write_sector = NULL; + disk = disk_image__new(fd, st->st_size, &ro_ops_nowrite, DISK_IMAGE_REGULAR); + } + + return disk; + } else { /* * Use read/write instead of mmap */ return disk_image__new(fd, st->st_size, &raw_image_regular_ops, DISK_IMAGE_REGULAR); + } } -- 1.7.7.1 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html