pma: more mmap changes. WIP

This commit is contained in:
barter-simsum 2023-12-12 22:22:48 -05:00
parent 13b5f6bee6
commit 7dfc32681a

View File

@ -88,7 +88,7 @@ STATIC_ASSERT(0, "debugger break instruction unimplemented");
#define SUCC(x) ((x) == BT_SUCC) #define SUCC(x) ((x) == BT_SUCC)
#define BT_MAPADDR ((void *) S(0x1000,0000,0000)) #define BT_MAPADDR ((BYTE *) S(0x1000,0000,0000))
static inline vaof_t static inline vaof_t
addr2off(void *p) addr2off(void *p)
@ -111,6 +111,7 @@ off2addr(vaof_t off)
#define BT_PAGEWORD 32ULL #define BT_PAGEWORD 32ULL
#define BT_NUMMETAS 2 /* 2 metapages */ #define BT_NUMMETAS 2 /* 2 metapages */
#define BT_META_SECTION_WIDTH (BT_NUMMETAS * BT_PAGESIZE)
#define BT_ADDRSIZE (BT_PAGESIZE << BT_PAGEWORD) #define BT_ADDRSIZE (BT_PAGESIZE << BT_PAGEWORD)
#define PMA_GROW_SIZE (BT_PAGESIZE * 1024 * 64) #define PMA_GROW_SIZE (BT_PAGESIZE * 1024 * 64)
@ -235,7 +236,7 @@ static_assert(BT_DAT_MAXBYTES % sizeof(BT_dat) == 0);
a meta page is like any other page, but the data section is used to store a meta page is like any other page, but the data section is used to store
additional information additional information
*/ */
#define BLK_BASE_LEN0 (MBYTES(2) - (BT_PAGESIZE * BT_NUMMETAS)) #define BLK_BASE_LEN0 (MBYTES(2) - BT_META_SECTION_WIDTH)
#define BLK_BASE_LEN1 (BLK_BASE_LEN0 * 4) #define BLK_BASE_LEN1 (BLK_BASE_LEN0 * 4)
#define BLK_BASE_LEN2 (BLK_BASE_LEN1 * 4) #define BLK_BASE_LEN2 (BLK_BASE_LEN1 * 4)
#define BLK_BASE_LEN3 (BLK_BASE_LEN2 * 4) #define BLK_BASE_LEN3 (BLK_BASE_LEN2 * 4)
@ -409,8 +410,10 @@ _bt_nalloc(BT_state *state)
} }
} }
/* make node writeable */ /* make node writable */
mprotect(ret, sizeof(BT_page), PROT_READ | PROT_WRITE); mprotect(ret, sizeof(BT_page), PROT_READ | PROT_WRITE);
return ret;
} }
static int static int
@ -1498,7 +1501,7 @@ _flist_grow(BT_state *state, BT_flistnode *space)
static int static int
_flist_new(BT_state *state) _flist_new(BT_state *state)
#define FLIST_PG_START (((BT_PAGESIZE * BT_NUMMETAS) + BLK_BASE_LEN0) / BT_PAGESIZE) #define FLIST_PG_START ((BT_META_SECTION_WIDTH + BLK_BASE_LEN0) / BT_PAGESIZE)
{ {
BT_meta *meta = state->meta_pages[state->which]; BT_meta *meta = state->meta_pages[state->which];
BT_page *root = _node_get(state, meta->root); BT_page *root = _node_get(state, meta->root);
@ -2189,6 +2192,13 @@ _bt_state_meta_new(BT_state *state)
TRACE(); TRACE();
/* open the metapage region for writing */
if (mprotect(BT_MAPADDR, BT_META_SECTION_WIDTH,
PROT_READ | PROT_WRITE) != 0) {
DPRINTF("mprotect of metapage section failed with %s", strerror(errno));
abort();
}
/* initialize the block base array */ /* initialize the block base array */
meta.blk_base[0] = BT_PAGESIZE * BT_NUMMETAS; meta.blk_base[0] = BT_PAGESIZE * BT_NUMMETAS;
@ -2219,6 +2229,17 @@ _bt_state_meta_new(BT_state *state)
first?? */ first?? */
memcpy(METADATA(p2), &meta, sizeof meta); memcpy(METADATA(p2), &meta, sizeof meta);
/* only the active metapage should be writable (first page) */
if (mprotect(BT_MAPADDR, BT_META_SECTION_WIDTH, PROT_READ) != 0) {
DPRINTF("mprotect of metapage section failed with %s", strerror(errno));
abort();
}
if (mprotect(BT_MAPADDR, BT_PAGESIZE,
PROT_READ | PROT_WRITE) != 0) {
DPRINTF("mprotect of current metapage failed with %s", strerror(errno));
abort();
}
return BT_SUCC; return BT_SUCC;
} }
@ -2242,11 +2263,10 @@ _bt_state_load(BT_state *state)
} }
} }
/* map first node stripe (along with metapages) as read only */
state->map = mmap(BT_MAPADDR, state->map = mmap(BT_MAPADDR,
BT_ADDRSIZE, /* should actually just be first 2M BT_META_SECTION_WIDTH + BLK_BASE_LEN0,
stripe. and then from there PROT_READ,
should map like it's freespace. */
PROT_READ | PROT_WRITE, /* ;;: PROT_READ */
MAP_FIXED | MAP_SHARED, MAP_FIXED | MAP_SHARED,
state->data_fd, state->data_fd,
0); 0);
@ -2420,7 +2440,7 @@ _bt_sync_meta(BT_state *state)
newwhich = state->which ? 0 : 1; newwhich = state->which ? 0 : 1;
newmeta = state->meta_pages[newwhich]; newmeta = state->meta_pages[newwhich];
/* make new metapage writeable */ /* make new metapage writable */
if (mprotect(newmeta, sizeof(BT_page), PROT_READ | PROT_WRITE) != 0) { if (mprotect(newmeta, sizeof(BT_page), PROT_READ | PROT_WRITE) != 0) {
DPRINTF("mprotect of new metapage failed with %s", strerror(errno)); DPRINTF("mprotect of new metapage failed with %s", strerror(errno));
abort(); abort();
@ -2527,6 +2547,9 @@ bt_state_open(BT_state *state, const char *path, ULONG flags, mode_t mode)
if (!dpath) return ENOMEM; if (!dpath) return ENOMEM;
sprintf(dpath, "%s" DATANAME, path); sprintf(dpath, "%s" DATANAME, path);
if (mkdir(path, 0774) == -1)
return errno;
if ((state->data_fd = open(dpath, oflags, mode)) == -1) if ((state->data_fd = open(dpath, oflags, mode)) == -1)
return errno; return errno;
@ -2596,7 +2619,7 @@ bt_malloc(BT_state *state, size_t pages)
addr2off(ret) + pages, addr2off(ret) + pages,
pgno); pgno);
DPRINTF("map %p to offset %lld bytes (%lld pages)\n", ret, P2BYTES(pgno), pgno); DPRINTF("map %p to offset 0x%zx bytes (0x%x pages)\n", ret, P2BYTES(pgno), pgno);
if (ret != if (ret !=
mmap(ret, mmap(ret,
P2BYTES(pages), P2BYTES(pages),
@ -2929,7 +2952,7 @@ int
bt_inbounds(BT_state *state, void *p) bt_inbounds(BT_state *state, void *p)
/* 1: if in the bounds of the PMA, 0 otherwise */ /* 1: if in the bounds of the PMA, 0 otherwise */
{ {
return p >= BT_MAPADDR return p >= (void *)BT_MAPADDR
&& p < (void *)((uintptr_t)BT_MAPADDR + BT_ADDRSIZE); && p < (void *)((uintptr_t)BT_MAPADDR + BT_ADDRSIZE);
} }