#include <unistd.h>
#include <fcntl.h>
-struct disk_image *disk_image__open(const char *filename)
+struct disk_image *disk_image__new(int fd, uint64_t size, struct disk_image_operations *ops)
{
struct disk_image *self;
- struct stat st;
self = malloc(sizeof *self);
if (!self)
return NULL;
- self->fd = open(filename, O_RDWR);
- if (self->fd < 0)
- goto failed_free;
-
- if (fstat(self->fd, &st) < 0)
- goto failed_close_fd;
-
- self->size = st.st_size;
+ self->fd = fd;
+ self->size = size;
+ self->ops = ops;
return self;
-
-failed_close_fd:
- close(self->fd);
-failed_free:
- free(self);
-
- return NULL;
}
-void disk_image__close(struct disk_image *self)
-{
- if (close(self->fd) < 0)
- warning("close() failed");
-
- free(self);
-}
-
-int disk_image__read_sector(struct disk_image *self, uint64_t sector, void *dst, uint32_t dst_len)
+static int raw_image__read_sector(struct disk_image *self, uint64_t sector, void *dst, uint32_t dst_len)
{
uint64_t offset = sector << SECTOR_SHIFT;
return 0;
}
-int disk_image__write_sector(struct disk_image *self, uint64_t sector, void *src, uint32_t src_len)
+static int raw_image__write_sector(struct disk_image *self, uint64_t sector, void *src, uint32_t src_len)
{
uint64_t offset = sector << SECTOR_SHIFT;
return 0;
}
+
+static struct disk_image_operations raw_image_ops = {
+ .read_sector = raw_image__read_sector,
+ .write_sector = raw_image__write_sector,
+};
+
+static struct disk_image *raw_image__probe(int fd)
+{
+ struct stat st;
+
+ if (fstat(fd, &st) < 0)
+ return NULL;
+
+ return disk_image__new(fd, st.st_size, &raw_image_ops);
+}
+
+struct disk_image *disk_image__open(const char *filename)
+{
+ struct disk_image *self;
+ int fd;
+
+ fd = open(filename, O_RDWR);
+ if (fd < 0)
+ return NULL;
+
+ self = raw_image__probe(fd);
+ if (self)
+ return self;
+
+ if (close(self->fd) < 0)
+ warning("close() failed");
+
+ return NULL;
+}
+
+void disk_image__close(struct disk_image *self)
+{
+ if (self->ops->close)
+ self->ops->close(self);
+
+ if (close(self->fd) < 0)
+ warning("close() failed");
+
+ free(self);
+}
#define SECTOR_SHIFT 9
#define SECTOR_SIZE (1UL << SECTOR_SHIFT)
+struct disk_image;
+
+struct disk_image_operations {
+ int (*read_sector)(struct disk_image *self, uint64_t sector, void *dst, uint32_t dst_len);
+ int (*write_sector)(struct disk_image *self, uint64_t sector, void *src, uint32_t src_len);
+ void (*close)(struct disk_image *self);
+};
+
struct disk_image {
- int fd;
- uint64_t size;
+ int fd;
+ uint64_t size;
+ struct disk_image_operations *ops;
+ void *priv;
};
struct disk_image *disk_image__open(const char *filename);
+struct disk_image *disk_image__new(int fd, uint64_t size, struct disk_image_operations *ops);
void disk_image__close(struct disk_image *self);
-int disk_image__read_sector(struct disk_image *self, uint64_t sector, void *dst, uint32_t dst_len);
-int disk_image__write_sector(struct disk_image *self, uint64_t sector, void *src, uint32_t src_len);
+
+static inline int disk_image__read_sector(struct disk_image *self, uint64_t sector, void *dst, uint32_t dst_len)
+{
+ return self->ops->read_sector(self, sector, dst, dst_len);
+}
+
+static inline int disk_image__write_sector(struct disk_image *self, uint64_t sector, void *src, uint32_t src_len)
+{
+ return self->ops->write_sector(self, sector, src, src_len);
+}
#endif /* KVM__DISK_IMAGE_H */