shithub: riscv

Download patch

ref: fc2a3496feb277add577903425058c5ca1f2a9af
parent: 786ec28b7b561fb1448a884ee0cd51525e9339d6
author: cinap_lenrek <[email protected]>
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)