[dovecot-cvs] dovecot/src/lib file-cache.c,1.12,1.12.2.1

cras at dovecot.org cras at dovecot.org
Mon May 29 02:43:46 EEST 2006


Update of /var/lib/cvs/dovecot/src/lib
In directory talvi:/tmp/cvs-serv19350

Modified Files:
      Tag: branch_1_0
	file-cache.c 
Log Message:
We were caching the EOF block wrongly in some situations.



Index: file-cache.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/file-cache.c,v
retrieving revision 1.12
retrieving revision 1.12.2.1
diff -u -d -r1.12 -r1.12.2.1
--- file-cache.c	16 Feb 2006 15:23:04 -0000	1.12
+++ file-cache.c	28 May 2006 23:43:44 -0000	1.12.2.1
@@ -168,7 +168,12 @@
 			/* EOF. mark the last block as cached even if it
 			   isn't completely. read_highwater tells us how far
 			   we've actually made. */
-			bits[poffset / CHAR_BIT] |= 1 << (poffset % CHAR_BIT);
+			if (dest_offset == cache->read_highwater) {
+				i_assert(poffset ==
+					 cache->read_highwater / page_size);
+				bits[poffset / CHAR_BIT] |=
+					1 << (poffset % CHAR_BIT);
+			}
 			return dest_offset <= offset ? 0 :
 				dest_offset - offset < size ?
 				dest_offset - offset : size;
@@ -177,8 +182,17 @@
 		dest += ret;
 		dest_offset += ret;
 
-		if (cache->read_highwater < dest_offset)
+		if (cache->read_highwater < dest_offset) {
+			unsigned int high_poffset =
+				cache->read_highwater / page_size;
+
+			/* read_highwater needs to be updated. if we didn't
+			   just read that block, we can't trust anymore that
+			   we have it cached */
+			bits[high_poffset / CHAR_BIT] &=
+				~(1 << (high_poffset % CHAR_BIT));
 			cache->read_highwater = dest_offset;
+		}
 
 		if ((size_t)ret != dest_size) {
 			/* partial read - probably EOF but make sure. */
@@ -247,7 +261,7 @@
 	unsigned char *bits, mask;
 	unsigned int i;
 
-	if (offset >= cache->read_highwater)
+	if (offset >= cache->read_highwater || size == 0)
 		return;
 
 	if (size > cache->read_highwater - offset)
@@ -255,6 +269,7 @@
 
 	size = (offset + size + page_size-1) / page_size;
 	offset /= page_size;
+	i_assert(size > offset);
 	size -= offset;
 
 	if (size != 1) {



More information about the dovecot-cvs mailing list