dovecot: Keep a separate copy of mail_cache_header when mmap_dis...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Nov 6 20:28:06 EET 2007
details: http://hg.dovecot.org/dovecot/rev/75c48f171ad3
changeset: 6703:75c48f171ad3
user: Timo Sirainen <tss at iki.fi>
date: Tue Nov 06 20:28:01 2007 +0200
description:
Keep a separate copy of mail_cache_header when mmap_disable=yes, otherwise
it could get cleared unexpectedly.
diffstat:
3 files changed, 29 insertions(+), 20 deletions(-)
src/lib-index/mail-cache-private.h | 6 ++++
src/lib-index/mail-cache-transaction.c | 1
src/lib-index/mail-cache.c | 42 ++++++++++++++++----------------
diffs (126 lines):
diff -r 34a5cf8675fc -r 75c48f171ad3 src/lib-index/mail-cache-private.h
--- 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 mail_cache {
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;
diff -r 34a5cf8675fc -r 75c48f171ad3 src/lib-index/mail-cache-transaction.c
--- 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 @@ mail_cache_header_fields_write(struct ma
/* 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;
}
diff -r 34a5cf8675fc -r 75c48f171ad3 src/lib-index/mail-cache.c
--- 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 @@ static bool mail_cache_verify_header(str
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 @@ static bool mail_cache_verify_header(str
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 @@ int mail_cache_map(struct mail_cache *ca
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 @@ int mail_cache_map(struct mail_cache *ca
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;
- }
-
+ return -1;
+ }
+
+ cache->hdr = cache->data;
return 0;
}
@@ -601,6 +603,7 @@ int mail_cache_unlock(struct mail_cache
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 @@ int mail_cache_write(struct mail_cache *
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;
}
More information about the dovecot-cvs
mailing list