shithub: gefs

Download patch

ref: 729a62cf4172100f394553f2c4d69f77148c8ce5
parent: 8fad4df88ae048a8317f1633cdc47fbaf17d896b
author: Ori Bernstein <[email protected]>
date: Fri Oct 13 13:44:20 EDT 2023

fs: clearb needs epoch cleans around its operations

clearb can generate an unbounded amount of data to go into
the limbo list, which means that we need to clean it up
as we go; luckily, we don't access cross-epoch within the
places that call clearb, so we can pause the epoch and
clean up the limbo list there.

--- a/fs.c
+++ b/fs.c
@@ -280,7 +280,7 @@
  * the range listed.
  */
 static char*
-clearb(Mount *mnt, vlong qid, vlong off, vlong len)
+clearb(int id, Mount *mnt, vlong qid, vlong off, vlong len)
 {
 	char *e, buf[Offksz];
 	Msg m;
@@ -295,6 +295,9 @@
 		PACK64(m.k+9, off);
 		m.v = nil;
 		m.nv = 0;
+		epochend(id);
+		epochclean();
+		epochstart(id);
 		if((e = upsert(mnt, &m, 1)) != nil)
 			return e;
 	}
@@ -1597,7 +1600,7 @@
 }
 
 static void
-fsremove(Fmsg *m)
+fsremove(Fmsg *m, int id)
 {
 	char upbuf[Upksz];
 	Fcall r;
@@ -1636,7 +1639,7 @@
 	if((e = upsert(f->mnt, mb, 1)) != nil)
 		goto Error;
 	if(f->dent->qid.type == QTFILE){
-		e = clearb(f->mnt, f->qpath, 0, f->dent->length);
+		e = clearb(id, f->mnt, f->qpath, 0, f->dent->length);
 		if(e != nil)
 			goto Error;
 	}
@@ -1655,7 +1658,7 @@
 }
 
 static void
-fsopen(Fmsg *m)
+fsopen(Fmsg *m, int id)
 {
 	char *p, *e, buf[Kvmax];
 	int mbits;
@@ -1735,7 +1738,7 @@
 		mb.nk = f->dent->nk;
 		mb.v = buf;
 		mb.nv = p - buf;
-		clearb(f->mnt, f->qpath, 0, f->dent->length);
+		clearb(id, f->mnt, f->qpath, 0, f->dent->length);
 		if((e = upsert(f->mnt, &mb, 1)) != nil){
 			wunlock(f->dent);
 			rerror(m, e);
@@ -2070,7 +2073,7 @@
 }
 
 void
-runfs(int wid, void *pc)
+runfs(int id, void *pc)
 {
 	char err[128];
 	RWLock *lk;
@@ -2111,7 +2114,7 @@
 		}
 
 		h = ihash(m->fid) % fs->nreaders;
-		epochstart(wid);
+		epochstart(id);
 		switch(m->type){
 		/* sync setup */
 		case Tversion:	fsversion(m);	break;
@@ -2136,7 +2139,6 @@
 			if((m->mode & OTRUNC) || (m->mode & 0xf) == OEXEC)
 				chsend(fs->wrchan, m);
 			else
-
 				chsend(fs->rdchan[h], m);
 			break;
 
@@ -2148,12 +2150,12 @@
 			respond(m, &r);
 			break;
 		}
-		epochend(wid);
+		epochend(id);
 	}
 }
 
 void
-runwrite(int wid, void *)
+runwrite(int id, void *)
 {
 	Mount *mnt;
 	Fmsg *m;
@@ -2161,7 +2163,7 @@
 
 	while(1){
 		m = chrecv(fs->wrchan);
-		epochstart(wid);
+		epochstart(id);
 		ao = (m->a == nil) ? AOnone : m->a->op;
 		switch(ao){
 		case AOnone:
@@ -2177,8 +2179,8 @@
 			case Tcreate:	fscreate(m);	break;
 			case Twrite:	fswrite(m);	break;
 			case Twstat:	fswstat(m);	break;
-			case Tremove:	fsremove(m);	break;
-			case Topen:	fsopen(m);	break;
+			case Tremove:	fsremove(m,id);	break;
+			case Topen:	fsopen(m, id);	break;
 			}
 			break;
 		case AOsync:
@@ -2194,32 +2196,32 @@
 			freemsg(m);
 			break;
 		}
-		epochend(wid);
+		epochend(id);
 		epochclean();
 	}
 }
 
 void
-runread(int wid, void *ch)
+runread(int id, void *ch)
 {
 	Fmsg *m;
 
 	while(1){
 		m = chrecv(ch);
-		epochstart(wid);
+		epochstart(id);
 		switch(m->type){
 		case Tattach:	fsattach(m);	break;
 		case Twalk:	fswalk(m);	break;
 		case Tread:	fsread(m);	break;
 		case Tstat:	fsstat(m);	break;
-		case Topen:	fsopen(m);	break;
+		case Topen:	fsopen(m, id);	break;
 		}
-		epochend(wid);
+		epochend(id);
 	}
 }
 
 void
-runtasks(int wid, void *)
+runtasks(int id, void *)
 {
 	int i, c;
 	Fmsg *m;
@@ -2252,7 +2254,7 @@
 		 */
 		qlock(&fs->synclk);
 		for(i = 0; i < fs->narena; i++){
-			epochstart(wid);
+			epochstart(id);
 			lock(&fs->arenas[i]);
 			c = fs->arenas[i].nlog > fs->arenas[i].reserve/(4*Blksz);
 			unlock(&fs->arenas[i]);
@@ -2260,7 +2262,7 @@
 				if(compresslog(&fs->arenas[i]) == -1)
 					fprint(2, "compress log: %r");
 			}
-			epochend(wid);
+			epochend(id);
 		}
 		qunlock(&fs->synclk);
 	}