xref: /kvmtool/disk/raw.c (revision 72133dd2d8ab6fbc651a5e3b65391f2bcd29c7d5)
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 ssize_t 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 dst_len;
27 }
28 
29 ssize_t 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 src_len;
39 }
40 
41 int raw_image__close_ro_mmap(struct disk_image *disk)
42 {
43 	int ret = 0;
44 
45 	if (disk->priv != MAP_FAILED)
46 		ret = munmap(disk->priv, disk->size);
47 
48 	return ret;
49 }
50 
51 static struct disk_image_operations raw_image_ops = {
52 	.read_sector_iov	= raw_image__read_sector_iov,
53 	.write_sector_iov	= raw_image__write_sector_iov,
54 };
55 
56 static struct disk_image_operations raw_image_ro_mmap_ops = {
57 	.read_sector		= raw_image__read_sector_ro_mmap,
58 	.write_sector		= raw_image__write_sector_ro_mmap,
59 	.close			= raw_image__close_ro_mmap,
60 };
61 
62 struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly)
63 {
64 
65 	if (readonly)
66 		/*
67 		 * Use mmap's MAP_PRIVATE to implement non-persistent write
68 		 * FIXME: This does not work on 32-bit host.
69 		 */
70 		return disk_image__new(fd, st->st_size, &raw_image_ro_mmap_ops, DISK_IMAGE_MMAP);
71 	else
72 		/*
73 		 * Use read/write instead of mmap
74 		 */
75 		return disk_image__new(fd, st->st_size, &raw_image_ops, DISK_IMAGE_NOMMAP);
76 }
77