code: mafs

Download patch

ref: 2473bd0e87137da5a04c269beb06c2162839390d
parent: d51673903684ef948787a209a7e48acf92e6a745
author: 9ferno <gophone2015@gmail.com>
date: Fri Dec 2 12:37:22 EST 2022

fixed bug in managing frees on a failed restart

We do not clear the frees until the restart is successful.
Earlier, we werer clearing the frees as soon as we loaded them
without waiting to check if the restart was successful or not.

--- a/9p.c
+++ b/9p.c
@@ -1017,7 +1017,7 @@
 		}
 	}
 */
-	savefrees(Bdfrees);
+	savefrees();
 /*	if(synchronouswrites == 0){
 		while((n=pendingwrites())>0){
 			if(chatty9p > 1)
--- a/all.h
+++ b/all.h
@@ -148,13 +148,14 @@
 
 /* dentry routines */
 u64 	addrelative(Dentry *d, u64 dblkno, u64 reli, u64 blkno);
+void	clearfrees(void);
 void	freeaux(Aux *a);
 Iobuf*	getdatablkat(Dentry *d, u64 reli);
-void	loadfrees(u64 dblkno);
+void	loadfrees(void);
 Aux*	newaux(u64 addr, u16 uid);
 s32		readfile(u64 dblkno, u64 qpath, char *rbuf, s32 rbufsize, u64 offset);
 s32		readfilesize(u64 dblkno, u64 qpath);
-void	savefrees(u64 dblkno);
+void	savefrees(void);
 void	truncatefile(u64 qpath, u64 dblkno, s16 uid);
 s32		writeallappend(Iobuf *dbuf, Dentry *d, u64 dblkno);
 s32		writefile(u64 dblkno, u64 qpath, s16 uid, char *wbuf, s32 wbufsize, u64 offset);
--- a/dentry.c
+++ b/dentry.c
@@ -575,7 +575,7 @@
 /* the frees list of free blocks will include the blocks
 	used to store the frees */
 void
-savefrees(u64 dblkno)
+savefrees(void)
 {
 	s32 nbuf;
 	s8 *buf;
@@ -583,7 +583,7 @@
 
 	/* should not be necessary as we clear out the file
 		in loadfrees() */
-	truncatefile(Qpfrees, dblkno, -1);
+	clearfrees();
 
 	/* will not be accurate as we are allocating blocks below.
 		But, will be more than what we will actually end up using.
@@ -596,53 +596,54 @@
 		panic("savefrees nbuf not enough");
 
 	/* writing the actual extents now */
-	writefile(dblkno, Qpfrees, -1, buf, nbuf, 0);
+	writefile(Bdfrees, Qpfrees, -1, buf, nbuf, 0);
 	free(buf);
 
 	/* flush to the disk if append has stuff */
-	dbuf = getmetachk(dblkno, Bwritable, Tdentry, Qpfrees);
+	dbuf = getmetachk(Bdfrees, Bwritable, Tdentry, Qpfrees);
 	if(dbuf == nil)
 		return;
 	if(dbuf->append != nil)
-		writeallappend(dbuf, dbuf->new, dblkno);
+		writeallappend(dbuf, dbuf->new, Bdfrees);
 	putbuf(dbuf, 1);
 }
 
 void
-loadfrees(u64 dblkno)
+loadfrees(void)
 {
 	u64 size, n;
 	s8 *buf;
-	Iobuf *dbuf;
-	Dentry *d;
-	int i;
 
-	size = readfilesize(dblkno, Qpfrees);
+	size = readfilesize(Bdfrees, Qpfrees);
 	if(size == 0)
 		panic("loadfrees size == 0");
 	buf = emalloc(size);
 	if(buf == nil)
 		panic("loadfrees: nil emalloc of %llud bytes", size);
-	if(readfile(dblkno, Qpfrees, buf, size, 0) != size)
+	if(readfile(Bdfrees, Qpfrees, buf, size, 0) != size)
 		panic("loadfrees: could not load frees");
 	n = loadextents(&frees, buf, size);
 	if(chatty9p > 2)
 	dprint("loadfrees: loaded free extents %llud\n", n);
 	free(buf);
+}
 
-	/* clear out /adm/frees data contents */
-	/* I cannot use truncatefile() below as it would
-		bfree() the blocks (which are already in the Extents frees)
-		and that would cause an inconsistency/panic */
-	dbuf = getmetachk(dblkno, Bwritable, Tdentry, Qpfrees);
+/* clear out /adm/frees data contents after starting up
+	I cannot use truncatefile() below as it would
+	bfree() the blocks (which are already in the Extents frees)
+	and that would cause an inconsistency/panic */
+void
+clearfrees(void)
+{
+	Iobuf *dbuf;
+	Dentry *d;
+
+	dbuf = getmetachk(Bdfrees, Bwritable, Tdentry, Qpfrees);
 	if(dbuf == nil)
 			dprint("%s",errstring[Ephase]);
 	d = (Dentry*)dbuf->new;
 	d->size = 0;
-	for(i=0; i<Ndblock; i++)
-		d->dblocks[i] = 0;
-	for(i=0;i<Niblock; i++)
-		d->iblocks[i] = 0;
+	memset(d->buf, 0, Ddatasize);
 	d->mtime = nsec();
 	d->muid = -1;
 	putbuf(dbuf, 1);
--- a/sub.c
+++ b/sub.c
@@ -80,7 +80,7 @@
 	Iobuf *buf;
 
 	if(len > Maxdatablockunits)
-		panic("allocblocks(): invalid len %ud tag %s qpath %llud\n",
+		panic("allocblocks(): invalid len %llud tag %s qpath %llud\n",
 				len, tagnames[tag], qpath);
 	blkno = balloc(&frees, len);
 	if(chatty9p > 1)
@@ -372,9 +372,7 @@
 {
 	Iobuf *sbuf;
 	Dentry *s;
-	u64 nbused;
 
-	nbused = Nbused;
 	sbuf = getbuf(Bdsuper, Metadataunits, Bwritable, Bfreshalloc);
 	if(sbuf == nil)
 		panic("superream: sbuf == nil");
@@ -430,14 +428,14 @@
 
 	reamdefaults(config.config.dest[0], config.super.dest[0], config.root.dest[0]);
 
-	if(config.root.dest[0]-nbused > 0)
-		bfree(&frees, nbused, config.root.dest[0]-nbused);
-	else if (config.root.dest[0] == nbused)
-		dprint("mafs: %s no free blocks: config.root.dest[0] %llud nbused %llud Nminblocks %llud\n",
-				service, config.root.dest[0], nbused, Nminblocks);
+	if(config.root.dest[0]-Nbused > 0)
+		bfree(&frees, Nbused, config.root.dest[0]-Nbused);
+	else if (config.root.dest[0] == Nbused)
+		dprint("mafs: %s no free blocks: config.root.dest[0] %llud Nbused %ud Nminblocks %llud\n",
+				service, config.root.dest[0], Nbused, Nminblocks);
 	else
-		panic("not enough blocks for mafs config.root.dest[0] %llud nbused %llud Nminblocks %d\n",
-				config.root.dest[0], nbused, Nminblocks);
+		panic("not enough blocks for mafs config.root.dest[0] %llud Nbused %ud Nminblocks %d\n",
+				config.root.dest[0], Nbused, Nminblocks);
 	if(chatty9p > 1)
 		showextents(2, "free extents: ", &frees);
 	if(chatty9p > 1)
@@ -497,7 +495,7 @@
 		ream(size);
 	else{
 		initconfig(Bdconfig);
-		loadfrees(Bdfrees);
+		loadfrees();
 	}
 
 	/* check magic */
@@ -525,12 +523,17 @@
 		return;
 	}
 	s = (Dentry*)sb->new;
-	if(s->fsok != 1 || config.size != size)
+	if(s->fsok != 1 || config.size != size){
+		dprint("s->fsok %d config.size %llud size %llud\n",
+				s->fsok, config.size, size);
 		panic(errstring[Edirty]);
+	}
 
 	s->fsok = 0;
 	putbuf(sb, 1);
 	shuttingdown = 0;
+	if(doream == 0)
+		clearfrees();
 	usersinit();
 }