qcow2: cache L1 table (speed up ~10% on my system)
This commit is contained in:
parent
76c7819882
commit
dd34949209
6
io.c
6
io.c
@ -25,7 +25,7 @@ io_init(int *running) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
io_close(struct umka_io *io) {
|
io_close(struct umka_io *io) {
|
||||||
io_async_close(io->async);
|
io_async_close(io->async);
|
||||||
free(io);
|
free(io);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,8 +44,8 @@ ssize_t
|
|||||||
io_write(int fd, const void *buf, size_t count, struct umka_io *io) {
|
io_write(int fd, const void *buf, size_t count, struct umka_io *io) {
|
||||||
ssize_t res;
|
ssize_t res;
|
||||||
if (!*io->running) {
|
if (!*io->running) {
|
||||||
res = write(fd, buf, count);
|
res = write(fd, buf, count);
|
||||||
} else {
|
} else {
|
||||||
res = io_async_write(fd, buf, count, io->async);
|
res = io_async_write(fd, buf, count, io->async);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
#include "miniz/miniz.h"
|
#include "miniz/miniz.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
|
||||||
|
#define L1_MAX_LEN (32u*1024u*1024u)
|
||||||
|
#define L1_MAX_ENTRIES (L1_MAX_LEN / sizeof(uint64_t))
|
||||||
|
|
||||||
struct vdisk_qcow2 {
|
struct vdisk_qcow2 {
|
||||||
struct vdisk vdisk;
|
struct vdisk vdisk;
|
||||||
int fd;
|
int fd;
|
||||||
@ -33,6 +36,7 @@ struct vdisk_qcow2 {
|
|||||||
off_t refcount_table_offset;
|
off_t refcount_table_offset;
|
||||||
size_t l1_size;
|
size_t l1_size;
|
||||||
uint64_t sector_idx_mask;
|
uint64_t sector_idx_mask;
|
||||||
|
uint64_t *l1;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define QCOW2_MAGIC "QFI\xfb"
|
#define QCOW2_MAGIC "QFI\xfb"
|
||||||
@ -93,16 +97,8 @@ qcow2_read_guest_sector(struct vdisk_qcow2 *d, uint64_t sector, uint8_t *buf) {
|
|||||||
uint64_t cluster_index = offset / d->cluster_size;
|
uint64_t cluster_index = offset / d->cluster_size;
|
||||||
uint64_t l1_index = (cluster_index) / l2_entries;
|
uint64_t l1_index = (cluster_index) / l2_entries;
|
||||||
uint64_t l2_index = (cluster_index) % l2_entries;
|
uint64_t l2_index = (cluster_index) % l2_entries;
|
||||||
uint64_t l1_entry;
|
uint64_t l1_entry = d->l1[l1_index];
|
||||||
uint64_t l2_entry;
|
uint64_t l2_entry;
|
||||||
uint64_t l1_entry_offset = d->l1_table_offset + l1_index*sizeof(l1_entry);
|
|
||||||
lseek(d->fd, l1_entry_offset, SEEK_SET);
|
|
||||||
if (!io_read(d->fd, &l1_entry, sizeof(l1_entry), d->vdisk.io)) {
|
|
||||||
fprintf(stderr, "[vdisk.qcow2] can't read from image file: %s\n",
|
|
||||||
strerror(errno));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
l1_entry = be64(&l1_entry);
|
|
||||||
|
|
||||||
uint64_t l2_table_offset = l1_entry & L1_ENTRY_OFFSET_MASK;
|
uint64_t l2_table_offset = l1_entry & L1_ENTRY_OFFSET_MASK;
|
||||||
if (!l2_table_offset) {
|
if (!l2_table_offset) {
|
||||||
@ -162,6 +158,7 @@ vdisk_qcow2_close(void *userdata) {
|
|||||||
}
|
}
|
||||||
free(d->cluster);
|
free(d->cluster);
|
||||||
free(d->cmp_cluster);
|
free(d->cmp_cluster);
|
||||||
|
free(d->l1);
|
||||||
free(d);
|
free(d);
|
||||||
COVERAGE_ON();
|
COVERAGE_ON();
|
||||||
}
|
}
|
||||||
@ -306,5 +303,25 @@ vdisk_init_qcow2(const char *fname, struct umka_io *io) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d->l1 = (uint64_t*)malloc(d->l1_size * sizeof(uint64_t));
|
||||||
|
if (!d->l1) {
|
||||||
|
fprintf(stderr, "[vdisk.qcow2] can't allocate memory: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
vdisk_qcow2_close(d);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
lseek(d->fd, d->l1_table_offset, SEEK_SET);
|
||||||
|
if (!io_read(d->fd, d->l1, d->l1_size * sizeof(uint64_t), d->vdisk.io)) {
|
||||||
|
fprintf(stderr, "[vdisk.qcow2] can't read from image file: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
vdisk_qcow2_close(d);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint64_t *x = d->l1; x < d->l1 + d->l1_size; x++) {
|
||||||
|
*x = be64(x);
|
||||||
|
}
|
||||||
|
|
||||||
return (struct vdisk*)d;
|
return (struct vdisk*)d;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user