dovecot: If cache file's file_seq appears to be broken, handle i...

dovecot at dovecot.org dovecot at dovecot.org
Sun Nov 18 09:59:58 EET 2007


details:   http://hg.dovecot.org/dovecot/rev/3a41003bb1ae
changeset: 6830:3a41003bb1ae
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Nov 18 09:59:52 2007 +0200
description:
If cache file's file_seq appears to be broken, handle it by compressing the
cache instead of just never using it.

diffstat:

3 files changed, 55 insertions(+), 9 deletions(-)
src/lib-index/mail-cache-lookup.c      |    2 -
src/lib-index/mail-cache-transaction.c |   55 +++++++++++++++++++++++++++-----
src/lib-index/mail-cache.c             |    7 ++++

diffs (114 lines):

diff -r dbab5e592577 -r 3a41003bb1ae src/lib-index/mail-cache-lookup.c
--- a/src/lib-index/mail-cache-lookup.c	Sun Nov 18 08:40:59 2007 +0200
+++ b/src/lib-index/mail-cache-lookup.c	Sun Nov 18 09:59:52 2007 +0200
@@ -72,7 +72,7 @@ mail_cache_lookup_offset(struct mail_cac
 	   it was probably for an old cache file that's already lost by now. */
 	i = 0;
 	while (cache->hdr->file_seq != reset_id) {
-		if (++i == 2)
+		if (++i == 2 || reset_id < cache->hdr->file_seq)
 			return 0;
 
 		if (cache->locked) {
diff -r dbab5e592577 -r 3a41003bb1ae src/lib-index/mail-cache-transaction.c
--- a/src/lib-index/mail-cache-transaction.c	Sun Nov 18 08:40:59 2007 +0200
+++ b/src/lib-index/mail-cache-transaction.c	Sun Nov 18 09:59:52 2007 +0200
@@ -109,12 +109,26 @@ mail_cache_transaction_free(struct mail_
 	i_free(ctx);
 }
 
+static int
+mail_cache_transaction_compress(struct mail_cache_transaction_ctx *ctx)
+{
+	struct mail_cache *cache = ctx->cache;
+
+	ctx->tried_compression = TRUE;
+
+	cache->need_compress_file_seq =
+		MAIL_CACHE_IS_UNUSABLE(cache) ? 0 : cache->hdr->file_seq;
+
+	return mail_cache_compress(cache, ctx->trans);
+}
+
 static void
 mail_cache_transaction_open_if_needed(struct mail_cache_transaction_ctx *ctx)
 {
 	struct mail_cache *cache = ctx->cache;
 	const struct mail_index_ext *ext;
 	uint32_t idx;
+	int i;
 
 	if (!cache->opened) {
 		(void)mail_cache_open_and_verify(cache);
@@ -124,12 +138,38 @@ mail_cache_transaction_open_if_needed(st
 		return;
 
 	/* see if we should try to reopen the cache file */
-	if (!mail_index_map_get_ext_idx(cache->index->map, cache->ext_id, &idx))
-		return;
-
-	ext = array_idx(&cache->index->map->extensions, idx);
-	if (ext->reset_id != cache->hdr->file_seq)
-		(void)mail_cache_reopen(cache);
+	for (i = 0;; i++) {
+		if (!mail_index_map_get_ext_idx(cache->index->map,
+						cache->ext_id, &idx))
+			return;
+
+		ext = array_idx(&cache->index->map->extensions, idx);
+		if (ext->reset_id == cache->hdr->file_seq || i == 2)
+			break;
+
+		/* index offsets don't match the cache file */
+		if (ext->reset_id > cache->hdr->file_seq) {
+			/* the cache file appears to be too old.
+			   reopening should help. */
+			if (mail_cache_reopen(cache) != 0)
+				break;
+		}
+
+		/* cache file sequence might be broken. it's also possible
+		   that it was just compressed and we just haven't yet seen
+		   the changes in index. try if refreshing index helps.
+		   if not, compress the cache file. */
+		if (i == 0) {
+			if (ctx->tried_compression)
+				break;
+			/* get the latest reset ID */
+			if (mail_index_refresh(ctx->cache->index) < 0)
+				return;
+		} else {
+			i_assert(i == 1);
+			(void)mail_cache_transaction_compress(ctx);
+		}
+	}
 }
 
 static int mail_cache_transaction_lock(struct mail_cache_transaction_ctx *ctx)
@@ -144,8 +184,7 @@ static int mail_cache_transaction_lock(s
 			return -1;
 
 		if (!ctx->tried_compression && MAIL_CACHE_IS_UNUSABLE(cache)) {
-			ctx->tried_compression = TRUE;
-			if (mail_cache_compress(cache, ctx->trans) < 0)
+			if (mail_cache_transaction_compress(ctx) < 0)
 				return -1;
 			return mail_cache_transaction_lock(ctx);
 		} else {
diff -r dbab5e592577 -r 3a41003bb1ae src/lib-index/mail-cache.c
--- a/src/lib-index/mail-cache.c	Sun Nov 18 08:40:59 2007 +0200
+++ b/src/lib-index/mail-cache.c	Sun Nov 18 09:59:52 2007 +0200
@@ -521,6 +521,13 @@ int mail_cache_lock(struct mail_cache *c
 		if (cache->hdr->file_seq != reset_id &&
 		    (require_same_reset_id || i == 0)) {
 			/* we want the latest cache file */
+			if (reset_id < cache->hdr->file_seq) {
+				/* either we're still waiting for index to
+				   catch up with a cache compression, or
+				   that catching up is never going to happen */
+				ret = 0;
+				break;
+			}
 			ret = mail_cache_reopen(cache);
 			if (ret < 0 || (ret == 0 && require_same_reset_id))
 				break;


More information about the dovecot-cvs mailing list