dovecot-1.0: Map the log files only after they've all been found...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Jun 20 23:58:52 EEST 2007
details: http://hg.dovecot.org/dovecot-1.0/rev/b55165d5e675
changeset: 5324:b55165d5e675
user: Timo Sirainen <tss at iki.fi>
date: Wed Jun 20 23:58:48 2007 +0300
description:
Map the log files only after they've all been found. Otherwise we could have
skipped some transactions from the end of non-head logs.
diffstat:
1 file changed, 39 insertions(+), 25 deletions(-)
src/lib-index/mail-transaction-log-view.c | 64 +++++++++++++++++------------
diffs (106 lines):
diff -r 98cd45935799 -r b55165d5e675 src/lib-index/mail-transaction-log-view.c
--- a/src/lib-index/mail-transaction-log-view.c Wed Jun 20 20:51:38 2007 +0300
+++ b/src/lib-index/mail-transaction-log-view.c Wed Jun 20 23:58:48 2007 +0300
@@ -97,9 +97,10 @@ mail_transaction_log_view_set(struct mai
uint32_t max_file_seq, uoff_t max_file_offset,
enum mail_transaction_type type_mask)
{
- struct mail_transaction_log_file *file, *first;
+ struct mail_transaction_log_file *file, *const *files;
+ unsigned int i;
uint32_t seq;
- uoff_t end_offset;
+ uoff_t start_offset, end_offset;
int ret;
i_assert(view->log != NULL);
@@ -159,12 +160,8 @@ mail_transaction_log_view_set(struct mai
return -1;
}
- end_offset = min_file_seq == max_file_seq ?
- max_file_offset : (uoff_t)-1;
- ret = mail_transaction_log_file_map(file, min_file_offset, end_offset);
- if (ret <= 0)
- return ret;
- first = file;
+ view->tail = file;
+ view->head = file;
for (seq = min_file_seq+1; seq <= max_file_seq; seq++) {
file = file->next;
@@ -192,40 +189,57 @@ mail_transaction_log_view_set(struct mai
/* missing files in the middle */
return 0;
}
-
+ view->head = file;
+ }
+
+ /* we have all of them. update refcounts. */
+ mail_transaction_log_view_unref_all(view);
+
+ /* reference all used files */
+ for (file = view->tail;; file = file->next) {
+ array_append(&view->file_refs, &file, 1);
+ file->refcount++;
+
+ if (file == view->head)
+ break;
+ }
+
+ /* Map the files only after we've found them all. Otherwise if we map
+ one file and then another file just happens to get rotated, we could
+ include both files in the view but skip the last transactions from
+ the first file.
+
+ We're mapping the files in reverse order so that _log_file_map()
+ can verify that prev_file_offset matches how far it actually managed
+ to sync the file. */
+ files = array_idx(&view->file_refs, 0);
+ for (i = array_count(&view->file_refs); i > 0; i--) {
+ file = files[i-1];
+ start_offset = file->hdr.file_seq == min_file_seq ?
+ min_file_offset : file->hdr.hdr_size;
end_offset = file->hdr.file_seq == max_file_seq ?
max_file_offset : (uoff_t)-1;
- ret = mail_transaction_log_file_map(file, file->hdr.hdr_size,
+ ret = mail_transaction_log_file_map(file, start_offset,
end_offset);
if (ret <= 0)
return ret;
}
+ i_assert(max_file_seq == (uint32_t)-1 ||
+ max_file_seq == view->head->hdr.file_seq);
i_assert(max_file_offset == (uoff_t)-1 ||
- max_file_offset <= file->sync_offset);
-
- /* we have all of them. update refcounts. */
- mail_transaction_log_view_unref_all(view);
-
- view->tail = first;
- view->head = view->log->head;
-
- /* reference all used files */
- for (file = view->tail; file != NULL; file = file->next) {
- array_append(&view->file_refs, &file, 1);
- file->refcount++;
- }
+ max_file_offset <= view->head->sync_offset);
view->prev_file_seq = 0;
view->prev_file_offset = 0;
- view->cur = first;
+ view->cur = view->tail;
view->cur_offset = min_file_offset;
view->min_file_seq = min_file_seq;
view->min_file_offset = min_file_offset;
view->max_file_seq = max_file_seq;
- view->max_file_offset = max_file_offset;
+ view->max_file_offset = I_MIN(max_file_offset, view->head->sync_offset);
view->type_mask = type_mask;
view->broken = FALSE;
More information about the dovecot-cvs
mailing list