changeset 8131:32a045eaf6b6 HEAD

Fixed crashes related to struct mail_index_map_modseq handling.
author Timo Sirainen <tss@iki.fi>
date Sun, 31 Aug 2008 11:02:13 +0300
parents b97c3be33b04
children 66dd5f452d32
files src/lib-index/mail-index-map.c src/lib-index/mail-index-modseq.c src/lib-index/mail-index-modseq.h src/lib-index/mail-index-sync-update.c src/lib-index/mail-index-view-sync.c
diffstat 5 files changed, 50 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-index-map.c	Sun Aug 31 10:22:10 2008 +0300
+++ b/src/lib-index/mail-index-map.c	Sun Aug 31 11:02:13 2008 +0300
@@ -978,7 +978,7 @@
 	}
 	array_free(&rec_map->maps);
 	if (rec_map->modseq != NULL)
-		mail_index_map_modseq_free(rec_map->modseq);
+		mail_index_map_modseq_free(&rec_map->modseq);
 	i_free(rec_map);
 }
 
@@ -991,8 +991,10 @@
 	for (i = 0; i < count; i++) {
 		if (maps[i] == map) {
 			array_delete(&map->rec_map->maps, i, 1);
-			if (i == 0 && count == 1)
+			if (i == 0 && count == 1) {
 				mail_index_record_map_free(map, map->rec_map);
+				map->rec_map = NULL;
+			}
 			return;
 		}
 	}
@@ -1145,6 +1147,10 @@
 	} else {
 		new_map = map->rec_map;
 	}
+	if (map->rec_map->modseq != NULL) {
+		new_map->modseq =
+			mail_index_map_modseq_clone(map->rec_map->modseq);
+	}
 
 	if (new_map->records_count != map->hdr.messages_count) {
 		new_map->records_count = map->hdr.messages_count;
@@ -1168,8 +1174,13 @@
 
 	i_assert(map->rec_map->lock_id != 0);
 
-	new_map = array_count(&map->rec_map->maps) == 1 ? map->rec_map :
-		mail_index_record_map_alloc(map);
+	if (array_count(&map->rec_map->maps) == 1)
+		new_map = map->rec_map;
+	else {
+		new_map = mail_index_record_map_alloc(map);
+		new_map->modseq = map->rec_map->modseq == NULL ? NULL :
+			mail_index_map_modseq_clone(map->rec_map->modseq);
+	}
 
 	mail_index_map_copy_records(new_map, map->rec_map,
 				    map->hdr.record_size);
--- a/src/lib-index/mail-index-modseq.c	Sun Aug 31 10:22:10 2008 +0300
+++ b/src/lib-index/mail-index-modseq.c	Sun Aug 31 11:02:13 2008 +0300
@@ -494,11 +494,18 @@
 	struct mail_index_modseq_sync *ctx = *_ctx;
 
 	*_ctx = NULL;
-	if (ctx->mmap != NULL)
+	if (ctx->mmap != NULL) {
+		i_assert(ctx->mmap == ctx->view->map->rec_map->modseq);
 		mail_index_modseq_update_header(ctx);
+	}
 	i_free(ctx);
 }
 
+void mail_index_modseq_sync_map_replaced(struct mail_index_modseq_sync *ctx)
+{
+	ctx->mmap = mail_index_map_modseq(ctx->view);
+}
+
 void mail_index_modseq_hdr_update(struct mail_index_modseq_sync *ctx)
 {
 	if (ctx->mmap == NULL) {
@@ -601,11 +608,27 @@
 		modseqs_idx_update(ctx, i, seq1, seq2);
 }
 
-void mail_index_map_modseq_free(struct mail_index_map_modseq *mmap)
+struct mail_index_map_modseq *
+mail_index_map_modseq_clone(const struct mail_index_map_modseq *mmap)
 {
+	struct mail_index_map_modseq *new_mmap;
+
+	new_mmap = i_new(struct mail_index_map_modseq, 1);
+	i_array_init(&new_mmap->metadata_modseqs,
+		     array_count(&mmap->metadata_modseqs) + 16);
+	array_append_array(&new_mmap->metadata_modseqs,
+			   &mmap->metadata_modseqs);
+	return new_mmap;
+}
+
+void mail_index_map_modseq_free(struct mail_index_map_modseq **_mmap)
+{
+	struct mail_index_map_modseq *mmap = *_mmap;
 	struct metadata_modseqs *metadata;
 	unsigned int i, count;
 
+	*_mmap = NULL;
+
 	metadata = array_get_modifiable(&mmap->metadata_modseqs, &count);
 	for (i = 0; i < count; i++) {
 		if (array_is_created(&metadata[i].modseqs))
--- a/src/lib-index/mail-index-modseq.h	Sun Aug 31 10:22:10 2008 +0300
+++ b/src/lib-index/mail-index-modseq.h	Sun Aug 31 11:02:13 2008 +0300
@@ -40,6 +40,7 @@
 mail_index_modseq_sync_begin(struct mail_index_sync_map_ctx *sync_map_ctx);
 void mail_index_modseq_sync_end(struct mail_index_modseq_sync **ctx);
 
+void mail_index_modseq_sync_map_replaced(struct mail_index_modseq_sync *ctx);
 void mail_index_modseq_hdr_update(struct mail_index_modseq_sync *ctx);
 void mail_index_modseq_append(struct mail_index_modseq_sync *ctx, uint32_t seq);
 void mail_index_modseq_expunge(struct mail_index_modseq_sync *ctx,
@@ -53,7 +54,9 @@
 void mail_index_modseq_reset_keywords(struct mail_index_modseq_sync *ctx,
 				      uint32_t seq1, uint32_t seq2);
 
-void mail_index_map_modseq_free(struct mail_index_map_modseq *mmap);
+struct mail_index_map_modseq *
+mail_index_map_modseq_clone(const struct mail_index_map_modseq *mmap);
+void mail_index_map_modseq_free(struct mail_index_map_modseq **mmap);
 
 bool mail_index_modseq_get_next_log_offset(struct mail_index_view *view,
 					   uint64_t modseq, uint32_t *log_seq_r,
--- a/src/lib-index/mail-index-sync-update.c	Sun Aug 31 10:22:10 2008 +0300
+++ b/src/lib-index/mail-index-sync-update.c	Sun Aug 31 11:02:13 2008 +0300
@@ -65,6 +65,8 @@
 
 	if (ctx->type != MAIL_INDEX_SYNC_HANDLER_VIEW)
 		view->index->map = map;
+
+	mail_index_modseq_sync_map_replaced(ctx->modseq_ctx);
 }
 
 static void
@@ -82,6 +84,7 @@
 
 	if (!MAIL_INDEX_MAP_IS_IN_MEMORY(ctx->view->map))
 		mail_index_map_move_to_memory(ctx->view->map);
+	mail_index_modseq_sync_map_replaced(ctx->modseq_ctx);
 }
 
 struct mail_index_map *
@@ -89,6 +92,7 @@
 {
 	mail_index_sync_move_to_private_memory(ctx);
 	mail_index_record_map_move_to_private(ctx->view->map);
+	mail_index_modseq_sync_map_replaced(ctx->modseq_ctx);
 	ctx->view->map->write_atomic = TRUE;
 	return ctx->view->map;
 }
--- a/src/lib-index/mail-index-view-sync.c	Sun Aug 31 10:22:10 2008 +0300
+++ b/src/lib-index/mail-index-view-sync.c	Sun Aug 31 11:02:13 2008 +0300
@@ -559,8 +559,6 @@
 		return ctx;
 	}
 
-	mail_index_sync_map_init(&ctx->sync_map_ctx, view,
-				 MAIL_INDEX_SYNC_HANDLER_VIEW);
 	if (ret == 0) {
 		ctx->log_was_lost = TRUE;
 		if (!sync_expunges)
@@ -629,6 +627,8 @@
 			ctx->sync_new_map->refcount++;
 		}
 	}
+	mail_index_sync_map_init(&ctx->sync_map_ctx, view,
+				 MAIL_INDEX_SYNC_HANDLER_VIEW);
 
 #ifdef DEBUG
 	mail_index_map_check(view->map);