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