git: 9front

Download patch

ref: 24b7b54a0864c824e09a8ec59e51f438663040cb
parent: 5b0618bb1e41d07074c66072f48cf4fb1fb32f28
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Wed Nov 21 11:19:51 EST 2018

upas/fs: don't enter mailbox into hashtree when it is being freed

syncmbox() used to enter the mailbox into the hash tree to
update the qid.vers. this is wrong when we are doing the final
sync before freeing the mailbox as the hash reference has already
been removed by freemailbox().

also avoid adding hash entries for mails for the about to be
freed mailbox in cachehash().

--- a/sys/src/cmd/upas/fs/cache.c
+++ b/sys/src/cmd/upas/fs/cache.c
@@ -216,6 +216,9 @@
 void
 cachehash(Mailbox *mb, Message *m)
 {
+	assert(mb->refs >= 0);
+	if(mb->refs == 0)
+		return;
 	if(m->whole == m->whole->whole)
 		henter(PATH(mb->id, Qmbox), m->name,
 			(Qid){PATH(m->id, Qdir), 0, QTDIR}, m, mb);
--- a/sys/src/cmd/upas/fs/mbox.c
+++ b/sys/src/cmd/upas/fs/mbox.c
@@ -115,14 +115,15 @@
 	a = mb->root->subname - a;
 	assert(a >= 0);
 	if(n + d + y + a){
+		Hash *h;
+
 		iprint("deleted: %d; new %d; stale %d\n", d, n, y);
 		logmsg(nil, "deleted: %d; new %d; stale %d", d, n, y);
 		wridxfile(mb);
-	}
-	if(n + d + y + a){
+
 		mb->vers++;
-		henter(PATH(0, Qtop), mb->name,
-			(Qid){PATH(mb->id, Qmbox), mb->vers, QTDIR}, nil, mb);
+		if(mb->refs > 0 && (h = hlook(PATH(0, Qtop), mb->name)) != nil && h->mb == mb)
+			h->qid.vers = mb->vers;
 	}
 
 	mb->syncing = 0;
@@ -166,8 +167,8 @@
 	strcat(f1, ".imp");
 	rename(f0, f1, 0);
 
-	snprint(mb->path, sizeof mb->path, "%s", b);
 	hfree(PATH(0, Qtop), mb->name);
+	snprint(mb->path, sizeof mb->path, "%s", b);
 	p0 = strrchr(mb->path, '/') + 1;
 	if(p0 == (char*)1)
 		p0 = mb->path;
--