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 int 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 0; 63 64 if (disk->ops->close) 65 return disk->ops->close(disk); 66 67 if (close(disk->fd) < 0) 68 warning("close() failed"); 69 70 free(disk); 71 72 return 0; 73 } 74 75 /* Fill iov with disk data, starting from sector 'sector'. Return amount of bytes read. */ 76 ssize_t disk_image__read(struct disk_image *disk, u64 sector, const struct iovec *iov, int iovcount) 77 { 78 u64 first_sector = sector; 79 80 if (disk->ops->read_sector_iov) 81 return disk->ops->read_sector_iov(disk, sector, iov, iovcount); 82 83 while (iovcount--) { 84 if (disk->ops->read_sector(disk, sector, iov->iov_base, iov->iov_len) < 0) 85 return -1; 86 87 sector += iov->iov_len >> SECTOR_SHIFT; 88 iov++; 89 } 90 91 return (sector - first_sector) << SECTOR_SHIFT; 92 } 93 94 /* Write iov to disk, starting from sector 'sector'. Return amount of bytes written. */ 95 ssize_t disk_image__write(struct disk_image *disk, u64 sector, const struct iovec *iov, int iovcount) 96 { 97 u64 first_sector = sector; 98 99 if (disk->ops->write_sector_iov) 100 return disk->ops->write_sector_iov(disk, sector, iov, iovcount); 101 102 while (iovcount--) { 103 if (disk->ops->write_sector(disk, sector, iov->iov_base, iov->iov_len) < 0) 104 return -1; 105 106 sector += iov->iov_len >> SECTOR_SHIFT; 107 iov++; 108 } 109 110 return (sector - first_sector) << SECTOR_SHIFT; 111 } 112