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