19f532d00SPekka Enberg #ifndef KVM__DISK_IMAGE_H 29f532d00SPekka Enberg #define KVM__DISK_IMAGE_H 39f532d00SPekka Enberg 49f532d00SPekka Enberg #include <stdint.h> 59ac38fe1SSasha Levin #include <stdbool.h> 6*70b53f25SSasha Levin #include <sys/uio.h> 79f532d00SPekka Enberg 82924f993SAsias He #define SECTOR_SHIFT 9 92924f993SAsias He #define SECTOR_SIZE (1UL << SECTOR_SHIFT) 102924f993SAsias He 11499f3bedSPekka Enberg struct disk_image; 12499f3bedSPekka Enberg 13499f3bedSPekka Enberg struct disk_image_operations { 14499f3bedSPekka Enberg int (*read_sector)(struct disk_image *self, uint64_t sector, void *dst, uint32_t dst_len); 15499f3bedSPekka Enberg int (*write_sector)(struct disk_image *self, uint64_t sector, void *src, uint32_t src_len); 16*70b53f25SSasha Levin ssize_t (*read_sector_sg)(struct disk_image *self, uint64_t sector, const struct iovec *iov, int iovcount); 17*70b53f25SSasha Levin ssize_t (*write_sector_sg)(struct disk_image *self, uint64_t sector, const struct iovec *iov, int iovcount); 18499f3bedSPekka Enberg void (*close)(struct disk_image *self); 19499f3bedSPekka Enberg }; 20499f3bedSPekka Enberg 219f532d00SPekka Enberg struct disk_image { 229f532d00SPekka Enberg int fd; 239f532d00SPekka Enberg uint64_t size; 24499f3bedSPekka Enberg struct disk_image_operations *ops; 25499f3bedSPekka Enberg void *priv; 269f532d00SPekka Enberg }; 279f532d00SPekka Enberg 289ac38fe1SSasha Levin struct disk_image *disk_image__open(const char *filename, bool readonly); 29f4ff38dfSPrasad Joshi struct disk_image *disk_image__new(int fd, uint64_t size, struct disk_image_operations *ops); 30f4ff38dfSPrasad Joshi struct disk_image *disk_image__new_readonly(int fd, uint64_t size, struct disk_image_operations *ops); 319f532d00SPekka Enberg void disk_image__close(struct disk_image *self); 32499f3bedSPekka Enberg 33499f3bedSPekka Enberg static inline int disk_image__read_sector(struct disk_image *self, uint64_t sector, void *dst, uint32_t dst_len) 34499f3bedSPekka Enberg { 35499f3bedSPekka Enberg return self->ops->read_sector(self, sector, dst, dst_len); 36499f3bedSPekka Enberg } 37499f3bedSPekka Enberg 38499f3bedSPekka Enberg static inline int disk_image__write_sector(struct disk_image *self, uint64_t sector, void *src, uint32_t src_len) 39499f3bedSPekka Enberg { 40499f3bedSPekka Enberg return self->ops->write_sector(self, sector, src, src_len); 41499f3bedSPekka Enberg } 429f532d00SPekka Enberg 43*70b53f25SSasha Levin static inline ssize_t disk_image__read_sector_sg(struct disk_image *self, uint64_t sector, const struct iovec *iov, int iovcount) 44*70b53f25SSasha Levin { 45*70b53f25SSasha Levin if (self->ops->read_sector_sg) 46*70b53f25SSasha Levin return self->ops->read_sector_sg(self, sector, iov, iovcount); 47*70b53f25SSasha Levin 48*70b53f25SSasha Levin while (iovcount--) { 49*70b53f25SSasha Levin self->ops->read_sector(self, sector, iov->iov_base, iov->iov_len); 50*70b53f25SSasha Levin sector += iov->iov_len >> SECTOR_SHIFT; 51*70b53f25SSasha Levin iov++; 52*70b53f25SSasha Levin } 53*70b53f25SSasha Levin 54*70b53f25SSasha Levin return sector << SECTOR_SHIFT; 55*70b53f25SSasha Levin } 56*70b53f25SSasha Levin 57*70b53f25SSasha Levin static inline ssize_t disk_image__write_sector_sg(struct disk_image *self, uint64_t sector, const struct iovec *iov, int iovcount) 58*70b53f25SSasha Levin { 59*70b53f25SSasha Levin if (self->ops->write_sector_sg) 60*70b53f25SSasha Levin return self->ops->write_sector_sg(self, sector, iov, iovcount); 61*70b53f25SSasha Levin 62*70b53f25SSasha Levin while (iovcount--) { 63*70b53f25SSasha Levin self->ops->write_sector(self, sector, iov->iov_base, iov->iov_len); 64*70b53f25SSasha Levin sector += iov->iov_len >> SECTOR_SHIFT; 65*70b53f25SSasha Levin iov++; 66*70b53f25SSasha Levin } 67*70b53f25SSasha Levin 68*70b53f25SSasha Levin return sector << SECTOR_SHIFT; 69*70b53f25SSasha Levin } 70*70b53f25SSasha Levin 719f532d00SPekka Enberg #endif /* KVM__DISK_IMAGE_H */ 72