xref: /kvmtool/disk/raw.c (revision 2534c9b6413c6b4b27669f57f7fc77639d0540a3)
1c9310ac4SAsias He #include "kvm/disk-image.h"
2c9310ac4SAsias He 
3*2534c9b6SSasha Levin ssize_t raw_image__read_sector(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*2534c9b6SSasha Levin ssize_t raw_image__write_sector(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*2534c9b6SSasha Levin ssize_t raw_image__read_sector_mmap(struct disk_image *disk, u64 sector, const struct iovec *iov, int iovcount)
18c9310ac4SAsias He {
19c9310ac4SAsias He 	u64 offset = sector << SECTOR_SHIFT;
20*2534c9b6SSasha Levin 	ssize_t nr, total = 0;
21c9310ac4SAsias He 
22*2534c9b6SSasha Levin 	while (iovcount--) {
23*2534c9b6SSasha Levin 		memcpy(iov->iov_base, disk->priv + offset, iov->iov_len);
24c9310ac4SAsias He 
25*2534c9b6SSasha Levin 		sector	+= iov->iov_len >> SECTOR_SHIFT;
26*2534c9b6SSasha Levin 		iov++;
27*2534c9b6SSasha Levin 		total	+= nr;
28c9310ac4SAsias He 	}
29c9310ac4SAsias He 
30*2534c9b6SSasha Levin 	return total;
31*2534c9b6SSasha Levin }
32*2534c9b6SSasha Levin 
33*2534c9b6SSasha Levin ssize_t raw_image__write_sector_mmap(struct disk_image *disk, u64 sector, const struct iovec *iov, int iovcount)
34c9310ac4SAsias He {
35c9310ac4SAsias He 	u64 offset = sector << SECTOR_SHIFT;
36*2534c9b6SSasha Levin 	ssize_t nr, total = 0;
37c9310ac4SAsias He 
38*2534c9b6SSasha Levin 	while (iovcount--) {
39*2534c9b6SSasha Levin 		memcpy(disk->priv + offset, iov->iov_base, iov->iov_len);
40c9310ac4SAsias He 
41*2534c9b6SSasha Levin 		sector	+= iov->iov_len >> SECTOR_SHIFT;
42*2534c9b6SSasha Levin 		iov++;
43*2534c9b6SSasha Levin 		total	+= nr;
44*2534c9b6SSasha Levin 	}
45c9310ac4SAsias He 
46*2534c9b6SSasha Levin 	return total;
47c9310ac4SAsias He }
48c9310ac4SAsias He 
4987ee33c8SAsias He int raw_image__close(struct disk_image *disk)
50c9310ac4SAsias He {
5172133dd2SAsias He 	int ret = 0;
5272133dd2SAsias He 
53c9310ac4SAsias He 	if (disk->priv != MAP_FAILED)
5472133dd2SAsias He 		ret = munmap(disk->priv, disk->size);
5572133dd2SAsias He 
5672133dd2SAsias He 	return ret;
57c9310ac4SAsias He }
58c9310ac4SAsias He 
5987ee33c8SAsias He /*
6087ee33c8SAsias He  * multiple buffer based disk image operations
6187ee33c8SAsias He  */
62*2534c9b6SSasha Levin static struct disk_image_operations raw_image_regular_ops = {
63*2534c9b6SSasha Levin 	.read_sector		= raw_image__read_sector,
64*2534c9b6SSasha Levin 	.write_sector		= raw_image__write_sector,
65c9310ac4SAsias He };
66c9310ac4SAsias He 
6787ee33c8SAsias He /*
68*2534c9b6SSasha Levin  * mmap() based disk image operations
6987ee33c8SAsias He  */
70*2534c9b6SSasha Levin static struct disk_image_operations raw_image_mmap_ops = {
71*2534c9b6SSasha Levin 	.read_sector		= raw_image__read_sector_mmap,
72*2534c9b6SSasha Levin 	.write_sector		= raw_image__write_sector_mmap,
7387ee33c8SAsias He 	.close			= raw_image__close,
74c9310ac4SAsias He };
75c9310ac4SAsias He 
76c9310ac4SAsias He struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly)
77c9310ac4SAsias He {
787d22135fSAsias He 
79c9310ac4SAsias He 	if (readonly)
807d22135fSAsias He 		/*
817d22135fSAsias He 		 * Use mmap's MAP_PRIVATE to implement non-persistent write
827d22135fSAsias He 		 * FIXME: This does not work on 32-bit host.
837d22135fSAsias He 		 */
84*2534c9b6SSasha Levin 		return disk_image__new(fd, st->st_size, &raw_image_mmap_ops, DISK_IMAGE_MMAP);
85c9310ac4SAsias He 	else
867d22135fSAsias He 		/*
877d22135fSAsias He 		 * Use read/write instead of mmap
887d22135fSAsias He 		 */
89*2534c9b6SSasha Levin 		return disk_image__new(fd, st->st_size, &raw_image_regular_ops, DISK_IMAGE_REGULAR);
90c9310ac4SAsias He }
91