1*c9310ac4SAsias He #include "kvm/disk-image.h" 2*c9310ac4SAsias He 3*c9310ac4SAsias He static ssize_t raw_image__read_sector_iov(struct disk_image *disk, u64 sector, const struct iovec *iov, int iovcount) 4*c9310ac4SAsias He { 5*c9310ac4SAsias He u64 offset = sector << SECTOR_SHIFT; 6*c9310ac4SAsias He 7*c9310ac4SAsias He return preadv_in_full(disk->fd, iov, iovcount, offset); 8*c9310ac4SAsias He } 9*c9310ac4SAsias He 10*c9310ac4SAsias He static ssize_t raw_image__write_sector_iov(struct disk_image *disk, u64 sector, const struct iovec *iov, int iovcount) 11*c9310ac4SAsias He { 12*c9310ac4SAsias He u64 offset = sector << SECTOR_SHIFT; 13*c9310ac4SAsias He 14*c9310ac4SAsias He return pwritev_in_full(disk->fd, iov, iovcount, offset); 15*c9310ac4SAsias He } 16*c9310ac4SAsias He 17*c9310ac4SAsias He static int raw_image__read_sector_ro_mmap(struct disk_image *disk, u64 sector, void *dst, u32 dst_len) 18*c9310ac4SAsias He { 19*c9310ac4SAsias He u64 offset = sector << SECTOR_SHIFT; 20*c9310ac4SAsias He 21*c9310ac4SAsias He if (offset + dst_len > disk->size) 22*c9310ac4SAsias He return -1; 23*c9310ac4SAsias He 24*c9310ac4SAsias He memcpy(dst, disk->priv + offset, dst_len); 25*c9310ac4SAsias He 26*c9310ac4SAsias He return 0; 27*c9310ac4SAsias He } 28*c9310ac4SAsias He 29*c9310ac4SAsias He static int raw_image__write_sector_ro_mmap(struct disk_image *disk, u64 sector, void *src, u32 src_len) 30*c9310ac4SAsias He { 31*c9310ac4SAsias He u64 offset = sector << SECTOR_SHIFT; 32*c9310ac4SAsias He 33*c9310ac4SAsias He if (offset + src_len > disk->size) 34*c9310ac4SAsias He return -1; 35*c9310ac4SAsias He 36*c9310ac4SAsias He memcpy(disk->priv + offset, src, src_len); 37*c9310ac4SAsias He 38*c9310ac4SAsias He return 0; 39*c9310ac4SAsias He } 40*c9310ac4SAsias He 41*c9310ac4SAsias He static void raw_image__close_ro_mmap(struct disk_image *disk) 42*c9310ac4SAsias He { 43*c9310ac4SAsias He if (disk->priv != MAP_FAILED) 44*c9310ac4SAsias He munmap(disk->priv, disk->size); 45*c9310ac4SAsias He } 46*c9310ac4SAsias He 47*c9310ac4SAsias He static struct disk_image_operations raw_image_ops = { 48*c9310ac4SAsias He .read_sector_iov = raw_image__read_sector_iov, 49*c9310ac4SAsias He .write_sector_iov = raw_image__write_sector_iov 50*c9310ac4SAsias He }; 51*c9310ac4SAsias He 52*c9310ac4SAsias He static struct disk_image_operations raw_image_ro_mmap_ops = { 53*c9310ac4SAsias He .read_sector = raw_image__read_sector_ro_mmap, 54*c9310ac4SAsias He .write_sector = raw_image__write_sector_ro_mmap, 55*c9310ac4SAsias He .close = raw_image__close_ro_mmap, 56*c9310ac4SAsias He }; 57*c9310ac4SAsias He 58*c9310ac4SAsias He struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly) 59*c9310ac4SAsias He { 60*c9310ac4SAsias He if (readonly) 61*c9310ac4SAsias He return disk_image__new_readonly(fd, st->st_size, &raw_image_ro_mmap_ops); 62*c9310ac4SAsias He else 63*c9310ac4SAsias He return disk_image__new(fd, st->st_size, &raw_image_ops); 64*c9310ac4SAsias He } 65*c9310ac4SAsias He 66*c9310ac4SAsias He struct disk_image *blkdev__probe(const char *filename, struct stat *st) 67*c9310ac4SAsias He { 68*c9310ac4SAsias He u64 size; 69*c9310ac4SAsias He int fd; 70*c9310ac4SAsias He 71*c9310ac4SAsias He if (!S_ISBLK(st->st_mode)) 72*c9310ac4SAsias He return NULL; 73*c9310ac4SAsias He 74*c9310ac4SAsias He fd = open(filename, O_RDONLY); 75*c9310ac4SAsias He if (fd < 0) 76*c9310ac4SAsias He return NULL; 77*c9310ac4SAsias He 78*c9310ac4SAsias He if (ioctl(fd, BLKGETSIZE64, &size) < 0) { 79*c9310ac4SAsias He close(fd); 80*c9310ac4SAsias He return NULL; 81*c9310ac4SAsias He } 82*c9310ac4SAsias He 83*c9310ac4SAsias He return disk_image__new_readonly(fd, size, &raw_image_ro_mmap_ops); 84*c9310ac4SAsias He } 85