shithub: gefs

Download patch

ref: 3e2d8934b70a0622a2bca53e281dbe811a3fed03
parent: a9fd1bd8bb277a68f9995132db70b6ef0bb09431
author: Ori Bernstein <ori@eigenstate.org>
date: Tue Apr 25 19:58:49 EDT 2023

blk: defer frees/reclaims until after syncing

--- a/blk.c
+++ b/blk.c
@@ -17,7 +17,6 @@
 static vlong	blkalloc(int, uint);
 static int	blkdealloc_lk(vlong);
 static Blk*	initblk(Blk*, vlong, vlong, int);
-static int	logop(Arena *, vlong, vlong, int);
 
 int
 checkflag(Blk *b, int f)
@@ -290,7 +289,7 @@
 	assert(off % Blksz == 0);
 	assert(op == LogAlloc || op == LogFree);
 	assert(lb == nil || lb->type == Tlog);
-	dprint("logop %llx+%llx@%x: %s\n", off, len, lb->logsz, (op == LogAlloc) ? "Alloc" : "Free");
+	dprint("logop %llx+%llx@%x: %s\n", off, len, lb?lb->logsz:-1, (op == LogAlloc) ? "Alloc" : "Free");
 	/*
 	 * move to the next block when we have
 	 * 40 bytes in the log:
@@ -343,28 +342,16 @@
 
 }
 
-static int
-logop(Arena *a, vlong off, vlong len, int op)
-{
-	if(logappend(a, off, len, op, &a->tail) == -1)
-		return -1;
-	if(a->head.addr == -1)
-		a->head = a->tail->bp;
-	return 0;
-}
-
 int
-loadlog(Arena *a)
+loadlog(Arena *a, Bptr bp)
 {
 	vlong ent, off, len;
 	int op, i, n;
 	uvlong bh;
-	Bptr bp;
 	char *d;
 	Blk *b;
 
 
-	bp = a->head;
 Nextblk:
 	if((b = getblk(bp, GBnochk)) == nil)
 		return -1;
@@ -457,14 +444,14 @@
 	}
 
 	graft = b->bp.addr;
-	if(a->tail != nil){
-		finalize(a->tail);
-		if(syncblk(a->tail) == -1){
+	if(a->logtl != nil){
+		finalize(a->logtl);
+		if(syncblk(a->logtl) == -1){
 			dropblk(b);
 			return -1;
 		}
 	}
-	a->tail = b;
+	a->logtl = b;
 
 	/*
 	 * Prepare what we're writing back.
@@ -537,10 +524,10 @@
 		return -1;
 
 	lock(a);
-	oldhd = a->head.addr;
-	a->head.addr = hd->bp.addr;
-	a->head.hash = hd->bp.hash;
-	a->head.gen = -1;
+	oldhd = a->loghd.addr;
+	a->loghd.addr = hd->bp.addr;
+	a->loghd.hash = hd->bp.hash;
+	a->loghd.gen = -1;
 	rv = syncarena(a);
 	unlock(a);
 	if(rv == -1)
@@ -579,8 +566,8 @@
 	lock(a);
 	a->nlog = 0;
 	unlock(a);
-	finalize(a->tail);
-	if(syncblk(a->tail) == -1)
+	finalize(a->logtl);
+	if(syncblk(a->logtl) == -1)
 		return -1;
 	return 0;
 }
@@ -633,8 +620,10 @@
 
 	r = -1;
 	a = getarena(b);
-	if(logop(a, b, Blksz, LogFree) == -1)
-		goto out;
+	if(logappend(a, b, Blksz, LogFree, &a->logtl) == -1)
+		return -1;
+	if(a->loghd.addr == -1)
+		a->loghd = a->logtl->bp;
 	if(freerange(a->free, b, Blksz) == -1)
 		goto out;
 	a->used -= Blksz;
@@ -643,6 +632,24 @@
 	return r;
 }
 
+int
+blkrelease(vlong b)
+{
+	Arena *a;
+	int r;
+
+	a = getarena(b);
+	lock(a);
+	r = -1;
+	a = getarena(b);
+	if(logappend(a, b, Blksz, LogFree, &a->defertl) == -1)
+		return -1;
+	if(a->loghd.addr == -1)
+		a->loghd = a->logtl->bp;
+	unlock(a);
+	return r;
+}
+
 static vlong
 blkalloc(int ty, uint hint)
 {
@@ -675,27 +682,16 @@
 		unlock(a);
 		goto Again;
 	}
-	if(logop(a, b, Blksz, LogAlloc) == -1){
+	if(logappend(a, b, Blksz, LogAlloc, &a->logtl) == -1){
 		unlock(a);
 		return -1;
 	}
+	if(a->loghd.addr == -1)
+		a->loghd = a->logtl->bp;
 	unlock(a);
 	return b;
 }
 
-int
-blkdealloc(vlong b)
-{
-	Arena *a;
-	int r;
-
-	a = getarena(b);
-	lock(a);
-	r = blkdealloc_lk(b);
-	unlock(a);
-	return r;
-}
-
 static Blk*
 initblk(Blk *b, vlong bp, vlong gen, int ty)
 {
@@ -963,7 +959,6 @@
 {
 	ulong e, ge;
 	Bfree *p, *n;
-	Arena *a;
 	int i;
 
 	ge = agetl(&fs->epoch);
@@ -981,15 +976,10 @@
 
 	while(p != nil){
 		n = p->next;
-		a = getarena(p->bp.addr);
-
-		lock(a);
 		cachedel(p->bp.addr);
-		blkdealloc_lk(p->bp.addr);
+		blkrelease(p->bp.addr);
 		if(p->b != nil)
 			dropblk(p->b);
-		unlock(a);
-
 		free(p);
 		p = n;
 	}
@@ -1132,8 +1122,17 @@
 		rsleep(&fs->syncrz);
 	for(i = 0; i < fs->narena; i++){
 		a = &fs->arenas[i];
-		finalize(a->tail);
-		if(syncblk(a->tail) == -1)
+
+		if(a->deferhd.addr != -1){
+			chainlog(a->logtl, a->deferhd.addr);
+			loadlog(a, a->deferhd);
+			a->logtl = a->defertl;
+			a->deferhd = (Bptr){-1, -1, -1};
+			a->defertl = nil;
+		}
+
+		finalize(a->logtl);
+		if(syncblk(a->logtl) == -1)
 			sysfatal("sync arena: %r");
 		if(syncarena(a) == -1)
 			sysfatal("sync arena: %r");
--- a/dat.h
+++ b/dat.h
@@ -509,16 +509,18 @@
 	Avltree *free;
 	Blk	**queue;
 	int	nqueue;
-	Blk	*b;	/* arena block */
-	Blk	**q;	/* write queue */
+	Blk	*b;			/* arena block */
+	Blk	**q;			/* write queue */
 	vlong	nq;
 	vlong	size;
 	vlong	used;
 	vlong	reserve;
 	/* allocation log */
-	vlong	nlog;	/* number of blocks logged since last compression */
-	Bptr	head;	/* start of allocation log */
-	Blk	*tail;	/* end of the log, open for writing */
+	vlong	nlog;		/* logged since last copression */
+	Bptr	loghd;		/* allocation log */
+	Blk	*logtl;		/* end of the log, open for writing */
+	Bptr	deferhd;	/* allocation log */
+	Blk	*defertl;	/* end of the log, open for writing */
 	Syncq	*sync;
 };
 
--- a/fns.h
+++ b/fns.h
@@ -54,8 +54,9 @@
 void	freesync(void);
 void	freeblk(Tree*, Blk*);
 void	freebp(Tree*, Bptr);
+int	dlappend(Dlist *dl, Bptr);
 int	killblk(Tree*, Bptr);
-int	blkdealloc(vlong);
+int	blkrelease(vlong);
 ushort	blkfill(Blk*);
 uvlong	blkhash(Blk*);
 uvlong	bufhash(void*, usize);
@@ -73,7 +74,7 @@
 int	loadarena(Arena*, Fshdr *fi, vlong);
 void	loadfs(char*);
 void	sync(void);
-int	loadlog(Arena*);
+int	loadlog(Arena*, Bptr);
 int	scandead(Dlist*, int, void(*)(Bptr, void*), void*);
 int	endfs(void);
 int	compresslog(Arena*);
--- a/load.c
+++ b/load.c
@@ -91,7 +91,7 @@
 	}
 	for(i = 0; i < fs->narena; i++){
 		a = &fs->arenas[i];
-		if(loadlog(a) == -1)
+		if(loadlog(a, a->loghd) == -1)
 			sysfatal("load log: %r");
 		if(compresslog(a) == -1)
 			sysfatal("compress log: %r");
--- a/pack.c
+++ b/pack.c
@@ -532,8 +532,8 @@
 	PACK64(p, fi->arenasz);		p += 8;
 	PACK64(p, fi->nextqid);		p += 8;
 	PACK64(p, fi->nextgen);		p += 8;
-	PACK64(p, a->head.addr);	p += 8;	/* freelist addr */
-	PACK64(p, a->head.hash);	p += 8;	/* freelist hash */
+	PACK64(p, a->loghd.addr);	p += 8;	/* freelist addr */
+	PACK64(p, a->loghd.hash);	p += 8;	/* freelist hash */
 	PACK64(p, a->size);		p += 8;	/* arena size */
 	PACK64(p, a->used);		p += 8;	/* arena used */
 	return p;
@@ -560,11 +560,16 @@
 	fi->arenasz = UNPACK64(p);	p += 8;
 	fi->nextqid = UNPACK64(p);	p += 8;
 	fi->nextgen = UNPACK64(p);	p += 8;
-	a->head.addr = UNPACK64(p);	p += 8;
-	a->head.hash = UNPACK64(p);	p += 8;
-	a->head.gen = -1;		p += 0;
+	a->loghd.addr = UNPACK64(p);	p += 8;
+	a->loghd.hash = UNPACK64(p);	p += 8;
+	a->loghd.gen = -1;		p += 0;
 	a->size = UNPACK64(p);		p += 8;
 	a->used = UNPACK64(p);		p += 8;
-	a->tail = nil;
+	a->logtl = nil;
+
+	a->deferhd.addr = -1;
+	a->deferhd.hash = -1;
+	a->deferhd.gen = -1;
+	a->defertl = nil;
 	return p;
 }
--- a/ream.c
+++ b/ream.c
@@ -165,11 +165,11 @@
 	Blk *b;
 
 	b = cachepluck();
-	addr = start+Blksz;	/* arena header */
+	addr = start+Blksz;	/* arena loghder */
 
-	a->head.addr = -1;
-	a->head.hash = -1;
-	a->head.gen = -1;
+	a->loghd.addr = -1;
+	a->loghd.hash = -1;
+	a->loghd.gen = -1;
 
 	memset(b->buf, 0, sizeof(b->buf));
 	b->type = Tlog;
@@ -197,12 +197,12 @@
 	b->type = Tarena;
 	b->bp.addr = start;
 	b->data = b->buf;
-	a->head.addr = bo;
-	a->head.hash = bh;
-	a->head.gen = -1;
+	a->loghd.addr = bo;
+	a->loghd.hash = bh;
+	a->loghd.gen = -1;
 	a->size = asz;
 	a->used = Blksz;
-	a->tail = nil;
+	a->logtl = nil;
 	packarena(b->data, Blksz, a, fi);
 	finalize(b);
 	if(syncblk(b) == -1)
@@ -260,7 +260,7 @@
 		a = &fs->arenas[i];
 		if((loadarena(a, fs, i*asz)) == -1)
 			sysfatal("ream: loadarena: %r");
-		if(loadlog(a) == -1)
+		if(loadlog(a, a->loghd) == -1)
 			sysfatal("load log: %r");
 		if(compresslog(a) == -1)
 			sysfatal("compress log: %r");
@@ -321,8 +321,8 @@
 
 	for(i = 0; i < fs->narena; i++){
 		a = &fs->arenas[i];
-		finalize(a->tail);
-		if(syncblk(a->tail) == -1)
+		finalize(a->logtl);
+		if(syncblk(a->logtl) == -1)
 			sysfatal("sync arena: %r");
 		packarena(a->b->data, Blksz, a, fs);
 		finalize(a->b);
--- a/snap.c
+++ b/snap.c
@@ -154,7 +154,7 @@
 			return Efs;
 		if(docontents){
 			for(p = b->data; p != b->data+b->deadsz; p += 8){
-				if(blkdealloc(UNPACK64(p)) == -1){
+				if(blkrelease(UNPACK64(p)) == -1){
 					dropblk(b);
 					return Efs;
 				}