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.
This commit is contained in:
Ori Bernstein 2023-09-26 01:54:03 +00:00
parent fc6d319a3f
commit b0ad72be22

View file

@ -240,12 +240,12 @@ lose:
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 @@ wridxfile(Mailbox *mb)
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);