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