changeset 5255:005d73928f8f HEAD

Don't set log sync position right after extension introduction, unless it's at the end of the file. This should fix some "Extension reset without intro prefix" errors.
author Timo Sirainen <tss@iki.fi>
date Fri, 09 Mar 2007 23:17:10 +0200
parents 46e3249aa15b
children d66f62eb69b3
files src/lib-index/mail-index-sync-private.h src/lib-index/mail-index-sync-update.c
diffstat 2 files changed, 31 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-index-sync-private.h	Fri Mar 09 22:22:50 2007 +0200
+++ b/src/lib-index/mail-index-sync-private.h	Fri Mar 09 23:17:10 2007 +0200
@@ -46,6 +46,10 @@
 	struct mail_index_view *view;
 	uint32_t cur_ext_id;
 
+	uint32_t ext_intro_seq;
+	uoff_t ext_intro_offset;
+	uint32_t ext_intro_size;
+
 	ARRAY_DEFINE(expunge_handlers, struct mail_index_expunge_handler);
 	ARRAY_DEFINE(extra_contexts, void *);
 
--- a/src/lib-index/mail-index-sync-update.c	Fri Mar 09 22:22:50 2007 +0200
+++ b/src/lib-index/mail-index-sync-update.c	Fri Mar 09 23:17:10 2007 +0200
@@ -14,7 +14,7 @@
 
 static void
 mail_index_sync_update_log_offset(struct mail_index_sync_map_ctx *ctx,
-				  struct mail_index_map *map)
+				  struct mail_index_map *map, bool eol)
 {
 	uint32_t prev_seq;
 	uoff_t prev_offset;
@@ -22,6 +22,19 @@
 	mail_transaction_log_view_get_prev_pos(ctx->view->log_view,
 					       &prev_seq, &prev_offset);
 
+	if (prev_offset == ctx->ext_intro_offset + ctx->ext_intro_size &&
+	    prev_seq == ctx->ext_intro_seq && !eol) {
+		/* previous transaction was an extension introduction.
+		   we probably came here from mail_index_sync_ext_reset().
+		   if there are any more views which want to continue syncing
+		   it needs the intro. so back up a bit more.
+
+		   don't do this in case the last transaction in the log is
+		   the extension intro, so we don't keep trying to sync it
+		   over and over again. */
+		prev_offset = ctx->ext_intro_offset;
+	}
+
 	if (!ctx->sync_only_external)
 		map->hdr.log_file_int_offset = prev_offset;
 	else if (map->hdr.log_file_seq != prev_seq && map == ctx->view->map) {
@@ -94,7 +107,7 @@
 	/* some views may still use the same mapping, and since we could have
 	   already updated the records, make sure we leave the header in a
 	   valid state as well */
-	mail_index_sync_update_log_offset(ctx, old_map);
+	mail_index_sync_update_log_offset(ctx, old_map, FALSE);
 	(void)mail_index_map_msync(view->index, old_map);
 	mail_index_unmap(view->index, &old_map);
 
@@ -613,6 +626,14 @@
 	case MAIL_TRANSACTION_EXT_INTRO: {
 		const struct mail_transaction_ext_intro *rec = data;
 		unsigned int i;
+		uint32_t prev_seq;
+		uoff_t prev_offset;
+
+		mail_transaction_log_view_get_prev_pos(ctx->view->log_view,
+						       &prev_seq, &prev_offset);
+		ctx->ext_intro_seq = prev_seq;
+		ctx->ext_intro_offset = prev_offset;
+		ctx->ext_intro_size = hdr->size + sizeof(*hdr);
 
 		for (i = 0; i < hdr->size; ) {
 			if (i + sizeof(*rec) > hdr->size) {
@@ -851,8 +872,10 @@
 		map = NULL;
 	}
 
-	if (ret == 0)
-		mail_index_sync_update_log_offset(&sync_map_ctx, view->map);
+	if (ret == 0) {
+		mail_index_sync_update_log_offset(&sync_map_ctx, view->map,
+						  TRUE);
+	}
 	mail_index_sync_map_deinit(&sync_map_ctx);
 
 	index->sync_update = FALSE;