shithub: riscv

Download patch

ref: 2c6cc121339ade33ac5aa4b46356df1cd5469fbe
parent: f464b7ff16135fc4dddf30291dc5b7226651d2b3
author: Alex Musolino <alex@musolino.id.au>
date: Sun Dec 30 19:00:09 EST 2018

upas/fs: fix infinite loop in putcache (again)

The previous attempt to fix this problem (see changesets b32199e0f90a
and 00ae79a6ba50) caused all calls to cachefree to free the cached
message contents in addition to updating the LRU list.  This causes
problems for the POP3 driver since it provides no fetch function; once
a message is evicted from the LRU cache, its contents is lost.

This time we fix cachefree to always update the LRU list but only free
the cached message contents if the driver provides a fetch function or
the force flag is set.

--- a/sys/src/cmd/upas/fs/cache.c
+++ b/sys/src/cmd/upas/fs/cache.c
@@ -35,7 +35,7 @@
 }
 
 void
-cachefree(Mailbox *mb, Message *m)
+cachefree(Mailbox *mb, Message *m, int force)
 {
 	long i;
 	Message *s, **ll;
@@ -54,7 +54,9 @@
 		mb->cached -= m->csize;
 	}
 	for(s = m->part; s; s = s->next)
-		cachefree(mb, s);
+		cachefree(mb, s, force);
+	if(!force && mb->fetch == nil)
+		return;
 	if(m->mallocd){
 		free(m->start);
 		m->mallocd = 0;
@@ -101,7 +103,7 @@
 				return;
 			addlru(mb, mb->lru);
 		}
-		cachefree(mb, mb->lru);
+		cachefree(mb, mb->lru, 0);
 	}
 }
 
--- a/sys/src/cmd/upas/fs/dat.h
+++ b/sys/src/cmd/upas/fs/dat.h
@@ -207,7 +207,7 @@
 
 /**/
 void		putcache(Mailbox*, Message*);		/* asymmetricial */
-void		cachefree(Mailbox*, Message*);
+void		cachefree(Mailbox*, Message*, int);
 
 char*		syncmbox(Mailbox*, int);
 void*		emalloc(ulong);
--- a/sys/src/cmd/upas/fs/mbox.c
+++ b/sys/src/cmd/upas/fs/mbox.c
@@ -1041,7 +1041,7 @@
 
 		if(Topmsg(mb, m))
 			mtreedelete(mb, m);
-		cachefree(mb, m);
+		cachefree(mb, m, 1);
 		idxfree(m);
 	}
 	free(m->unixfrom);