xref: /kvmtool/disk/raw.c (revision 87ee33c8e924461317658a87d1cc3cd9b306c908)
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(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(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(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 /*
52  * multiple buffer based disk image operations
53  */
54 static struct disk_image_operations raw_image_iov_ops = {
55 	.read_sector_iov	= raw_image__read_sector_iov,
56 	.write_sector_iov	= raw_image__write_sector_iov,
57 };
58 
59 /*
60  * single buffer based disk image operations
61  */
62 static struct disk_image_operations raw_image_ops = {
63 	.read_sector		= raw_image__read_sector,
64 	.write_sector		= raw_image__write_sector,
65 	.close			= raw_image__close,
66 };
67 
68 struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly)
69 {
70 
71 	if (readonly)
72 		/*
73 		 * Use mmap's MAP_PRIVATE to implement non-persistent write
74 		 * FIXME: This does not work on 32-bit host.
75 		 */
76 		return disk_image__new(fd, st->st_size, &raw_image_ops, DISK_IMAGE_MMAP);
77 	else
78 		/*
79 		 * Use read/write instead of mmap
80 		 */
81 		return disk_image__new(fd, st->st_size, &raw_image_iov_ops, DISK_IMAGE_NOMMAP);
82 }
83