shithub: riscv

Download patch

ref: 70f700699ac06fb33267395c60f62b4fae3f4f15
parent: 5ef10e16427a4312f9a19a4710dbdbe32fb88963
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;