changeset 5820:e59892590a02 HEAD

Handle losing index file better. Handle fsck better.
author Timo Sirainen <tss@iki.fi>
date Thu, 28 Jun 2007 01:48:59 +0300
parents 4ea31bf18a56
children b564f45c4d7b
files src/lib-index/mail-index-fsck.c src/lib-index/mail-index-private.h src/lib-index/mail-index-sync-private.h src/lib-index/mail-index-sync-update.c src/lib-index/mail-index-sync.c src/lib-index/mail-index-view-sync.c src/lib-index/mail-index-write.c src/lib-index/mail-index.c
diffstat 8 files changed, 48 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-index-fsck.c	Thu Jun 28 01:03:18 2007 +0300
+++ b/src/lib-index/mail-index-fsck.c	Thu Jun 28 01:48:59 2007 +0300
@@ -47,6 +47,11 @@
 					      &file_offset);
 	}
 
+	/* Remember the log head position. If we go back in the index's head
+	   offset, ignore errors in the log up to this offset. */
+	index->fsck_log_head_file_seq = file_seq;
+	index->fsck_log_head_file_offset = file_offset;
+
 	/* locking already does the most important sanity checks for header */
 	hdr = map->hdr;
 
@@ -55,8 +60,7 @@
 
 	hdr.flags &= ~MAIL_INDEX_HDR_FLAG_FSCK;
 
-	if (hdr.log_file_seq != file_seq) {
-		hdr.log_file_seq = file_seq;
+	if (hdr.log_file_seq < file_seq) {
 		hdr.log_file_head_offset = hdr.log_file_tail_offset =
 			sizeof(struct mail_transaction_log_header);
 	} else {
@@ -65,6 +69,7 @@
 		if (hdr.log_file_tail_offset > hdr.log_file_head_offset)
 			hdr.log_file_tail_offset = hdr.log_file_head_offset;
 	}
+	hdr.log_file_seq = file_seq;
 
 	hdr.messages_count = 0;
 	hdr.recent_messages_count = 0;
--- a/src/lib-index/mail-index-private.h	Thu Jun 28 01:03:18 2007 +0300
+++ b/src/lib-index/mail-index-private.h	Thu Jun 28 01:48:59 2007 +0300
@@ -161,7 +161,7 @@
 	struct mail_index_map *map;
 	uint32_t indexid;
 	/* last_read_log_file_* contains the seq/offsets we last read from
-	   the main index file's headers. these are used ro figure out when
+	   the main index file's headers. these are used to figure out when
 	   the main index file should be updated, and if we can update it
 	   by writing on top of it or if we need to recreate it. */
 	uint32_t last_read_log_file_seq;
@@ -169,6 +169,10 @@
 	uint32_t last_read_log_file_tail_offset;
 	struct stat last_read_stat;
 
+	/* transaction log head seq/offset when we last fscked */
+	uint32_t fsck_log_head_file_seq;
+	uoff_t fsck_log_head_file_offset;
+
 	int lock_type, shared_lock_count, excl_lock_count;
 	unsigned int lock_id;
 	enum file_lock_method lock_method;
@@ -281,8 +285,6 @@
 void mail_index_view_transaction_ref(struct mail_index_view *view);
 void mail_index_view_transaction_unref(struct mail_index_view *view);
 
-void mail_index_set_inconsistent(struct mail_index *index);
-
 int mail_index_set_error(struct mail_index *index, const char *fmt, ...)
 	__attr_format__(2, 3);
 /* "%s failed with index file %s: %m" */
--- a/src/lib-index/mail-index-sync-private.h	Thu Jun 28 01:03:18 2007 +0300
+++ b/src/lib-index/mail-index-sync-private.h	Thu Jun 28 01:48:59 2007 +0300
@@ -38,6 +38,7 @@
 	unsigned int expunge_handlers_set:1;
 	unsigned int expunge_handlers_used:1;
 	unsigned int cur_ext_ignore:1;
+	unsigned int errors:1;
 };
 
 extern struct mail_transaction_map_functions mail_index_map_sync_funcs;
--- a/src/lib-index/mail-index-sync-update.c	Thu Jun 28 01:03:18 2007 +0300
+++ b/src/lib-index/mail-index-sync-update.c	Thu Jun 28 01:48:59 2007 +0300
@@ -814,6 +814,10 @@
 
 	/*FIXME:if (mail_index_map_msync(index, map) < 0)
 		ret = -1;*/
+	if (sync_map_ctx.errors) {
+		/* avoid the same syncing errors the next time */
+		mail_index_write(index, FALSE);
+	}
 
 	/* restore refcount before closing the view. this is necessary also
 	   if map got cloned, because view closing would otherwise destroy it */
--- a/src/lib-index/mail-index-sync.c	Thu Jun 28 01:03:18 2007 +0300
+++ b/src/lib-index/mail-index-sync.c	Thu Jun 28 01:48:59 2007 +0300
@@ -321,7 +321,6 @@
 		mail_index_set_error(view->index,
 			"Unexpected transaction log desync with index %s",
 			view->index->filepath);
-		mail_index_set_inconsistent(view->index);
 		return -1;
 	}
 	return 0;
@@ -396,8 +395,17 @@
 	   the end of the transaction log */
 	if (mail_index_sync_set_log_view(ctx->view, hdr->log_file_seq,
 					 hdr->log_file_tail_offset) < 0) {
-                mail_index_sync_rollback(&ctx);
-		return -1;
+		/* if a log file is missing, there's nothing we can do except
+		   to skip over it. fix the problem with fsck and try again. */
+		mail_index_sync_rollback(&ctx);
+		if (mail_index_fsck(index) <= 0) {
+			mail_index_unlock(index, lock_id);
+			mail_transaction_log_sync_unlock(index->log);
+			return -1;
+		}
+		return mail_index_sync_begin(index, ctx_r, view_r, trans_r,
+					     log_file_seq, log_file_offset,
+					     flags);
 	}
 
 	/* we need to have all the transactions sorted to optimize
@@ -690,9 +698,18 @@
 	uint32_t seq;
 	uoff_t offset;
 
+	ctx->errors = TRUE;
+
 	mail_transaction_log_view_get_prev_pos(ctx->view->log_view,
 					       &seq, &offset);
 
+	if (seq < ctx->view->index->fsck_log_head_file_seq ||
+	    (seq == ctx->view->index->fsck_log_head_file_seq &&
+	     offset < ctx->view->index->fsck_log_head_file_offset)) {
+		/* be silent */
+		return;
+	}
+
 	va_start(va, fmt);
 	t_push();
 	mail_index_set_error(ctx->view->index,
--- a/src/lib-index/mail-index-view-sync.c	Thu Jun 28 01:03:18 2007 +0300
+++ b/src/lib-index/mail-index-view-sync.c	Thu Jun 28 01:48:59 2007 +0300
@@ -104,7 +104,7 @@
 			mail_index_set_error(view->index,
 				"Transaction log got desynced for index %s",
 				view->index->filepath);
-			mail_index_set_inconsistent(view->index);
+			view->inconsistent = TRUE;
 		}
 		return -1;
 	}
--- a/src/lib-index/mail-index-write.c	Thu Jun 28 01:03:18 2007 +0300
+++ b/src/lib-index/mail-index-write.c	Thu Jun 28 01:48:59 2007 +0300
@@ -194,7 +194,10 @@
 	} else {
 		if (mail_index_write_map_over(index) < 0) {
 			mail_index_set_syscall_error(index, "pwrite_full()");
-			mail_index_set_inconsistent(index);
+			/* hopefully didn't break badly */
+			mail_index_unlock(index, lock_id);
+			mail_index_move_to_memory(index);
+			return;
 		}
 		mail_index_unlock(index, lock_id);
 	}
--- a/src/lib-index/mail-index.c	Thu Jun 28 01:03:18 2007 +0300
+++ b/src/lib-index/mail-index.c	Thu Jun 28 01:48:59 2007 +0300
@@ -364,9 +364,11 @@
 
 	if (ret == 0) {
 		/* it's corrupted - recreate it */
-		if (close(index->fd) < 0)
-			mail_index_set_syscall_error(index, "close()");
-		index->fd = -1;
+		if (index->fd != -1) {
+			if (close(index->fd) < 0)
+				mail_index_set_syscall_error(index, "close()");
+			index->fd = -1;
+		}
 	}
 	return ret;
 }
@@ -618,11 +620,6 @@
 	return -1;
 }
 
-void mail_index_set_inconsistent(struct mail_index *index)
-{
-	index->indexid = 0;
-}
-
 int mail_index_move_to_memory(struct mail_index *index)
 {
 	struct mail_index_map *map;
@@ -667,7 +664,7 @@
 
 void mail_index_mark_corrupted(struct mail_index *index)
 {
-	mail_index_set_inconsistent(index);
+	index->indexid = 0;
 
 	index->map->hdr.flags |= MAIL_INDEX_HDR_FLAG_CORRUPTED;
 	if (unlink(index->filepath) < 0 && errno != ENOENT && errno != ESTALE)