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