Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
__secure_getenv \
secure_getenv \
qsort \
__secure_getenv \
secure_getenv \
qsort \
}
header.as_length = htonl(db->as_count * sizeof(dbas));
}
header.as_length = htonl(db->as_count * sizeof(dbas));
+ // Move to next page boundary
+ while (offset % LOC_DATABASE_PAGE_SIZE > 0)
+ offset += fwrite("", 1, 1, f);
+
// Save the offset of the pool section
DEBUG(db->ctx, "Pool starts at %jd bytes\n", offset);
header.pool_offset = htonl(offset);
// Save the offset of the pool section
DEBUG(db->ctx, "Pool starts at %jd bytes\n", offset);
header.pool_offset = htonl(offset);
#define LOC_DATABASE_MAGIC "LOCDBXX"
#define LOC_DATABASE_VERSION 0
#define LOC_DATABASE_MAGIC "LOCDBXX"
#define LOC_DATABASE_VERSION 0
+#define LOC_DATABASE_PAGE_SIZE 4096
+
struct loc_database_magic {
char magic[7];
struct loc_database_magic {
char magic[7];
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/mman.h>
+#include <unistd.h>
#include <loc/libloc.h>
#include "libloc-private.h"
#include <loc/libloc.h>
#include "libloc-private.h"
+static int loc_stringpool_deallocate(struct loc_stringpool* pool) {
+ if (pool->data) {
+ int r = munmap(pool->data, pool->max_length);
+ if (r) {
+ ERROR(pool->ctx, "Could not unmap data at %p: %s\n",
+ pool->data, strerror(errno));
+
+ return r;
+ }
+ }
+
+ return 0;
+}
+
static int loc_stringpool_allocate(struct loc_stringpool* pool, size_t length) {
// Drop old data
static int loc_stringpool_allocate(struct loc_stringpool* pool, size_t length) {
// Drop old data
- if (pool->data)
- free(pool->data);
+ int r = loc_stringpool_deallocate(pool);
+ if (r)
+ return r;
pool->max_length = length;
pool->max_length = length;
+
+ // Align to page size
+ while (pool->max_length % sysconf(_SC_PAGE_SIZE) > 0)
+ pool->max_length++;
+
DEBUG(pool->ctx, "Allocating pool of %zu bytes\n", pool->max_length);
DEBUG(pool->ctx, "Allocating pool of %zu bytes\n", pool->max_length);
- if (pool->max_length > 0) {
- pool->data = malloc(pool->max_length);
- if (!pool->data)
- return -ENOMEM;
+ // Allocate some memory
+ pool->data = pool->pos = mmap(NULL, pool->max_length,
+ PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+
+ if (pool->data == MAP_FAILED) {
+ DEBUG(pool->ctx, "%s\n", strerror(errno));
+ return -errno;
- pool->pos = pool->data;
+ DEBUG(pool->ctx, "Allocated pool at %p\n", pool->data);
p->refcount = 1;
// Allocate the data section
p->refcount = 1;
// Allocate the data section
- int r = loc_stringpool_allocate(p, max_length);
- if (r) {
- loc_stringpool_unref(p);
- return r;
+ if (max_length > 0) {
+ int r = loc_stringpool_allocate(p, max_length);
+ if (r) {
+ loc_stringpool_unref(p);
+ return r;
+ }
}
DEBUG(p->ctx, "String pool allocated at %p\n", p);
}
DEBUG(p->ctx, "String pool allocated at %p\n", p);
static void loc_stringpool_free(struct loc_stringpool* pool) {
DEBUG(pool->ctx, "Releasing string pool %p\n", pool);
static void loc_stringpool_free(struct loc_stringpool* pool) {
DEBUG(pool->ctx, "Releasing string pool %p\n", pool);
+ loc_stringpool_deallocate(pool);
-
- if (pool->data)
- free(pool->data);
-
-LOC_EXPORT int loc_stringpool_read(struct loc_stringpool* pool, FILE* f, off_t offset, size_t length) {
- // Allocate enough space
- int r = loc_stringpool_allocate(pool, length);
- if (r)
- return r;
-
- DEBUG(pool->ctx, "Reading string pool from %zu\n", offset);
- // Seek to the right offset
- r = fseek(f, offset, SEEK_SET);
- if (r)
- return r;
+LOC_EXPORT int loc_stringpool_read(struct loc_stringpool* pool, FILE* f, off_t offset, size_t length) {
+ DEBUG(pool->ctx, "Reading string pool from %zu (%zu bytes)\n", offset, length);
- size_t bytes_read = fread(pool->data, sizeof(*pool->data), length, f);
- if (bytes_read < length) {
- ERROR(pool->ctx, "Could not read pool. Only read %zu bytes\n", bytes_read);
- return 1;
- }
+ pool->data = pool->pos = mmap(NULL, length, PROT_READ,
+ MAP_PRIVATE, fileno(f), offset);
+ pool->max_length = length;
- DEBUG(pool->ctx, "Read pool of %zu bytes\n", length);
+ if (pool->data == MAP_FAILED)
+ return -errno;