Mercurial > dovecot > original-hg > dovecot-1.2
changeset 1937:f56d502b248b HEAD
Ignore new mail appends if they're already in transaction log.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 29 Apr 2004 15:49:27 +0300 |
parents | bb1bde2680b0 |
children | a2eaa322ca8c |
files | src/lib-index/mail-index-sync-update.c src/lib-index/mail-transaction-log.c |
diffstat | 2 files changed, 69 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-index-sync-update.c Thu Apr 29 03:13:05 2004 +0300 +++ b/src/lib-index/mail-index-sync-update.c Thu Apr 29 15:49:27 2004 +0300 @@ -151,10 +151,6 @@ mail_index_header_update_lowwaters(&ctx->hdr, &appends[i]); if (appends[i].uid < next_uid) { - /* FIXME: should we rather just update the record? - this can actually happen if append was written to - transaction log but index wasn't updated, then - another sync wrote it again.. */ mail_transaction_log_view_set_corrupted(ctx->log_view, "Append with UID %u, but next_uid = %u", appends[i].uid, next_uid);
--- a/src/lib-index/mail-transaction-log.c Thu Apr 29 03:13:05 2004 +0300 +++ b/src/lib-index/mail-transaction-log.c Thu Apr 29 15:49:27 2004 +0300 @@ -877,6 +877,73 @@ return 0; } +static int mail_transaction_log_fix_appends(struct mail_transaction_log *log, + struct mail_index_transaction *t) +{ + struct mail_transaction_log_view *sync_view; + const struct mail_index_record *old, *old_end; + struct mail_index_record *appends, *end, *rec, *dest; + const struct mail_transaction_header *hdr; + const void *data; + size_t size; + int ret, deleted = FALSE; + + if (t->appends == NULL) + return 0; + + appends = buffer_get_modifyable_data(t->appends, &size); + end = PTR_OFFSET(appends, size); + + if (appends == end) + return 0; + + /* 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; + + old = data; + old_end = CONST_PTR_OFFSET(old, hdr->size); + for (; old != old_end; old++) { + /* appends are sorted */ + for (rec = appends; rec != end; rec++) { + if (rec->uid >= old->uid) { + if (rec->uid == old->uid) { + rec->uid = 0; + deleted = TRUE; + } + break; + } + } + } + } + + if (deleted) { + /* compress deleted appends away */ + for (rec = dest = appends; rec != end; rec++) { + if (rec->uid != 0) + dest++; + else if (rec != dest) + *rec = *dest; + } + buffer_set_used_size(t->appends, + (char *)dest - (char *)appends); + } + + mail_transaction_log_view_close(sync_view); + return ret; +} + static int log_append_buffer(struct mail_transaction_log_file *file, const buffer_t *buf, enum mail_transaction_type type, int external) @@ -944,7 +1011,8 @@ file = log->head; append_offset = file->hdr.used_size; - if (mail_transaction_log_fix_sequences(log, t) < 0) { + if (mail_transaction_log_fix_sequences(log, t) < 0 || + mail_transaction_log_fix_appends(log, t) < 0) { if (!log->index->log_locked) (void)mail_transaction_log_file_lock(file, F_UNLCK); return -1;