]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm tools: Modify disk ops usage
authorSasha Levin <levinsasha928@gmail.com>
Wed, 2 Nov 2011 05:41:07 +0000 (07:41 +0200)
committerPekka Enberg <penberg@kernel.org>
Wed, 2 Nov 2011 06:21:30 +0000 (08:21 +0200)
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@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
tools/kvm/disk/core.c
tools/kvm/disk/raw.c

index 78495cc1d29c08c6f416c23e07878186133865ca..9a84f3946d499270b51f1420866ee203d6165915 100644 (file)
@@ -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;
index 1c6a985f8c6ea02fa3a1ffe151e9d052e8e3f6be..7255eb4477eb73fc7f3455fb4e0e7379a63f883a 100644 (file)
@@ -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);
+       }
 }