Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8811:69ddd7c9c585 HEAD
indexes: Fixes to handling shrinking tail offsets.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 10 Mar 2009 12:28:22 -0400 |
parents | b21104f6a752 |
children | 69a5c4798421 |
files | src/lib-index/mail-index-sync.c src/lib-index/mail-index-transaction-private.h src/lib-index/mail-transaction-log-append.c src/lib-index/mail-transaction-log-file.c |
diffstat | 4 files changed, 31 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-index-sync.c Tue Mar 10 12:28:00 2009 -0400 +++ b/src/lib-index/mail-index-sync.c Tue Mar 10 12:28:22 2009 -0400 @@ -461,6 +461,7 @@ if ((ctx->flags & MAIL_INDEX_SYNC_FLAG_AVOID_FLAG_UPDATES) != 0) trans_flags |= MAIL_INDEX_TRANSACTION_FLAG_AVOID_FLAG_UPDATES; ctx->ext_trans = mail_index_transaction_begin(ctx->view, trans_flags); + ctx->ext_trans->sync_transaction = TRUE; index->syncing = TRUE;
--- a/src/lib-index/mail-index-transaction-private.h Tue Mar 10 12:28:00 2009 -0400 +++ b/src/lib-index/mail-index-transaction-private.h Tue Mar 10 12:28:22 2009 -0400 @@ -73,6 +73,7 @@ unsigned int no_appends:1; + unsigned int sync_transaction:1; unsigned int appends_nonsorted:1; unsigned int pre_hdr_changed:1; unsigned int post_hdr_changed:1;
--- a/src/lib-index/mail-transaction-log-append.c Tue Mar 10 12:28:00 2009 -0400 +++ b/src/lib-index/mail-transaction-log-append.c Tue Mar 10 12:28:22 2009 -0400 @@ -523,6 +523,13 @@ buffer_t *buf; uint32_t offset; + /* Update the tail offsets only when committing the sync transaction. + Other transactions may not know the latest tail offset and might + end up shrinking it. (Alternatively the shrinking tail offsets could + just be ignored, which would probably work fine too.) */ + if (!ctx->trans->sync_transaction) + return; + if (ctx->file->max_tail_offset == ctx->file->sync_offset) { /* FIXME: when we remove exclusive log locking, we can't rely on this. then write non-changed offset + check
--- a/src/lib-index/mail-transaction-log-file.c Tue Mar 10 12:28:00 2009 -0400 +++ b/src/lib-index/mail-transaction-log-file.c Tue Mar 10 12:28:22 2009 -0400 @@ -147,8 +147,11 @@ file->sync_offset = modseq_hdr->log_offset; file->sync_highest_modseq = modseq_hdr->highest_modseq; } - file->saved_tail_offset = log->index->map->hdr.log_file_tail_offset; - file->saved_tail_sync_offset = file->saved_tail_offset; + if (file->hdr.file_seq == log->index->map->hdr.log_file_seq) { + file->saved_tail_offset = + log->index->map->hdr.log_file_tail_offset; + file->saved_tail_sync_offset = file->saved_tail_offset; + } if (file->saved_tail_offset > file->max_tail_offset) file->max_tail_offset = file->saved_tail_offset; } @@ -755,9 +758,9 @@ const unsigned int offset_pos = offsetof(struct mail_index_header, log_file_tail_offset); const unsigned int offset_size = sizeof(ihdr->log_file_tail_offset); - uint32_t sync_offset; + uint32_t tail_offset; - i_assert(offset_size == sizeof(sync_offset)); + i_assert(offset_size == sizeof(tail_offset)); if (size < sizeof(*u) || size < sizeof(*u) + u->size) { mail_transaction_log_file_set_corrupted(file, @@ -767,28 +770,31 @@ if (u->offset <= offset_pos && u->offset + u->size >= offset_pos + offset_size) { - memcpy(&sync_offset, + memcpy(&tail_offset, CONST_PTR_OFFSET(u + 1, offset_pos - u->offset), - sizeof(sync_offset)); + sizeof(tail_offset)); - if (sync_offset < file->saved_tail_offset) { + if (tail_offset < file->saved_tail_offset) { if (file->sync_offset < file->saved_tail_sync_offset) { /* saved_tail_offset was already set in header, but we still had to resync the file to find modseqs. ignore this record. */ return 1; } - mail_transaction_log_file_set_corrupted(file, + mail_index_set_error(file->log->index, + "Transaction log file %s seq %u: " "log_file_tail_offset update shrank it " - "(%u vs %"PRIuUOFF_T", file_seq=%u)", - sync_offset, file->saved_tail_offset, - file->hdr.file_seq); - return -1; + "(%u vs %"PRIuUOFF_T" " + "sync_offset=%"PRIuUOFF_T")", + file->filepath, file->hdr.file_seq, + tail_offset, file->saved_tail_offset, + file->sync_offset); + } else { + file->saved_tail_offset = tail_offset; + if (tail_offset > file->max_tail_offset) + file->max_tail_offset = tail_offset; + return 1; } - file->saved_tail_offset = sync_offset; - if (sync_offset > file->max_tail_offset) - file->max_tail_offset = sync_offset; - return 1; } return 0; }