dovecot-2.2: lib-index: Updated dovecot.index file only by recre...

dovecot at dovecot.org dovecot at dovecot.org
Fri May 4 00:49:42 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/4c996a5737b0
changeset: 14230:4c996a5737b0
user:      Timo Sirainen <tss at iki.fi>
date:      Fri May 04 00:41:51 2012 +0300
description:
lib-index: Updated dovecot.index file only by recreating it, never write to it directly.
This is safer, and nowadays there shouldn't be much of a performance loss
with it either, since dovecot.index isn't updated very often.

This also allows removing all locking from dovecot.index file, although for
now we'll keep it in case old Dovecot versions are simultaneously writing to
the index.

diffstat:

 src/lib-index/mail-index-fsck.c          |    3 +-
 src/lib-index/mail-index-map.c           |    9 +-
 src/lib-index/mail-index-modseq.c        |    5 +-
 src/lib-index/mail-index-private.h       |   10 +-
 src/lib-index/mail-index-sync-ext.c      |   11 +-
 src/lib-index/mail-index-sync-keywords.c |    4 +-
 src/lib-index/mail-index-sync-private.h  |    2 -
 src/lib-index/mail-index-sync-update.c   |   23 +----
 src/lib-index/mail-index-write.c         |  143 +-----------------------------
 src/lib-index/test-mail-index-sync-ext.c |    3 -
 10 files changed, 24 insertions(+), 189 deletions(-)

diffs (truncated from 422 to 300 lines):

diff -r 96e3b3ef59dc -r 4c996a5737b0 src/lib-index/mail-index-fsck.c
--- a/src/lib-index/mail-index-fsck.c	Sun Mar 11 12:42:53 2012 +0200
+++ b/src/lib-index/mail-index-fsck.c	Fri May 04 00:41:51 2012 +0300
@@ -454,8 +454,7 @@
 		mail_index_fsck_map(index, map);
 	} T_END;
 
-	map->write_base_header = TRUE;
-	map->write_atomic = TRUE;
+	map->header_changed = TRUE;
 	mail_index_write(index, FALSE);
 
 	if (!orig_locked)
diff -r 96e3b3ef59dc -r 4c996a5737b0 src/lib-index/mail-index-map.c
--- a/src/lib-index/mail-index-map.c	Sun Mar 11 12:42:53 2012 +0200
+++ b/src/lib-index/mail-index-map.c	Fri May 04 00:41:51 2012 +0300
@@ -335,10 +335,7 @@
 	dest->records = buffer_get_modifiable_data(dest->buffer, NULL);
 	dest->records_count = src->records_count;
 
-	/* if the map is ever written back to disk, we need to keep track of
-	   what has changed. */
-	dest->write_seq_first = src->write_seq_first;
-	dest->write_seq_last = src->write_seq_last;
+	dest->records_changed = src->records_changed;
 }
 
 static void mail_index_map_copy_header(struct mail_index_map *dest,
@@ -401,9 +398,7 @@
 
 	mail_index_map_copy_header(mem_map, map);
 
-	mem_map->write_atomic = map->write_atomic;
-	mem_map->write_base_header = map->write_base_header;
-	mem_map->write_ext_header = map->write_ext_header;
+	mem_map->header_changed = map->header_changed;
 
 	/* copy extensions */
 	if (array_is_created(&map->ext_id_map)) {
diff -r 96e3b3ef59dc -r 4c996a5737b0 src/lib-index/mail-index-modseq.c
--- a/src/lib-index/mail-index-modseq.c	Sun Mar 11 12:42:53 2012 +0200
+++ b/src/lib-index/mail-index-modseq.c	Fri May 04 00:41:51 2012 +0300
@@ -458,8 +458,7 @@
 			} T_END;
 		}
 	}
-	mail_index_sync_write_seq_update(ctx->sync_map_ctx, 1,
-					 map->hdr.messages_count);
+	map->rec_map->records_changed = TRUE;
 	mail_transaction_log_view_close(&ctx->log_view);
 }
 
@@ -510,7 +509,7 @@
 		buffer_write(map->hdr_copy_buf, ext->hdr_offset,
 			     &new_modseq_hdr, sizeof(new_modseq_hdr));
 		map->hdr_base = map->hdr_copy_buf->data;
-		map->write_ext_header = TRUE;
+		map->header_changed = TRUE;
 	}
 }
 
diff -r 96e3b3ef59dc -r 4c996a5737b0 src/lib-index/mail-index-private.h
--- a/src/lib-index/mail-index-private.h	Sun Mar 11 12:42:53 2012 +0200
+++ b/src/lib-index/mail-index-private.h	Fri May 04 00:41:51 2012 +0300
@@ -129,10 +129,8 @@
 	struct mail_index_map_modseq *modseq;
 	uint32_t last_appended_uid;
 
-	/* If this mapping is written to disk and write_atomic=FALSE,
-	   write_seq_* specify the message sequence range that needs to be
-	   written. */
-	uint32_t write_seq_first, write_seq_last;
+	/* The records have changed since it was read */
+	bool records_changed;
 };
 
 struct mail_index_map {
@@ -151,9 +149,7 @@
 
 	struct mail_index_record_map *rec_map;
 
-	unsigned int write_base_header:1;
-	unsigned int write_ext_header:1;
-	unsigned int write_atomic:1; /* write to a new file and rename() */
+	unsigned int header_changed:1;
 };
 
 struct mail_index_module_register {
diff -r 96e3b3ef59dc -r 4c996a5737b0 src/lib-index/mail-index-sync-ext.c
--- a/src/lib-index/mail-index-sync-ext.c	Sun Mar 11 12:42:53 2012 +0200
+++ b/src/lib-index/mail-index-sync-ext.c	Fri May 04 00:41:51 2012 +0300
@@ -310,7 +310,7 @@
 		i_assert((map->hdr_copy_buf->used % sizeof(uint64_t)) == 0);
 		map->hdr_base = map->hdr_copy_buf->data;
 		map->hdr.header_size = map->hdr_copy_buf->used;
-		map->write_base_header = map->write_ext_header = TRUE;
+		map->header_changed = TRUE;
 
 		ext_hdr = get_ext_header(map, ext);
 		ext_hdr->reset_id = ext->reset_id;
@@ -570,8 +570,7 @@
 		memset(PTR_OFFSET(rec, ext->record_offset), 0,
 		       ext->record_size);
 	}
-	map->rec_map->write_seq_first = 1;
-	map->rec_map->write_seq_last = view->map->rec_map->records_count;
+	map->rec_map->records_changed = TRUE;
 }
 
 int mail_index_sync_ext_reset(struct mail_index_sync_map_ctx *ctx,
@@ -635,7 +634,7 @@
 	if (ext->index_idx == ctx->view->index->modseq_ext_id)
 		mail_index_modseq_hdr_update(ctx->modseq_ctx);
 
-	map->write_ext_header = TRUE;
+	map->header_changed = TRUE;
 	return 1;
 }
 
@@ -684,7 +683,7 @@
 			return ret;
 	}
 
-	mail_index_sync_write_seq_update(ctx, seq, seq);
+	view->map->rec_map->records_changed = TRUE;
 
 	/* @UNSAFE */
 	memcpy(old_data, u + 1, ext->record_size);
@@ -786,6 +785,6 @@
 		return -1;
 	}
 
-	mail_index_sync_write_seq_update(ctx, seq, seq);
+	view->map->rec_map->records_changed = TRUE;
 	return 1;
 }
diff -r 96e3b3ef59dc -r 4c996a5737b0 src/lib-index/mail-index-sync-keywords.c
--- a/src/lib-index/mail-index-sync-keywords.c	Sun Mar 11 12:42:53 2012 +0200
+++ b/src/lib-index/mail-index-sync-keywords.c	Fri May 04 00:41:51 2012 +0300
@@ -215,7 +215,7 @@
 	if (!mail_index_lookup_seq_range(view, uid1, uid2, &seq1, &seq2))
 		return 1;
 
-	mail_index_sync_write_seq_update(ctx, seq1, seq2);
+	view->map->rec_map->records_changed = TRUE;
 	mail_index_modseq_update_keyword(ctx->modseq_ctx, keyword_idx,
 					  seq1, seq2);
 
@@ -337,7 +337,7 @@
 						 &seq1, &seq2))
 			continue;
 
-		mail_index_sync_write_seq_update(ctx, seq1, seq2);
+		map->rec_map->records_changed = TRUE;
 		mail_index_modseq_reset_keywords(ctx->modseq_ctx, seq1, seq2);
 		for (seq1--; seq1 < seq2; seq1++) {
 			rec = MAIL_INDEX_MAP_IDX(map, seq1);
diff -r 96e3b3ef59dc -r 4c996a5737b0 src/lib-index/mail-index-sync-private.h
--- a/src/lib-index/mail-index-sync-private.h	Sun Mar 11 12:42:53 2012 +0200
+++ b/src/lib-index/mail-index-sync-private.h	Fri May 04 00:41:51 2012 +0300
@@ -60,8 +60,6 @@
 
 struct mail_index_map *
 mail_index_sync_get_atomic_map(struct mail_index_sync_map_ctx *ctx);
-void mail_index_sync_write_seq_update(struct mail_index_sync_map_ctx *ctx,
-				      uint32_t seq1, uint32_t seq2);
 
 void mail_index_sync_init_expunge_handlers(struct mail_index_sync_map_ctx *ctx);
 void
diff -r 96e3b3ef59dc -r 4c996a5737b0 src/lib-index/mail-index-sync-update.c
--- a/src/lib-index/mail-index-sync-update.c	Sun Mar 11 12:42:53 2012 +0200
+++ b/src/lib-index/mail-index-sync-update.c	Fri May 04 00:41:51 2012 +0300
@@ -95,7 +95,6 @@
 	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;
 }
 
@@ -344,18 +343,6 @@
 	return 1;
 }
 
-void mail_index_sync_write_seq_update(struct mail_index_sync_map_ctx *ctx,
-				      uint32_t seq1, uint32_t seq2)
-{
-	struct mail_index_map *map = ctx->view->map;
-
-	if (map->rec_map->write_seq_first == 0 ||
-	    map->rec_map->write_seq_first > seq1)
-		map->rec_map->write_seq_first = seq1;
-	if (map->rec_map->write_seq_last < seq2)
-		map->rec_map->write_seq_last = seq2;
-}
-
 static int sync_append(const struct mail_index_record *rec,
 		       struct mail_index_sync_map_ctx *ctx)
 {
@@ -396,9 +383,7 @@
 		map->rec_map->last_appended_uid = rec->uid;
 		new_flags = rec->flags;
 
-		mail_index_sync_write_seq_update(ctx,
-						 map->rec_map->records_count,
-						 map->rec_map->records_count);
+		map->rec_map->records_changed = TRUE;
 		mail_index_modseq_append(ctx->modseq_ctx,
 					 map->rec_map->records_count);
 	}
@@ -426,7 +411,7 @@
 	if (!mail_index_lookup_seq_range(view, u->uid1, u->uid2, &seq1, &seq2))
 		return 1;
 
-	mail_index_sync_write_seq_update(ctx, seq1, seq2);
+	view->map->rec_map->records_changed = TRUE;
 	if (!MAIL_TRANSACTION_FLAG_UPDATE_IS_INTERNAL(u)) {
 		mail_index_modseq_update_flags(ctx->modseq_ctx,
 					       u->add_flags | u->remove_flags,
@@ -483,7 +468,7 @@
 
 	buffer_write(map->hdr_copy_buf, u->offset, u + 1, u->size);
 	map->hdr_base = map->hdr_copy_buf->data;
-	map->write_base_header = TRUE;
+	map->header_changed = TRUE;
 
 	/* @UNSAFE */
 	if ((uint32_t)(u->offset + u->size) <= sizeof(map->hdr)) {
@@ -979,7 +964,7 @@
 	had_dirty = (map->hdr.flags & MAIL_INDEX_HDR_FLAG_HAVE_DIRTY) != 0;
 	if (had_dirty) {
 		map->hdr.flags &= ~MAIL_INDEX_HDR_FLAG_HAVE_DIRTY;
-		map->write_base_header = TRUE;
+		map->header_changed = TRUE;
 	}
 
 	if (map->hdr_base != map->hdr_copy_buf->data) {
diff -r 96e3b3ef59dc -r 4c996a5737b0 src/lib-index/mail-index-write.c
--- a/src/lib-index/mail-index-write.c	Sun Mar 11 12:42:53 2012 +0200
+++ b/src/lib-index/mail-index-write.c	Fri May 04 00:41:51 2012 +0300
@@ -119,152 +119,21 @@
 	return ret;
 }
 
-static int mail_index_write_map_over(struct mail_index *index)
-{
-	struct mail_index_map *map = index->map;
-	struct mail_index_record_map *rec_map = map->rec_map;
-	unsigned int base_size;
-
-	if (MAIL_INDEX_IS_IN_MEMORY(index))
-		return 0;
-
-	/* write extended headers */
-	if (map->write_ext_header) {
-		base_size = map->hdr.base_header_size;
-		if (pwrite_full(index->fd,
-				CONST_PTR_OFFSET(map->hdr_base, base_size),
-				map->hdr.header_size - base_size,
-				base_size) < 0)
-			return -1;
-	}
-
-	/* write records. */
-	if (rec_map->write_seq_first != 0) {
-		size_t rec_offset =
-			(rec_map->write_seq_first-1) * map->hdr.record_size;
-		size_t recs_size = map->hdr.record_size *
-			(rec_map->write_seq_last -
-			 rec_map->write_seq_first + 1);
-
-		if (pwrite_full(index->fd,
-				CONST_PTR_OFFSET(rec_map->records, rec_offset),
-				recs_size,
-				map->hdr.header_size + rec_offset) < 0)
-			return -1;
-	}
-
-	/* Write base header last. If we happen to crash in above pwrites, it
-	   doesn't matter because we haven't yet written log file offsets, so
-	   all the changes will be re-applied and the header/data state will
-	   stay valid.
-
-	   The base header changes practically always, so
-	   map->write_base_header might not be TRUE here in all situations.
-	   It's used only to figure out if we want to write the map at all. */
-	base_size = I_MIN(map->hdr.base_header_size, sizeof(map->hdr));
-	if (pwrite_full(index->fd, &map->hdr, base_size, 0) < 0)
-		return -1;
-	return 0;
-}
-
-static bool mail_index_has_last_changed(struct mail_index *index)
-{
-	struct mail_index_header hdr;
-	int ret;
-
-	if ((ret = pread_full(index->fd, &hdr, sizeof(hdr), 0)) <= 0) {
-		if (ret < 0 && errno != ESTALE)
-			mail_index_set_syscall_error(index, "pread_full()");


More information about the dovecot-cvs mailing list