Mercurial > dovecot > core-2.2
changeset 2282:c54f0c01da09 HEAD
Make sure we don't set cache_offsets to old cache files.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 05 Jul 2004 00:56:12 +0300 |
parents | e2a9be7c2270 |
children | 199eb3df762c |
files | src/lib-index/mail-cache-compress.c src/lib-index/mail-cache-transaction.c src/lib-index/mail-index-private.h src/lib-index/mail-index-transaction-private.h src/lib-index/mail-index-transaction.c src/lib-index/mail-transaction-log.c |
diffstat | 6 files changed, 104 insertions(+), 49 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-cache-compress.c Mon Jul 05 00:22:00 2004 +0300 +++ b/src/lib-index/mail-cache-compress.c Mon Jul 05 00:56:12 2004 +0300 @@ -188,7 +188,8 @@ if (keep_fields == cached_fields && cache_rec->prev_offset == 0) { /* just one unmodified block, save it */ - mail_index_update_cache(t, seq, output->offset, NULL); + mail_index_update_cache(t, seq, hdr.file_seq, + output->offset, NULL); o_stream_send(output, cache_rec, cache_rec->size); if ((cache_rec->size & 3) != 0) { @@ -198,7 +199,8 @@ } else { /* a) dropping fields b) multiple blocks, sort them into buffer */ - mail_index_update_cache(t, seq, output->offset, NULL); + mail_index_update_cache(t, seq, hdr.file_seq, + output->offset, NULL); t_push(); cache_rec = mail_cache_compress_record(cache_view, seq,
--- a/src/lib-index/mail-cache-transaction.c Mon Jul 05 00:22:00 2004 +0300 +++ b/src/lib-index/mail-cache-transaction.c Mon Jul 05 00:56:12 2004 +0300 @@ -369,6 +369,7 @@ synced. */ for (; seq_idx < seq_limit; seq_idx++) { mail_index_update_cache(ctx->trans, seq[seq_idx], + cache->hdr->file_seq, write_offset, &old_offset); if (old_offset != 0) { /* we added records for this message multiple
--- a/src/lib-index/mail-index-private.h Mon Jul 05 00:22:00 2004 +0300 +++ b/src/lib-index/mail-index-private.h Mon Jul 05 00:56:12 2004 +0300 @@ -132,8 +132,8 @@ void mail_index_reset_cache(struct mail_index_transaction *t, uint32_t new_file_seq); -void mail_index_update_cache(struct mail_index_transaction *t, - uint32_t seq, uint32_t offset, +void mail_index_update_cache(struct mail_index_transaction *t, uint32_t seq, + uint32_t file_seq, uint32_t offset, uint32_t *old_offset_r); int mail_index_fix_header(struct mail_index *index, struct mail_index_map *map,
--- a/src/lib-index/mail-index-transaction-private.h Mon Jul 05 00:22:00 2004 +0300 +++ b/src/lib-index/mail-index-transaction-private.h Mon Jul 05 00:56:12 2004 +0300 @@ -22,7 +22,7 @@ buffer_t *extra_rec_updates[MAIL_INDEX_MAX_EXTRA_RECORDS]; - uint32_t new_cache_file_seq; + uint32_t new_cache_file_seq, last_cache_file_seq; buffer_t *cache_updates; struct mail_cache_transaction_ctx *cache_trans_ctx;
--- a/src/lib-index/mail-index-transaction.c Mon Jul 05 00:22:00 2004 +0300 +++ b/src/lib-index/mail-index-transaction.c Mon Jul 05 00:56:12 2004 +0300 @@ -563,18 +563,44 @@ return FALSE; } +static void +mail_index_transaction_reset_cache_updates(struct mail_index_transaction *t) +{ + struct mail_index_record *rec; + uint32_t seq; + + if (t->last_cache_file_seq == 0) + return; + + buffer_set_used_size(t->cache_updates, 0); + + if (t->first_new_seq != 0) { + for (seq = t->first_new_seq; seq <= t->last_new_seq; seq++) { + rec = mail_index_transaction_lookup(t, seq); + rec->cache_offset = 0; + } + } +} + void mail_index_reset_cache(struct mail_index_transaction *t, uint32_t new_file_seq) { + mail_index_transaction_reset_cache_updates(t); t->new_cache_file_seq = new_file_seq; + t->last_cache_file_seq = new_file_seq; } -void mail_index_update_cache(struct mail_index_transaction *t, - uint32_t seq, uint32_t offset, +void mail_index_update_cache(struct mail_index_transaction *t, uint32_t seq, + uint32_t file_seq, uint32_t offset, uint32_t *old_offset_r) { struct mail_index_record *rec; + if (file_seq > t->last_cache_file_seq) { + mail_index_transaction_reset_cache_updates(t); + t->last_cache_file_seq = file_seq; + } + if (seq >= t->first_new_seq) { /* just appended message, modify it directly */ rec = mail_index_transaction_lookup(t, seq);
--- a/src/lib-index/mail-transaction-log.c Mon Jul 05 00:22:00 2004 +0300 +++ b/src/lib-index/mail-transaction-log.c Mon Jul 05 00:56:12 2004 +0300 @@ -883,62 +883,45 @@ return ret; } -static int mail_transaction_log_fix_appends(struct mail_transaction_log *log, - struct mail_index_transaction *t) +static void +mail_transaction_log_append_fix(struct mail_index_transaction *t, + const struct mail_transaction_header *hdr, + const void *data) { - struct mail_transaction_log_view *sync_view; + const struct mail_transaction_append_header *append_hdr = data; const struct mail_index_record *old, *old_end; struct mail_index_record *appends, *end, *rec, *dest; - const struct mail_transaction_append_header *append_hdr; - const struct mail_transaction_header *hdr; - const void *data; + uint32_t record_size = t->append_record_size; size_t size; - uint32_t record_size; - int ret, deleted = FALSE; + int deleted = FALSE; if (t->appends == NULL) - return 0; + return; - record_size = t->append_record_size; appends = buffer_get_modifyable_data(t->appends, &size); end = PTR_OFFSET(appends, size); if (appends == end) - return 0; + return; /* we'll just check that none of the appends are already in transaction log. this could happen if we crashed before we had a chance to update index file */ - sync_view = mail_transaction_log_view_open(log); - ret = mail_transaction_log_view_set(sync_view, t->view->log_file_seq, - t->view->log_file_offset, - log->head->hdr.file_seq, - log->head->hdr.used_size, - MAIL_TRANSACTION_TYPE_MASK); - while ((ret = mail_transaction_log_view_next(sync_view, - &hdr, &data, NULL)) == 1) { - if ((hdr->type & MAIL_TRANSACTION_TYPE_MASK) != - MAIL_TRANSACTION_APPEND) - continue; - - append_hdr = data; - - old = CONST_PTR_OFFSET(data, sizeof(*append_hdr)); - old_end = CONST_PTR_OFFSET(data, hdr->size); - while (old != old_end) { - /* appends are sorted */ - for (rec = appends; rec != end; ) { - if (rec->uid >= old->uid) { - if (rec->uid == old->uid) { - rec->uid = 0; - deleted = TRUE; - } - break; + old = CONST_PTR_OFFSET(data, sizeof(*append_hdr)); + old_end = CONST_PTR_OFFSET(data, hdr->size); + while (old != old_end) { + /* appends are sorted */ + for (rec = appends; rec != end; ) { + if (rec->uid >= old->uid) { + if (rec->uid == old->uid) { + rec->uid = 0; + deleted = TRUE; } - rec = PTR_OFFSET(rec, record_size); + break; } - old = CONST_PTR_OFFSET(old, append_hdr->record_size); + rec = PTR_OFFSET(rec, record_size); } + old = CONST_PTR_OFFSET(old, append_hdr->record_size); } if (deleted) { @@ -953,6 +936,44 @@ buffer_set_used_size(t->appends, (char *)dest - (char *)appends); } +} + +static int mail_transaction_log_scan_pending(struct mail_transaction_log *log, + struct mail_index_transaction *t) +{ + struct mail_transaction_log_view *sync_view; + const struct mail_transaction_header *hdr; + const void *data; + uint32_t max_cache_file_seq = 0; + int ret; + + sync_view = mail_transaction_log_view_open(log); + ret = mail_transaction_log_view_set(sync_view, t->view->log_file_seq, + t->view->log_file_offset, + log->head->hdr.file_seq, + log->head->hdr.used_size, + MAIL_TRANSACTION_TYPE_MASK); + while ((ret = mail_transaction_log_view_next(sync_view, + &hdr, &data, NULL)) == 1) { + switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) { + case MAIL_TRANSACTION_APPEND: + mail_transaction_log_append_fix(t, hdr, data); + break; + case MAIL_TRANSACTION_CACHE_RESET: { + const struct mail_transaction_cache_reset *reset = data; + + max_cache_file_seq = reset->new_file_seq; + break; + } + } + } + + /* make sure we're not writing cache_offsets to old cache file */ + if (t->new_cache_file_seq == 0 && max_cache_file_seq != 0 && + max_cache_file_seq != t->last_cache_file_seq) { + buffer_free(t->cache_updates); + t->cache_updates = NULL; + } mail_transaction_log_view_close(sync_view); return ret; @@ -1107,10 +1128,15 @@ file = log->head; append_offset = file->hdr.used_size; - if (mail_transaction_log_fix_appends(log, t) < 0) { - if (!log->index->log_locked) - (void)mail_transaction_log_file_lock(file, F_UNLCK); - return -1; + if (t->appends != NULL || + (t->cache_updates != NULL && t->new_cache_file_seq == 0)) { + if (mail_transaction_log_scan_pending(log, t) < 0) { + if (!log->index->log_locked) { + (void)mail_transaction_log_file_lock(file, + F_UNLCK); + } + return -1; + } } ret = 0;