ref: b0ad72be22c9125e674d53bc7f9c086cd7c1ac83
parent: fc6d319a3fc26e3a8335cbe61764ce5c67580a3e
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Sep 25 21:54:03 EDT 2023
upas/fs: write index out to temp file pridx() can be extremely slow when reading from imap, because it ensures each message is cached. Ensuring each message is cached may take a round trip to the IMAP server. Instead, we should write the index to a temp file, and rename it, to reduce the window wher the index can be broken.
--- a/sys/src/cmd/upas/fs/idx.c
+++ b/sys/src/cmd/upas/fs/idx.c
@@ -240,12 +240,12 @@
int
wridxfile(Mailbox *mb)
{
- char buf[Pathlen + 4];
+ char *p, buf[Pathlen + 32];
int r, fd;
Biobuf b;
- Dir *d;
+ Dir *d, n;
- snprint(buf, sizeof buf, "%s.idx", mb->path);
+ snprint(buf, sizeof buf, "%s.idx.tmp", mb->path);
iprint("wridxfile %s\n", buf);
if((fd = exopen(buf)) == -1){
rerrstr(buf, sizeof buf);
@@ -258,8 +258,21 @@
Binit(&b, fd, OWRITE);
r = pridx(&b, mb);
Bterm(&b);
+
+ /* remove and rename over the old index */
+ snprint(buf, sizeof buf, "%s.idx", mb->path);
+ remove(buf);
+
+ if((p = strrchr(mb->path, '/')) == nil)
+ sysfatal("index path is directory");
+ snprint(buf, sizeof buf, "%s.idx", p+1);
+ nulldir(&n);
+ n.name = buf;
+ if(dirfwstat(fd, &n) == -1)
+ sysfatal("dirfwstat: %r");
+
d = dirfstat(fd);
- if(d == 0)
+ if(d == nil)
sysfatal("dirfstat: %r");
mb->qid = d->qid;
free(d);