1 #include "kvm/disk-image.h" 2 #include "kvm/qcow.h" 3 4 struct disk_image *disk_image__new(int fd, u64 size, struct disk_image_operations *ops, int use_mmap) 5 { 6 struct disk_image *disk; 7 8 disk = malloc(sizeof *disk); 9 if (!disk) 10 return NULL; 11 12 disk->fd = fd; 13 disk->size = size; 14 disk->ops = ops; 15 16 if (use_mmap == DISK_IMAGE_MMAP) { 17 /* 18 * The write to disk image will be discarded 19 */ 20 disk->priv = mmap(NULL, size, PROT_RW, MAP_PRIVATE | MAP_NORESERVE, fd, 0); 21 if (disk->priv == MAP_FAILED) 22 die("mmap() failed"); 23 } 24 25 return disk; 26 } 27 28 struct disk_image *disk_image__open(const char *filename, bool readonly) 29 { 30 struct disk_image *disk; 31 struct stat st; 32 int fd; 33 34 if (stat(filename, &st) < 0) 35 return NULL; 36 37 if (S_ISBLK(st.st_mode)) 38 return blkdev__probe(filename, &st); 39 40 fd = open(filename, readonly ? O_RDONLY : O_RDWR); 41 if (fd < 0) 42 return NULL; 43 44 disk = qcow_probe(fd, readonly); 45 if (disk) 46 return disk; 47 48 disk = raw_image__probe(fd, &st, readonly); 49 if (disk) 50 return disk; 51 52 if (close(fd) < 0) 53 warning("close() failed"); 54 55 return NULL; 56 } 57 58 void disk_image__close(struct disk_image *disk) 59 { 60 /* If there was no disk image then there's nothing to do: */ 61 if (!disk) 62 return; 63 64 if (disk->ops->close) 65 disk->ops->close(disk); 66 67 if (close(disk->fd) < 0) 68 warning("close() failed"); 69 70 free(disk); 71 } 72 73 /* Fill iov with disk data, starting from sector 'sector'. Return amount of bytes read. */ 74 ssize_t disk_image__read(struct disk_image *disk, u64 sector, const struct iovec *iov, int iovcount) 75 { 76 u64 first_sector = sector; 77 78 if (disk->ops->read_sector_iov) 79 return disk->ops->read_sector_iov(disk, sector, iov, iovcount); 80 81 while (iovcount--) { 82 if (disk->ops->read_sector(disk, sector, iov->iov_base, iov->iov_len) < 0) 83 return -1; 84 85 sector += iov->iov_len >> SECTOR_SHIFT; 86 iov++; 87 } 88 89 return (sector - first_sector) << SECTOR_SHIFT; 90 } 91 92 /* Write iov to disk, starting from sector 'sector'. Return amount of bytes written. */ 93 ssize_t disk_image__write(struct disk_image *disk, u64 sector, const struct iovec *iov, int iovcount) 94 { 95 u64 first_sector = sector; 96 97 if (disk->ops->write_sector_iov) 98 return disk->ops->write_sector_iov(disk, sector, iov, iovcount); 99 100 while (iovcount--) { 101 if (disk->ops->write_sector(disk, sector, iov->iov_base, iov->iov_len) < 0) 102 return -1; 103 104 sector += iov->iov_len >> SECTOR_SHIFT; 105 iov++; 106 } 107 108 return (sector - first_sector) << SECTOR_SHIFT; 109 } 110