xref: /kvmtool/disk/raw.c (revision 708dc6cb4d3c6e6c224fe9016c7ea005e6912ebf) !
1c9310ac4SAsias He #include "kvm/disk-image.h"
2c9310ac4SAsias He 
3*708dc6cbSAsias He ssize_t raw_image__read_sector_iov(struct disk_image *disk, u64 sector, const struct iovec *iov, int iovcount)
4c9310ac4SAsias He {
5c9310ac4SAsias He 	u64 offset = sector << SECTOR_SHIFT;
6c9310ac4SAsias He 
7c9310ac4SAsias He 	return preadv_in_full(disk->fd, iov, iovcount, offset);
8c9310ac4SAsias He }
9c9310ac4SAsias He 
10*708dc6cbSAsias He ssize_t raw_image__write_sector_iov(struct disk_image *disk, u64 sector, const struct iovec *iov, int iovcount)
11c9310ac4SAsias He {
12c9310ac4SAsias He 	u64 offset = sector << SECTOR_SHIFT;
13c9310ac4SAsias He 
14c9310ac4SAsias He 	return pwritev_in_full(disk->fd, iov, iovcount, offset);
15c9310ac4SAsias He }
16c9310ac4SAsias He 
17*708dc6cbSAsias He int raw_image__read_sector_ro_mmap(struct disk_image *disk, u64 sector, void *dst, u32 dst_len)
18c9310ac4SAsias He {
19c9310ac4SAsias He 	u64 offset = sector << SECTOR_SHIFT;
20c9310ac4SAsias He 
21c9310ac4SAsias He 	if (offset + dst_len > disk->size)
22c9310ac4SAsias He 		return -1;
23c9310ac4SAsias He 
24c9310ac4SAsias He 	memcpy(dst, disk->priv + offset, dst_len);
25c9310ac4SAsias He 
26c9310ac4SAsias He 	return 0;
27c9310ac4SAsias He }
28c9310ac4SAsias He 
29*708dc6cbSAsias He int raw_image__write_sector_ro_mmap(struct disk_image *disk, u64 sector, void *src, u32 src_len)
30c9310ac4SAsias He {
31c9310ac4SAsias He 	u64 offset = sector << SECTOR_SHIFT;
32c9310ac4SAsias He 
33c9310ac4SAsias He 	if (offset + src_len > disk->size)
34c9310ac4SAsias He 		return -1;
35c9310ac4SAsias He 
36c9310ac4SAsias He 	memcpy(disk->priv + offset, src, src_len);
37c9310ac4SAsias He 
38c9310ac4SAsias He 	return 0;
39c9310ac4SAsias He }
40c9310ac4SAsias He 
41*708dc6cbSAsias He void raw_image__close_ro_mmap(struct disk_image *disk)
42c9310ac4SAsias He {
43c9310ac4SAsias He 	if (disk->priv != MAP_FAILED)
44c9310ac4SAsias He 		munmap(disk->priv, disk->size);
45c9310ac4SAsias He }
46c9310ac4SAsias He 
47c9310ac4SAsias He static struct disk_image_operations raw_image_ops = {
48c9310ac4SAsias He 	.read_sector_iov	= raw_image__read_sector_iov,
49*708dc6cbSAsias He 	.write_sector_iov	= raw_image__write_sector_iov,
50c9310ac4SAsias He };
51c9310ac4SAsias He 
52c9310ac4SAsias He static struct disk_image_operations raw_image_ro_mmap_ops = {
53c9310ac4SAsias He 	.read_sector		= raw_image__read_sector_ro_mmap,
54c9310ac4SAsias He 	.write_sector		= raw_image__write_sector_ro_mmap,
55c9310ac4SAsias He 	.close			= raw_image__close_ro_mmap,
56c9310ac4SAsias He };
57c9310ac4SAsias He 
58c9310ac4SAsias He struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly)
59c9310ac4SAsias He {
607d22135fSAsias He 
61c9310ac4SAsias He 	if (readonly)
627d22135fSAsias He 		/*
637d22135fSAsias He 		 * Use mmap's MAP_PRIVATE to implement non-persistent write
647d22135fSAsias He 		 * FIXME: This does not work on 32-bit host.
657d22135fSAsias He 		 */
667d22135fSAsias He 		return disk_image__new(fd, st->st_size, &raw_image_ro_mmap_ops, DISK_IMAGE_MMAP);
67c9310ac4SAsias He 	else
687d22135fSAsias He 		/*
697d22135fSAsias He 		 * Use read/write instead of mmap
707d22135fSAsias He 		 */
717d22135fSAsias He 		return disk_image__new(fd, st->st_size, &raw_image_ops, DISK_IMAGE_NOMMAP);
72c9310ac4SAsias He }
73