dovecot: Reopen cache file early enough in the transaction if it...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Nov 6 21:56:12 EET 2007
details: http://hg.dovecot.org/dovecot/rev/395082a34cf8
changeset: 6709:395082a34cf8
user: Timo Sirainen <tss at iki.fi>
date: Tue Nov 06 21:56:08 2007 +0200
description:
Reopen cache file early enough in the transaction if it has changed.
diffstat:
1 file changed, 55 insertions(+), 29 deletions(-)
src/lib-index/mail-cache-transaction.c | 84 ++++++++++++++++++++------------
diffs (129 lines):
diff -r a677ce398a6f -r 395082a34cf8 src/lib-index/mail-cache-transaction.c
--- a/src/lib-index/mail-cache-transaction.c Tue Nov 06 21:54:57 2007 +0200
+++ b/src/lib-index/mail-cache-transaction.c Tue Nov 06 21:56:08 2007 +0200
@@ -109,25 +109,60 @@ mail_cache_transaction_free(struct mail_
i_free(ctx);
}
+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;
+
+ if (!cache->opened) {
+ (void)mail_cache_open_and_verify(cache);
+ return;
+ }
+ if (MAIL_CACHE_IS_UNUSABLE(cache))
+ 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);
+}
+
static int mail_cache_transaction_lock(struct mail_cache_transaction_ctx *ctx)
{
+ struct mail_cache *cache = ctx->cache;
int ret;
- if (ctx->cache_file_seq == 0) {
- if (!ctx->cache->opened)
- (void)mail_cache_open_and_verify(ctx->cache);
- if (!MAIL_CACHE_IS_UNUSABLE(ctx->cache)) {
- i_assert(ctx->cache_data == NULL ||
- ctx->cache_data->used == 0);
- ctx->cache_file_seq = ctx->cache->hdr->file_seq;
- }
- }
-
- if ((ret = mail_cache_lock(ctx->cache, FALSE)) <= 0)
- return ret;
-
- if (ctx->cache_file_seq != ctx->cache->hdr->file_seq)
+ mail_cache_transaction_open_if_needed(ctx);
+
+ if ((ret = mail_cache_lock(cache, FALSE)) <= 0) {
+ if (ret < 0)
+ return -1;
+
+ if (!ctx->tried_compression && MAIL_CACHE_IS_UNUSABLE(cache)) {
+ ctx->tried_compression = TRUE;
+ if (mail_cache_compress(cache, ctx->trans) < 0)
+ return -1;
+ return mail_cache_transaction_lock(ctx);
+ } else {
+ return 0;
+ }
+ }
+
+ if (!MAIL_CACHE_IS_UNUSABLE(cache) && ctx->cache_file_seq == 0) {
+ i_assert(ctx->cache_data == NULL ||
+ ctx->cache_data->used == 0);
+ ctx->cache_file_seq = cache->hdr->file_seq;
+ } else if (ctx->cache_file_seq != cache->hdr->file_seq) {
+ if (mail_cache_unlock(cache) < 0)
+ return -1;
mail_cache_transaction_reset(ctx);
+ return 0;
+ }
return 1;
}
@@ -725,14 +760,6 @@ static int mail_cache_header_add_field(s
cache->fields[i].used = TRUE;
if ((ret = mail_cache_transaction_lock(ctx)) <= 0) {
- /* create the cache file if it doesn't exist yet */
- if (ctx->tried_compression)
- return -1;
- ctx->tried_compression = TRUE;
-
- if (mail_cache_compress(cache, ctx->trans) < 0)
- return -1;
-
/* if we compressed the cache, the field should be there now.
it's however possible that someone else just compressed it
and we only reopened the cache file. */
@@ -795,11 +822,12 @@ void mail_cache_add(struct mail_cache_tr
return;
if (ctx->cache_file_seq == 0) {
- if (!ctx->cache->opened)
- (void)mail_cache_open_and_verify(ctx->cache);
-
+ mail_cache_transaction_open_if_needed(ctx);
if (!MAIL_CACHE_IS_UNUSABLE(ctx->cache))
ctx->cache_file_seq = ctx->cache->hdr->file_seq;
+ } else if (ctx->cache_file_seq != ctx->cache->hdr->file_seq) {
+ /* cache was compressed within this transaction */
+ mail_cache_transaction_reset(ctx);
}
file_field = ctx->cache->field_file_map[field_idx];
@@ -874,8 +902,7 @@ bool mail_cache_field_want_add(struct ma
{
enum mail_cache_decision_type decision;
- if (!ctx->cache->opened)
- (void)mail_cache_open_and_verify(ctx->cache);
+ mail_cache_transaction_open_if_needed(ctx);
decision = mail_cache_field_get_decision(ctx->view->cache, field_idx);
if ((decision & ~MAIL_CACHE_DECISION_FORCED) == MAIL_CACHE_DECISION_NO)
@@ -889,8 +916,7 @@ bool mail_cache_field_can_add(struct mai
{
enum mail_cache_decision_type decision;
- if (!ctx->cache->opened)
- (void)mail_cache_open_and_verify(ctx->cache);
+ mail_cache_transaction_open_if_needed(ctx);
decision = mail_cache_field_get_decision(ctx->view->cache, field_idx);
if (decision == (MAIL_CACHE_DECISION_FORCED | MAIL_CACHE_DECISION_NO))
More information about the dovecot-cvs
mailing list