xref: /kvmtool/disk/raw.c (revision c9310ac48d9db848c9be0f123aa2f0cb53cc48bf)
1*c9310ac4SAsias He #include "kvm/disk-image.h"
2*c9310ac4SAsias He 
3*c9310ac4SAsias He static ssize_t raw_image__read_sector_iov(struct disk_image *disk, u64 sector, const struct iovec *iov, int iovcount)
4*c9310ac4SAsias He {
5*c9310ac4SAsias He 	u64 offset = sector << SECTOR_SHIFT;
6*c9310ac4SAsias He 
7*c9310ac4SAsias He 	return preadv_in_full(disk->fd, iov, iovcount, offset);
8*c9310ac4SAsias He }
9*c9310ac4SAsias He 
10*c9310ac4SAsias He static ssize_t raw_image__write_sector_iov(struct disk_image *disk, u64 sector, const struct iovec *iov, int iovcount)
11*c9310ac4SAsias He {
12*c9310ac4SAsias He 	u64 offset = sector << SECTOR_SHIFT;
13*c9310ac4SAsias He 
14*c9310ac4SAsias He 	return pwritev_in_full(disk->fd, iov, iovcount, offset);
15*c9310ac4SAsias He }
16*c9310ac4SAsias He 
17*c9310ac4SAsias He static int raw_image__read_sector_ro_mmap(struct disk_image *disk, u64 sector, void *dst, u32 dst_len)
18*c9310ac4SAsias He {
19*c9310ac4SAsias He 	u64 offset = sector << SECTOR_SHIFT;
20*c9310ac4SAsias He 
21*c9310ac4SAsias He 	if (offset + dst_len > disk->size)
22*c9310ac4SAsias He 		return -1;
23*c9310ac4SAsias He 
24*c9310ac4SAsias He 	memcpy(dst, disk->priv + offset, dst_len);
25*c9310ac4SAsias He 
26*c9310ac4SAsias He 	return 0;
27*c9310ac4SAsias He }
28*c9310ac4SAsias He 
29*c9310ac4SAsias He static int raw_image__write_sector_ro_mmap(struct disk_image *disk, u64 sector, void *src, u32 src_len)
30*c9310ac4SAsias He {
31*c9310ac4SAsias He 	u64 offset = sector << SECTOR_SHIFT;
32*c9310ac4SAsias He 
33*c9310ac4SAsias He 	if (offset + src_len > disk->size)
34*c9310ac4SAsias He 		return -1;
35*c9310ac4SAsias He 
36*c9310ac4SAsias He 	memcpy(disk->priv + offset, src, src_len);
37*c9310ac4SAsias He 
38*c9310ac4SAsias He 	return 0;
39*c9310ac4SAsias He }
40*c9310ac4SAsias He 
41*c9310ac4SAsias He static void raw_image__close_ro_mmap(struct disk_image *disk)
42*c9310ac4SAsias He {
43*c9310ac4SAsias He 	if (disk->priv != MAP_FAILED)
44*c9310ac4SAsias He 		munmap(disk->priv, disk->size);
45*c9310ac4SAsias He }
46*c9310ac4SAsias He 
47*c9310ac4SAsias He static struct disk_image_operations raw_image_ops = {
48*c9310ac4SAsias He 	.read_sector_iov	= raw_image__read_sector_iov,
49*c9310ac4SAsias He 	.write_sector_iov	= raw_image__write_sector_iov
50*c9310ac4SAsias He };
51*c9310ac4SAsias He 
52*c9310ac4SAsias He static struct disk_image_operations raw_image_ro_mmap_ops = {
53*c9310ac4SAsias He 	.read_sector		= raw_image__read_sector_ro_mmap,
54*c9310ac4SAsias He 	.write_sector		= raw_image__write_sector_ro_mmap,
55*c9310ac4SAsias He 	.close			= raw_image__close_ro_mmap,
56*c9310ac4SAsias He };
57*c9310ac4SAsias He 
58*c9310ac4SAsias He struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly)
59*c9310ac4SAsias He {
60*c9310ac4SAsias He 	if (readonly)
61*c9310ac4SAsias He 		return disk_image__new_readonly(fd, st->st_size, &raw_image_ro_mmap_ops);
62*c9310ac4SAsias He 	else
63*c9310ac4SAsias He 		return disk_image__new(fd, st->st_size, &raw_image_ops);
64*c9310ac4SAsias He }
65*c9310ac4SAsias He 
66*c9310ac4SAsias He struct disk_image *blkdev__probe(const char *filename, struct stat *st)
67*c9310ac4SAsias He {
68*c9310ac4SAsias He 	u64 size;
69*c9310ac4SAsias He 	int fd;
70*c9310ac4SAsias He 
71*c9310ac4SAsias He 	if (!S_ISBLK(st->st_mode))
72*c9310ac4SAsias He 		return NULL;
73*c9310ac4SAsias He 
74*c9310ac4SAsias He 	fd		= open(filename, O_RDONLY);
75*c9310ac4SAsias He 	if (fd < 0)
76*c9310ac4SAsias He 		return NULL;
77*c9310ac4SAsias He 
78*c9310ac4SAsias He 	if (ioctl(fd, BLKGETSIZE64, &size) < 0) {
79*c9310ac4SAsias He 		close(fd);
80*c9310ac4SAsias He 		return NULL;
81*c9310ac4SAsias He 	}
82*c9310ac4SAsias He 
83*c9310ac4SAsias He 	return disk_image__new_readonly(fd, size, &raw_image_ro_mmap_ops);
84*c9310ac4SAsias He }
85