Mercurial > dovecot > original-hg > dovecot-1.2
changeset 4285:9f5cdfb282a0 HEAD
We were caching the EOF block wrongly in some situations.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 30 May 2006 11:37:10 +0300 |
parents | ae0d876d98f5 |
children | b5b0e98b1d98 |
files | src/lib/file-cache.c |
diffstat | 1 files changed, 18 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/file-cache.c Tue May 30 11:36:43 2006 +0300 +++ b/src/lib/file-cache.c Tue May 30 11:37:10 2006 +0300 @@ -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) {