changeset 20721:6e339cbdeaf5

lib-index: Fixed mail_index_modseq_get_next_log_offset() when accessing .log.2 file->sync_offset was set only after header, so sync_highest_modseq was also same as initial_modseq. The previous code then just returned offset pointing to sync_offset, which was too early.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Fri, 09 Sep 2016 00:59:53 +0300
parents 866d29e08e70
children bf8fbf7fcc6a
files src/lib-index/mail-transaction-log-file.c
diffstat 1 files changed, 11 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-transaction-log-file.c	Thu Sep 08 23:54:22 2016 +0300
+++ b/src/lib-index/mail-transaction-log-file.c	Fri Sep 09 00:59:53 2016 +0300
@@ -1207,7 +1207,7 @@
 	uint64_t cur_modseq;
 	int ret;
 
-	if (modseq >= file->sync_highest_modseq) {
+	if (modseq == file->sync_highest_modseq) {
 		*next_offset_r = file->sync_offset;
 		return 0;
 	}
@@ -1231,8 +1231,10 @@
 		cur_modseq = cache->highest_modseq;
 	}
 
-	ret = mail_transaction_log_file_map(file, cur_offset,
-					    file->sync_offset);
+	/* make sure we've read until end of file. this is especially important
+	   with non-head logs which might only have been opened without being
+	   synced. */
+	ret = mail_transaction_log_file_map(file, cur_offset, (uoff_t)-1);
 	if (ret <= 0) {
 		if (ret < 0)
 			return -1;
@@ -1242,6 +1244,12 @@
 		return -1;
 	}
 
+	/* check sync_highest_modseq again in case sync_offset was updated */
+	if (modseq >= file->sync_highest_modseq) {
+		*next_offset_r = file->sync_offset;
+		return 0;
+	}
+
 	i_assert(cur_offset >= file->buffer_offset);
 	while (cur_offset < file->sync_offset) {
 		if (log_get_synced_record(file, &cur_offset, &hdr) < 0)