ref: 9bbd5644ef54b9384da88c208088639a11ec4275
parent: 7faf23b902bdc08a5aa221d01d537f6309b79d41
author: Noam Preil <noam@pixelhero.dev>
date: Sun Dec 24 21:41:06 EST 2023
cleanup
--- a/disk.c
+++ b/disk.c
@@ -3,10 +3,21 @@
#include <bio.h>
#include "neoventi.h"
+// Note: these should only be accessed via
VtArena *arenas = nil;
u32int numarenas = 0;
-VtISect
+struct {
+ u32int blocksize;
+ u32int buckets;
+ VtISect *sects;
+ int nsects;
+ u32int div;
+ u32int namap;
+ MapEntry *amap;
+} index;
+
+int
isectforbucket(u32int buck)
{
int r, l, m;
@@ -20,14 +31,16 @@
else
r = m - 1;
}
- return index.sects[l - 1];
+ return l-1;
}
static int
-bucketlookup(u8int *bucket, u16int nb, u8int *score, u16int *entry)
+bucketlookup(u8int *ibuf, u8int *score, u16int *entry)
{
+ u16int nb = U16GET(ibuf);
+ ibuf += 6;
for(*entry = 0; *entry <= nb; *entry += 1){
- if(memcmp(&bucket[*entry * IEntrySize], score, 20) == 0)
+ if(memcmp(&ibuf[*entry * IEntrySize], score, 20) == 0)
return 1;
}
return 0;
@@ -60,21 +73,19 @@
vtreadlookup(u8int *score, VtAddress *addr)
{
u8int *buf;
- u16int bentries;
u16int entry;
u64int aindex;
u64int bucket = U32GET(score) / index.div;
- VtISect sect = isectforbucket(bucket);
- bucket -= sect.start;
- buf = malloc(sect.blocksize);
+ VtISect *s_sect = &index.sects[isectforbucket(bucket)];
+ bucket -= s_sect->start;
+ buf = malloc(s_sect->blocksize);
if(buf == nil)
- sysfatal("OOM, blocksize: %d", sect.blocksize);
- if(pread(sect.fd, (char*)buf, sect.blocksize, sect.blockbase + (bucket << sect.blocklog)) != sect.blocksize)
+ sysfatal("OOM, blocksize: %d", s_sect->blocksize);
+ if(pread(s_sect->fd, (char*)buf, s_sect->blocksize, s_sect->blockbase + (bucket << s_sect->blocklog)) != s_sect->blocksize)
sysfatal("Failed to read bucket");
- bentries = U16GET(buf);
- if(sect.bucketmagic && U32GET(buf + 2) != sect.bucketmagic)
- sysfatal("index is corrupt: invalid bucket magic: sect %ux, buck %ux", sect.bucketmagic, U32GET(buf + 2));
- if(!bucketlookup(buf + 6, bentries, score, &entry))
+ if(s_sect->bucketmagic && U32GET(buf + 2) != s_sect->bucketmagic)
+ sysfatal("index is corrupt: invalid bucket magic: sect %ux, buck %ux", s_sect->bucketmagic, U32GET(buf + 2));
+ if(!bucketlookup(buf, score, &entry))
sysfatal("entry not found in bucket");
addr->offset = U64GET((buf + 6 + (entry * IEntrySize) + 26));
addr->size = U16GET((buf + 6 + (entry * IEntrySize) + 34));
@@ -273,20 +284,9 @@
}
static void
-initisectpart(char *path)
+loadisect(VtISect *sect, char *buf)
{
- u32int magic;
- char buf[HeadSize];
- u8int *p = (void*)buf;
-
- index.sects = realloc(index.sects, sizeof(VtISect) * (index.nsects + 1));
- VtISect *sect = &index.sects[index.nsects++];
-
- if((sect->fd = open(path, OREAD)) < 0)
- sysfatal("failed to open index section");
- if(pread(sect->fd, buf, HeadSize, PartBlank) != HeadSize)
- sysfatal("failed to read index section header");
- magic = U32GET(p);
+ u8int *p = (u8int*)buf;
sect->version = U32GET(p + 4);
memcpy(sect->name, buf + 8, NameSize);
memcpy(sect->index, buf + 8 + NameSize, NameSize);
@@ -298,20 +298,26 @@
sect->index[NameSize-1] = 0;
sect->name[NameSize-1] = 0;
sect->bucketmagic = 0;
- if(magic != ISectMagic)
- sysfatal("invalid / corrupt index section");
if(sect->version == 2)
sect->bucketmagic = U32GET(p + 28 + 2*NameSize);
- else if(sect->version != 1)
- sysfatal("unrecognized index section version %d; only 1 and 2 are supported", sect->version);
sect->buckmax = (sect->blocksize - IBucketSize) / IEntrySize;
sect->blocklog = u64log2(sect->blocksize);
+ sect->tabbase = (PartBlank + HeadSize + sect->blocksize - 1) & ~(sect->blocksize - 1);
+ sect->tabsize = sect->blockbase - sect->tabbase;
+}
+
+static void
+validateisect(VtISect *sect, u32int magic, char *path)
+{
+ if(magic != ISectMagic)
+ sysfatal("invalid / corrupt index section");
+ if(sect->version != 1 && sect->version != 2)
+ sysfatal("unrecognized index section version %d; only 1 and 2 are supported", sect->version);
if(sect->blocksize != (1 << sect->blocklog))
sysfatal("Illegal or corrupt index section");
- sect->tabbase = (PartBlank + HeadSize + sect->blocksize - 1) & ~(sect->blocksize - 1);
if(sect->tabbase >= sect->blockbase)
sysfatal("illegal or corrupt index section: config table overlaps bucket store");
- sect->tabsize = sect->blockbase - sect->tabbase;
+
if(sect->blockbase + (u64int)sect->blocks * sect->blocksize != partlen(sect->fd, path) & ~(u64int)(sect->blocksize - 1))
sysfatal("invalid or corrupt index section header: invalid blocks");
if(sect->stop - sect->start > sect->blocks)
@@ -318,6 +324,24 @@
sysfatal("invalid or corrupt index section: section overflows available space");
if(sect->stop < sect->start)
sysfatal("invalid or corrupt index section: impossible range");
+
+}
+
+static void
+initisectpart(char *path)
+{
+ char buf[HeadSize];
+
+ index.sects = realloc(index.sects, sizeof(VtISect) * (index.nsects + 1));
+ VtISect *sect = &index.sects[index.nsects++];
+
+ if((sect->fd = open(path, OREAD)) < 0)
+ sysfatal("failed to open index section");
+ if(pread(sect->fd, buf, HeadSize, PartBlank) != HeadSize)
+ sysfatal("failed to read index section header");
+
+ loadisect(sect, buf);
+ validateisect(sect, U32GET((u8int*)buf), path);
}
static void
--- a/main.c
+++ b/main.c
@@ -7,7 +7,6 @@
void
parseargs(int argc, char **argv)
{
- USED(argv);
if(argc != 1)
sysfatal("TODO: arg parsing");
}
--- a/neoventi.h
+++ b/neoventi.h
@@ -96,16 +96,6 @@
u64int start, stop;
} MapEntry;
-struct {
- u32int blocksize;
- u32int buckets;
- VtISect *sects;
- int nsects;
- u32int div;
- u32int namap;
- MapEntry *amap;
-} index;
-
enum
{
WhackStats = 8,
--- a/server.c
+++ b/server.c
@@ -99,7 +99,7 @@
case VtTsync:
vterr(conn, buf, "TODO: sync not supported yet");
default:
- vterr(conn, buf, "TODO safely hang up vtconns");
+ vterr(conn, buf, "TODO unimplemented request type %d", buf[2]);
}
return 0;
}
@@ -124,36 +124,44 @@
} ClientHandle;
static void
-handleproc(void *hnd)
+vtloop(VtConn conn, char *buf)
{
- ClientHandle *h = hnd;
- char buf[MaxPacketSize];
- VtConn conn;
- switch(setjmp(conn.bounce)){
+ while(1){
+ vtrecv(conn, buf);
+ vtconnhandle(conn, buf);
+ }
+}
+
+static int
+inittrampoline(ClientHandle *h, VtConn *conn)
+{
+ switch(setjmp(conn->bounce)){
case 0:
- break;
+ return 1;
case 1:
fprint(2, "abandoning client: %r\n");
case 2:
- close(conn.fd);
+ close(conn->fd);
free(h);
- return;
+ return 0;
default:
fprint(2, "internal error: unexpected bounce code\n");
- break;
+ return 0;
}
- conn.fd = accept(h->ctl, h->dir);
- if(conn.fd < 0)
+}
+
+static void
+handleproc(void *hnd)
+{
+ char buf[MaxPacketSize];
+ ClientHandle *h = hnd;
+ VtConn conn;
+ if(!inittrampoline(h, &conn))
+ return;
+ if((conn.fd = accept(h->ctl, h->dir)) < 0)
vterr(conn, nil, "failed to accept connection: %r");
vthello(conn, buf);
- while(1){
- vtrecv(conn, buf);
- if(!vtconnhandle(conn, buf)){
- close(conn.fd);
- return;
- }
- }
-
+ vtloop(conn, buf);
}
static void
--
⑨