shithub: gefs

Download patch

ref: 4a29d3fe0aada31421c2c48f167049ab373a96bf
parent: 6b3bff3c893fa5ffab171cf8010a23512926e196
author: Ori Bernstein <ori@eigenstate.org>
date: Tue Jan 11 01:08:39 EST 2022

fs: fix truncation.

--- a/blk.c
+++ b/blk.c
@@ -151,6 +151,7 @@
 		return -1;
 	r->off = off;
 	r->len = len;
+	assert(avllookup(t, r, 0) == nil);
 	avlinsert(t, r);
 
 Again:
@@ -231,6 +232,7 @@
 	Blk *pb, *lb;
 	vlong o;
 	char *p;
+	int r;
 
 	assert(off % Blksz == 0);
 	assert(op == LogAlloc || op == LogFree || op == LogDead);
@@ -245,21 +247,24 @@
 			return -1;
 		if((lb = initblk(o, Tlog)) == nil)
 			return -1;
+		cacheblk(lb);
 		lb->logsz = Loghdsz;
 		p = lb->data + lb->logsz;
 		PBIT64(p, (uvlong)LogEnd);
 		finalize(lb);
 		if(syncblk(lb) == -1){
-			free(lb);
+			putblk(lb);
 			return -1;
 		}
-
 		ol->tail = lb;
+
 		if(pb != nil){
 			p = pb->data + pb->logsz;
 			PBIT64(p + 0, lb->bp.addr|LogChain);
 			finalize(pb);
-			if(syncblk(pb) == -1)
+			r = syncblk(pb);
+			putblk(pb);
+			if(r == -1)
 				return -1;
 		}
 	}
@@ -711,6 +716,7 @@
 	if((b = lookupblk(bp)) == nil){
 		if((b = mallocz(sizeof(Blk), 1)) == nil)
 			return nil;
+		setmalloctag(b, getcallerpc(&bp));
 		/*
 		 * If the block is cached,
 		 * then the cache holds a ref
@@ -835,7 +841,8 @@
 	if((b = readblk(bp.addr, flg)) == nil){
 		qunlock(&fs->blklk);
 		return nil;
-	}
+	}else
+		setmalloctag(b, getcallerpc(&bp));
 	h = blkhash(b);
 	if((flg&GBnochk) == 0 && h != bp.hash){
 		fprint(2, "corrupt block %B: %llx != %llx\n", bp, blkhash(b), bp.hash);
--- a/fs.c
+++ b/fs.c
@@ -1069,6 +1069,10 @@
 		rerror(m, Enomem);
 		putfid(f);
 		return;
+	}else{
+		wlock(de);
+		de->length = 0;
+		wunlock(de);
 	}
 
 	lock(f);
@@ -1182,14 +1186,15 @@
 void
 fsopen(Fmsg *m)
 {
-	char *e, buf[Kvmax];
+	char *p, *e, buf[Kvmax];
+	int mbits;
 	Fcall r;
 	Xdir d;
 	Fid *f;
 	Kvp kv;
-	int mb;
+	Msg mb;
 
-	mb = mode2bits(m->mode);
+	mbits = mode2bits(m->mode);
 	if((f = getfid(m->fid)) == nil){
 		rerror(m, Efid);
 		return;
@@ -1204,7 +1209,7 @@
 		putfid(f);
 		return;
 	}
-	if(fsaccess(f->mnt, d.mode, d.uid, d.gid, mb) == -1){
+	if(fsaccess(f->mnt, d.mode, d.uid, d.gid, mbits) == -1){
 		rerror(m, Eperm);
 		putfid(f);
 		return;
@@ -1224,16 +1229,33 @@
 		return;
 	}
 	f->mode = mode2bits(m->mode);
-//	if((f->mode & DMEXEC)){
+//	if(!fs->rdonly && (m->mode == OEXEC)){
 //		lock(&fs->root.lk);
 //		f->root = fs->root;
 //		refblk(fs->root.bp);
 //		unlock(&fs->root.lk);
 //	}
-	if(f->mode & OTRUNC){
+	if(m->mode & OTRUNC){
 		wlock(f->dent);
-		clearb(f, 0, f->dent->length);
+		f->dent->muid = f->mnt->uid;
+		f->dent->qid.vers++;
 		f->dent->length = 0;
+
+		mb.op = Owstat;
+		p = buf;
+		p[0] = Owsize|Owmuid;	p += 1;
+		PBIT64(p, 0);		p += 8;
+		PBIT32(p, f->mnt->uid);	p += 4;
+		mb.k = f->dent->k;
+		mb.nk = f->dent->nk;
+		mb.v = buf;
+		mb.nv = p - buf;
+		clearb(f, 0, f->dent->length);
+		if((e = btupsert(f->mnt->root, &mb, 1)) != nil){
+			wunlock(f->dent);
+			rerror(m, e);
+			return;
+		}
 		wunlock(f->dent);
 	}
 	unlock(f);
@@ -1251,6 +1273,8 @@
 	s = f->scan;
 	if(s != nil && s->offset != 0 && s->offset != m->offset)
 		return Edscan;
+	if((r->data = malloc(m->count)) == nil)
+		return Enomem;
 	if(s == nil || m->offset == 0){
 		if((s = mallocz(sizeof(Scan), 1)) == nil)
 			return Enomem;
@@ -1258,7 +1282,6 @@
 		pfx[0] = Kent;
 		PBIT64(pfx+1, f->qpath);
 		if((e = btscan(f->mnt->root, s, pfx, sizeof(pfx))) != nil){
-			free(r->data);
 			btdone(s);
 			return e;
 		}
@@ -1305,8 +1328,6 @@
 	char *p;
 	Dent *e;
 
-	r->type = Rread;
-	r->count = 0;
 	e = f->dent;
 	rlock(e);
 	if(m->offset > e->length){
@@ -1313,10 +1334,6 @@
 		runlock(e);
 		return nil;
 	}
-	if((r->data = malloc(m->count)) == nil){
-		runlock(e);
-		return Enomem;
-	}
 	p = r->data;
 	c = m->count;
 	o = m->offset;
@@ -1362,12 +1379,10 @@
 		e = fsreaddir(m, f, &r);
 	else
 		e = fsreadfile(m, f, &r);
-	if(e != nil){
+	if(e != nil)
 		rerror(m, e);
-		putfid(f);
-		return;
-	}
-	respond(m, &r);
+	else
+		respond(m, &r);
 	free(r.data);
 	putfid(f);
 }
@@ -1484,7 +1499,6 @@
 		case Tversion:	fsversion(m, &msgmax);	break;
 		case Tauth:	fsauth(m);		break;
 		case Tclunk:	fsclunk(m);		break;
-		case Topen:	fsopen(m);		break;
 		case Tattach:	fsattach(m, msgmax);	break;
 
 		/* mutators */
@@ -1498,6 +1512,16 @@
 		case Twalk:	chsend(fs->rdchan, m);	break;
 		case Tread:	chsend(fs->rdchan, m);	break;
 		case Tstat:	chsend(fs->rdchan, m);	break;
+
+		/* both */
+		case Topen:
+			if(m->mode & OTRUNC)
+				chsend(fs->wrchan, m);
+			else
+
+				chsend(fs->rdchan, m);
+			break;
+
 		default:
 			fprint(2, "unknown message %F\n", &m->Fcall);
 			snprint(err, sizeof(err), "unknown message: %F", &m->Fcall);
@@ -1536,6 +1560,7 @@
 			case Twrite:	fswrite(m);	break;
 			case Twstat:	fswstat(m);	break;
 			case Tremove:	fsremove(m);	break;
+			case Topen:	fsopen(m);	break;
 			}
 			break;
 		case AOsync:
@@ -1570,6 +1595,7 @@
 		case Twalk:	fswalk(m);	break;
 		case Tread:	fsread(m);	break;
 		case Tstat:	fsstat(m);	break;
+		case Topen:	fsopen(m);	break;
 		}
 		quiesce(wid);
 	}
--- a/load.c
+++ b/load.c
@@ -90,10 +90,11 @@
 	}
 	fprint(2, "load: %8s\n", p);
 	fprint(2, "\tsnaptree:\t%B\n", fs->snap.bp);
-	fprint(2, "\tarenas:\t%d\n", fs->narena);
+	fprint(2, "\tnarenas:\t%d\n", fs->narena);
 	fprint(2, "\tarenasz:\t%lld\n", fs->arenasz);
 	fprint(2, "\tnextqid:\t%lld\n", fs->nextqid);
 	fprint(2, "\tnextgen:\t%lld\n", fs->nextgen);
+	fprint(2, "\tcachesz:\t%lld MiB\n", fs->cmax*Blksz/MiB);
 	if((fs->arenas = calloc(fs->narena, sizeof(Arena))) == nil)
 		sysfatal("malloc: %r");
 	for(i = 0; i < fs->narena; i++)