From: Timo Sirainen Date: Tue, 10 Mar 2009 16:28:22 +0000 (-0400) Subject: indexes: Fixes to handling shrinking tail offsets. X-Git-Tag: 1.2.beta2~20 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5d264bf541597af95a31c342644f6bb0fa6e0708;p=thirdparty%2Fdovecot%2Fcore.git indexes: Fixes to handling shrinking tail offsets. --HG-- branch : HEAD --- diff --git a/src/lib-index/mail-index-sync.c b/src/lib-index/mail-index-sync.c index 7c4f5d26f3..131b0207a6 100644 --- a/src/lib-index/mail-index-sync.c +++ b/src/lib-index/mail-index-sync.c @@ -461,6 +461,7 @@ int mail_index_sync_begin_to(struct mail_index *index, 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; diff --git a/src/lib-index/mail-index-transaction-private.h b/src/lib-index/mail-index-transaction-private.h index 9f9d260aa7..260b105475 100644 --- a/src/lib-index/mail-index-transaction-private.h +++ b/src/lib-index/mail-index-transaction-private.h @@ -73,6 +73,7 @@ struct mail_index_transaction { 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; diff --git a/src/lib-index/mail-transaction-log-append.c b/src/lib-index/mail-transaction-log-append.c index 6f4f77f399..4a264cde65 100644 --- a/src/lib-index/mail-transaction-log-append.c +++ b/src/lib-index/mail-transaction-log-append.c @@ -523,6 +523,13 @@ static void log_append_sync_offset_if_needed(struct log_append_context *ctx) 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 diff --git a/src/lib-index/mail-transaction-log-file.c b/src/lib-index/mail-transaction-log-file.c index e02363328f..c3c7bf40d5 100644 --- a/src/lib-index/mail-transaction-log-file.c +++ b/src/lib-index/mail-transaction-log-file.c @@ -147,8 +147,11 @@ mail_transaction_log_file_skip_to_head(struct mail_transaction_log_file *file) 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 @@ log_file_track_mailbox_sync_offset_hdr(struct mail_transaction_log_file *file, 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 @@ log_file_track_mailbox_sync_offset_hdr(struct mail_transaction_log_file *file, 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; }