git: 9front

Download patch

ref: 2f715651e67a40beb8e71f09c96973998ba99745
parent: ecb73058833bc3640ffffbf36ab6c3f2d312ea5f
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Jul 5 17:15:55 EDT 2020

upas/fs: wait until the index becomes unlocked

For big mailboxes with imap4d, ignoring the index and trying to scan
the mailbox concurrently is not very productive. Just wait for the
other upas/fs to write the whole index.

The issue is that imap might time out and make another connection
spawning even more upas/fs instances that all then try to rebuild
the index concurrently.

--- a/sys/src/cmd/upas/fs/idx.c
+++ b/sys/src/cmd/upas/fs/idx.c
@@ -123,14 +123,15 @@
 static char *eopen[] = {
 	"not found",
 	"does not exist",
-	"file is locked",
-	"file locked",
-	"exclusive lock",
 	0,
 };
 
 static char *ecreate[] = {
 	"already exists",
+	0,
+};
+
+static char *elocked[] = {
 	"file is locked",
 	"file locked",
 	"exclusive lock",
@@ -179,12 +180,12 @@
 	int i, fd;
 
 	for(i = 0; i < Idxto/Idxstep; i++){
-		if((fd = open(s, OWRITE|OTRUNC)) >= 0 || bad(eopen)){
+		if((fd = open(s, OWRITE|OTRUNC)) >= 0 || (bad(eopen) && bad(elocked))){
 			if(fd != -1 && forceexcl(fd) == -1)
 				continue;
 			return fd;
 		}
-		if((fd = create(s, OWRITE|OEXCL, DMTMP|DMEXCL|0600)) >= 0  || bad(ecreate))
+		if((fd = create(s, OWRITE|OEXCL, DMTMP|DMEXCL|0600)) >= 0  || (bad(ecreate) && bad(elocked)))
 			return fd;
 		sleep(Idxstep);
 	}
@@ -529,7 +530,8 @@
 	Biobuf *b;
 
 	snprint(buf, sizeof buf, "%s.idx", mb->path);
-	b = Bopen(buf, OREAD);
+	while((b = Bopen(buf, OREAD)) == nil && !bad(elocked))
+		sleep(1000);
 	if(b == nil)
 		return -2;
 	if(qidcmp(Bfildes(b), &mb->qid) == 0)
--