xref: /kvmtool/disk/raw.c (revision 87ee33c8e924461317658a87d1cc3cd9b306c908)
1c9310ac4SAsias He #include "kvm/disk-image.h"
2c9310ac4SAsias He 
3708dc6cbSAsias 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 
10708dc6cbSAsias 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*87ee33c8SAsias He ssize_t raw_image__read_sector(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 
2672133dd2SAsias He 	return dst_len;
27c9310ac4SAsias He }
28c9310ac4SAsias He 
29*87ee33c8SAsias He ssize_t raw_image__write_sector(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 
3872133dd2SAsias He 	return src_len;
39c9310ac4SAsias He }
40c9310ac4SAsias He 
41*87ee33c8SAsias He int raw_image__close(struct disk_image *disk)
42c9310ac4SAsias He {
4372133dd2SAsias He 	int ret = 0;
4472133dd2SAsias He 
45c9310ac4SAsias He 	if (disk->priv != MAP_FAILED)
4672133dd2SAsias He 		ret = munmap(disk->priv, disk->size);
4772133dd2SAsias He 
4872133dd2SAsias He 	return ret;
49c9310ac4SAsias He }
50c9310ac4SAsias He 
51*87ee33c8SAsias He /*
52*87ee33c8SAsias He  * multiple buffer based disk image operations
53*87ee33c8SAsias He  */
54*87ee33c8SAsias He static struct disk_image_operations raw_image_iov_ops = {
55c9310ac4SAsias He 	.read_sector_iov	= raw_image__read_sector_iov,
56708dc6cbSAsias He 	.write_sector_iov	= raw_image__write_sector_iov,
57c9310ac4SAsias He };
58c9310ac4SAsias He 
59*87ee33c8SAsias He /*
60*87ee33c8SAsias He  * single buffer based disk image operations
61*87ee33c8SAsias He  */
62*87ee33c8SAsias He static struct disk_image_operations raw_image_ops = {
63*87ee33c8SAsias He 	.read_sector		= raw_image__read_sector,
64*87ee33c8SAsias He 	.write_sector		= raw_image__write_sector,
65*87ee33c8SAsias He 	.close			= raw_image__close,
66c9310ac4SAsias He };
67c9310ac4SAsias He 
68c9310ac4SAsias He struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly)
69c9310ac4SAsias He {
707d22135fSAsias He 
71c9310ac4SAsias He 	if (readonly)
727d22135fSAsias He 		/*
737d22135fSAsias He 		 * Use mmap's MAP_PRIVATE to implement non-persistent write
747d22135fSAsias He 		 * FIXME: This does not work on 32-bit host.
757d22135fSAsias He 		 */
76*87ee33c8SAsias He 		return disk_image__new(fd, st->st_size, &raw_image_ops, DISK_IMAGE_MMAP);
77c9310ac4SAsias He 	else
787d22135fSAsias He 		/*
797d22135fSAsias He 		 * Use read/write instead of mmap
807d22135fSAsias He 		 */
81*87ee33c8SAsias He 		return disk_image__new(fd, st->st_size, &raw_image_iov_ops, DISK_IMAGE_NOMMAP);
82c9310ac4SAsias He }
83