Mercurial > dovecot > original-hg > dovecot-1.2
changeset 6703:75c48f171ad3 HEAD
Keep a separate copy of mail_cache_header when mmap_disable=yes, otherwise
it could get cleared unexpectedly.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 06 Nov 2007 20:28:01 +0200 |
parents | 34a5cf8675fc |
children | b0e8403b4bb1 |
files | src/lib-index/mail-cache-private.h src/lib-index/mail-cache-transaction.c src/lib-index/mail-cache.c |
diffstat | 3 files changed, 24 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-cache-private.h Tue Nov 06 19:13:33 2007 +0200 +++ b/src/lib-index/mail-cache-private.h Tue Nov 06 20:28:01 2007 +0200 @@ -142,7 +142,13 @@ struct dotlock *dotlock; struct file_lock *file_lock; + /* mmap_disable=no: hdr points to data / NULL when cache is invalid. + mmap_disable=yes: hdr points to hdr_ro_copy. this is needed because + cache invalidation can zero the data any time */ const struct mail_cache_header *hdr; + struct mail_cache_header hdr_ro_copy; + /* hdr_copy gets updated when cache is locked and written when + unlocking and hdr_modified=TRUE */ struct mail_cache_header hdr_copy; pool_t field_pool;
--- a/src/lib-index/mail-cache-transaction.c Tue Nov 06 19:13:33 2007 +0200 +++ b/src/lib-index/mail-cache-transaction.c Tue Nov 06 20:28:01 2007 +0200 @@ -705,6 +705,7 @@ /* we're adding the first field. hdr_copy needs to be kept in sync so unlocking won't overwrite it. */ cache->hdr_copy.field_header_offset = hdr_offset; + cache->hdr_ro_copy.field_header_offset = hdr_offset; } return 0; }
--- a/src/lib-index/mail-cache.c Tue Nov 06 19:13:33 2007 +0200 +++ b/src/lib-index/mail-cache.c Tue Nov 06 20:28:01 2007 +0200 @@ -181,7 +181,7 @@ return FALSE; } - if (cache->hdr->version != MAIL_CACHE_VERSION) { + if (hdr->version != MAIL_CACHE_VERSION) { /* version changed - upgrade silently */ return FALSE; } @@ -190,11 +190,11 @@ return FALSE; } - if (cache->hdr->indexid != cache->index->indexid) { + if (hdr->indexid != cache->index->indexid) { /* index id changed - handle silently */ return FALSE; } - if (cache->hdr->file_seq == 0) { + if (hdr->file_seq == 0) { mail_cache_set_corrupted(cache, "file_seq is 0"); return FALSE; } @@ -249,16 +249,19 @@ cache->data = file_cache_get_map(cache->file_cache, &cache->mmap_length); - cache->hdr = cache->data; - if (offset == 0 && !mail_cache_verify_header(cache)) { - cache->need_compress_file_seq = - !MAIL_CACHE_IS_UNUSABLE(cache) && - cache->hdr->file_seq != 0 ? - cache->hdr->file_seq : 0; - cache->hdr = NULL; - return -1; + if (offset == 0) { + if (!mail_cache_verify_header(cache)) { + cache->need_compress_file_seq = + !MAIL_CACHE_IS_UNUSABLE(cache) && + cache->hdr->file_seq != 0 ? + cache->hdr->file_seq : 0; + return -1; + } + memcpy(&cache->hdr_ro_copy, cache->data, + sizeof(cache->hdr_ro_copy)); } + cache->hdr = &cache->hdr_ro_copy; return 0; } @@ -293,17 +296,16 @@ return -1; } cache->data = cache->mmap_base; - cache->hdr = cache->mmap_base; if (!mail_cache_verify_header(cache)) { cache->need_compress_file_seq = !MAIL_CACHE_IS_UNUSABLE(cache) && cache->hdr->file_seq != 0 ? cache->hdr->file_seq : 0; - cache->hdr = NULL; return -1; } + cache->hdr = cache->data; return 0; } @@ -601,6 +603,7 @@ if (mail_cache_write(cache, &cache->hdr_copy, sizeof(cache->hdr_copy), 0) < 0) ret = -1; + cache->hdr_ro_copy = cache->hdr_copy; mail_cache_update_need_compress(cache); } @@ -624,10 +627,9 @@ if (cache->file_cache != NULL) { file_cache_write(cache->file_cache, data, size, offset); - /* data/hdr pointers may change if file cache was grown */ + /* data pointer may change if file cache was grown */ cache->data = file_cache_get_map(cache->file_cache, &cache->mmap_length); - cache->hdr = cache->data; } return 0; }