From bdb9b65e55f79a8482a7179aab8548a3764b032a Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Wed, 2 Nov 2011 07:41:07 +0200 Subject: [PATCH] kvm tools: Modify disk ops usage 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 Signed-off-by: Pekka Enberg --- 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 78495cc1d29c..9a84f3946d49 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 1c6a985f8c6e..7255eb4477eb 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); + } } -- 2.39.5