[dovecot-cvs] dovecot/src/lib-index mail-index-lock.c, 1.10, 1.11 mail-index-private.h, 1.10, 1.11 mail-index-reset.c, 1.2, 1.3 mail-index-view.c, 1.5, 1.6 mail-index.c, 1.113, 1.114 mail-transaction-log-view.c, 1.7, 1.8 mail-transaction-log.c, 1.13, 1.14 mail-transaction-log.h, 1.4, 1.5

cras at procontrol.fi cras at procontrol.fi
Sat May 1 19:08:17 EEST 2004


Update of /home/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv20041/lib-index

Modified Files:
	mail-index-lock.c mail-index-private.h mail-index-reset.c 
	mail-index-view.c mail-index.c mail-transaction-log-view.c 
	mail-transaction-log.c mail-transaction-log.h 
Log Message:
handle losing index file



Index: mail-index-lock.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-lock.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- mail-index-lock.c	1 May 2004 14:30:37 -0000	1.10
+++ mail-index-lock.c	1 May 2004 16:08:15 -0000	1.11
@@ -100,8 +100,15 @@
 
 	if (fstat(index->fd, &st1) < 0)
 		return mail_index_set_syscall_error(index, "fstat()");
-	if (stat(index->filepath, &st2) < 0)
-		return mail_index_set_syscall_error(index, "stat()");
+	if (stat(index->filepath, &st2) < 0) {
+		mail_index_set_syscall_error(index, "stat()");
+		if (errno != ENOENT)
+			return -1;
+
+		/* lost it? recreate */
+		(void)mail_index_reset(index);
+		return -1;
+	}
 
 	if (st1.st_ino != st2.st_ino ||
 	    !CMP_DEV_T(st1.st_dev, st2.st_dev)) {

Index: mail-index-private.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-private.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- mail-index-private.h	1 May 2004 14:30:37 -0000	1.10
+++ mail-index-private.h	1 May 2004 16:08:15 -0000	1.11
@@ -87,7 +87,6 @@
 int mail_index_write_header(struct mail_index *index,
 			    const struct mail_index_header *hdr);
 
-int mail_index_create(struct mail_index *index, struct mail_index_header *hdr);
 int mail_index_try_open_only(struct mail_index *index);
 int mail_index_try_open(struct mail_index *index, unsigned int *lock_id_r);
 int mail_index_create_tmp_file(struct mail_index *index, const char **path_r);
@@ -129,7 +128,6 @@
 			    const void *data, size_t *data_offset);
 
 void mail_index_set_inconsistent(struct mail_index *index);
-int mail_index_mark_corrupted(struct mail_index *index);
 
 int mail_index_set_error(struct mail_index *index, const char *fmt, ...)
 	__attr_format__(2, 3);

Index: mail-index-reset.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-reset.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- mail-index-reset.c	28 Apr 2004 00:21:00 -0000	1.2
+++ mail-index-reset.c	1 May 2004 16:08:15 -0000	1.3
@@ -6,28 +6,60 @@
 #include "mail-index-private.h"
 #include "mail-transaction-log.h"
 
-int mail_index_reset(struct mail_index *index)
+static int mail_index_mark_corrupted(struct mail_index *index)
 {
 	struct mail_index_header hdr;
 
-	if (mail_index_mark_corrupted(index) < 0)
+	if (index->readonly)
+		return 0;
+
+	/* make sure we can write the header */
+	if (!MAIL_INDEX_MAP_IS_IN_MEMORY(index->map)) {
+		if (mprotect(index->map->mmap_base, sizeof(hdr),
+			     PROT_READ | PROT_WRITE) < 0) {
+			mail_index_set_syscall_error(index, "mprotect()");
+			return -1;
+		}
+	}
+
+	hdr = *index->hdr;
+	hdr.flags |= MAIL_INDEX_HDR_FLAG_CORRUPTED;
+	if (mail_index_write_header(index, &hdr) < 0)
 		return -1;
 
+	if (fsync(index->fd) < 0)
+		return mail_index_set_syscall_error(index, "fsync()");
+
+	mail_index_set_inconsistent(index);
+	return 0;
+}
+
+int mail_index_reset(struct mail_index *index)
+{
+	struct mail_index_header hdr;
+	uint32_t file_seq;
+	uoff_t file_offset;
+	int log_locked;
+
 	mail_index_header_init(&hdr);
 	if (hdr.indexid == index->indexid)
 		hdr.indexid++;
 
-	// FIXME: close it? ..
-	if (mail_index_create(index, &hdr) < 0)
+	if (mail_index_mark_corrupted(index) < 0)
 		return -1;
 
-	/* reopen transaction log - FIXME: doesn't work, we have log views
-	   open.. */
-        mail_transaction_log_close(index->log);
-	index->log = mail_transaction_log_open_or_create(index);
-	if (index->log == NULL) {
-		/* FIXME: creates potential crashes.. */
+	log_locked = index->log_locked;
+	if (log_locked)
+                mail_transaction_log_sync_unlock(index->log);
+        mail_index_close(index);
+
+	if (mail_index_open(index, MAIL_INDEX_OPEN_FLAG_CREATE) < 0)
 		return -1;
+
+	if (log_locked) {
+		if (mail_transaction_log_sync_lock(index->log,
+						   &file_seq, &file_offset) < 0)
+			return -1;
 	}
 
 	return 0;

Index: mail-index-view.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-view.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- mail-index-view.c	1 May 2004 14:30:37 -0000	1.5
+++ mail-index-view.c	1 May 2004 16:08:15 -0000	1.6
@@ -83,7 +83,7 @@
 
 int mail_index_view_lock(struct mail_index_view *view)
 {
-	if (view->inconsistent)
+	if (mail_index_view_is_inconsistent(view))
 		return -1;
 
 	if (view->map != view->index->map) {
@@ -116,6 +116,8 @@
 
 int mail_index_view_is_inconsistent(struct mail_index_view *view)
 {
+	if (view->index->indexid != view->indexid)
+		view->inconsistent = TRUE;
 	return view->inconsistent;
 }
 

Index: mail-index.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index.c,v
retrieving revision 1.113
retrieving revision 1.114
diff -u -d -r1.113 -r1.114
--- mail-index.c	30 Apr 2004 20:17:15 -0000	1.113
+++ mail-index.c	1 May 2004 16:08:15 -0000	1.114
@@ -399,7 +399,8 @@
 	return fd;
 }
 
-int mail_index_create(struct mail_index *index, struct mail_index_header *hdr)
+static int mail_index_create(struct mail_index *index,
+			     struct mail_index_header *hdr)
 {
 	const char *path;
 	uint32_t seq;
@@ -518,8 +519,8 @@
 	return ret;
 }
 
-static int
-mail_index_open2(struct mail_index *index, enum mail_index_open_flags flags)
+static int mail_index_open_files(struct mail_index *index,
+				 enum mail_index_open_flags flags)
 {
 	struct mail_index_header hdr;
 	unsigned int lock_id = 0;
@@ -573,7 +574,7 @@
 
 		index->filepath = i_strconcat(index->dir, "/",
 					      index->prefix, NULL);
-		ret = mail_index_open2(index, flags);
+		ret = mail_index_open_files(index, flags);
 		if (ret <= 0)
 			break;
 
@@ -654,35 +655,6 @@
 	index->indexid = 0;
 }
 
-int mail_index_mark_corrupted(struct mail_index *index)
-{
-	struct mail_index_header hdr;
-
-	if (index->readonly || index->hdr == NULL ||
-	    (index->hdr->flags & MAIL_INDEX_HDR_FLAG_CORRUPTED) != 0)
-		return 0;
-
-	/* make sure we can write the header */
-	if (!MAIL_INDEX_MAP_IS_IN_MEMORY(index->map)) {
-		if (mprotect(index->map->mmap_base, sizeof(hdr),
-			     PROT_READ | PROT_WRITE) < 0) {
-			mail_index_set_syscall_error(index, "mprotect()");
-			return -1;
-		}
-	}
-
-	hdr = *index->hdr;
-	hdr.flags |= MAIL_INDEX_HDR_FLAG_CORRUPTED;
-	if (mail_index_write_header(index, &hdr) < 0)
-		return -1;
-
-	if (fsync(index->fd) < 0)
-		return mail_index_set_syscall_error(index, "fsync()");
-
-	mail_index_set_inconsistent(index);
-	return 0;
-}
-
 int mail_index_set_syscall_error(struct mail_index *index,
 				 const char *function)
 {

Index: mail-transaction-log-view.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-log-view.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- mail-transaction-log-view.c	1 May 2004 15:32:24 -0000	1.7
+++ mail-transaction-log-view.c	1 May 2004 16:08:15 -0000	1.8
@@ -45,6 +45,15 @@
 
 void mail_transaction_log_view_close(struct mail_transaction_log_view *view)
 {
+	struct mail_transaction_log_view **p;
+
+	for (p = &view->log->views; *p != NULL; p = &(*p)->next) {
+		if (*p == view) {
+			*p = view->next;
+			break;
+		}
+	}
+
 	mail_transaction_log_view_unset(view);
 	if (view->data_buf != NULL)
 		buffer_free(view->data_buf);
@@ -52,6 +61,14 @@
 	i_free(view);
 }
 
+void mail_transaction_log_views_close(struct mail_transaction_log *log)
+{
+	struct mail_transaction_log_view *view;
+
+	for (view = log->views; view != NULL; view = view->next)
+		view->log = NULL;
+}
+
 int
 mail_transaction_log_view_set(struct mail_transaction_log_view *view,
 			      uint32_t min_file_seq, uoff_t min_file_offset,
@@ -70,6 +87,9 @@
 	i_assert(min_file_offset >= sizeof(struct mail_transaction_log_header));
 	i_assert(max_file_offset >= sizeof(struct mail_transaction_log_header));
 
+	if (view->log == NULL)
+		return -1;
+
 	ret = mail_transaction_log_file_find(view->log, min_file_seq, &file);
 	if (ret <= 0) {
 		if (ret == 0 &&

Index: mail-transaction-log.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-log.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- mail-transaction-log.c	1 May 2004 15:32:24 -0000	1.13
+++ mail-transaction-log.c	1 May 2004 16:08:15 -0000	1.14
@@ -127,8 +127,9 @@
 
 void mail_transaction_log_close(struct mail_transaction_log *log)
 {
-	i_assert(log->views == NULL);
+	mail_transaction_log_views_close(log);
 
+	log->index->log = NULL;
 	i_free(log);
 }
 
@@ -683,7 +684,8 @@
 	if (st.st_size == file->hdr.used_size &&
 	    file->buffer_offset <= start_offset && end_offset == (uoff_t)-1) {
 		/* we've seen the whole file.. do we have all of it mapped? */
-		size = buffer_get_used_size(file->buffer);
+		size = file->buffer == NULL ? 0 :
+			buffer_get_used_size(file->buffer);
 		if (file->buffer_offset + size == file->hdr.used_size)
 			return 1;
 	}
@@ -709,13 +711,13 @@
 
 	if (start_offset < sizeof(file->hdr)) {
 		mail_transaction_log_file_set_corrupted(file,
-			"offset (%"PRIuUOFF_T"u) < header size (%"PRIuSIZE_T")",
+			"offset (%"PRIuUOFF_T") < header size (%"PRIuSIZE_T")",
 			start_offset, sizeof(file->hdr));
 		return -1;
 	}
 	if (end_offset > file->hdr.used_size) {
 		mail_transaction_log_file_set_corrupted(file,
-			"offset (%"PRIuUOFF_T"u) > used_size (%u)",
+			"offset (%"PRIuUOFF_T") > used_size (%u)",
 			end_offset, file->hdr.used_size);
 		return -1;
 	}

Index: mail-transaction-log.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-log.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- mail-transaction-log.h	1 May 2004 15:32:24 -0000	1.4
+++ mail-transaction-log.h	1 May 2004 16:08:15 -0000	1.5
@@ -94,6 +94,8 @@
 int
 mail_transaction_log_view_is_corrupted(struct mail_transaction_log_view *view);
 
+void mail_transaction_log_views_close(struct mail_transaction_log *log);
+
 /* Write data to transaction log. This is atomic operation. Sequences in
    updates[] and expunges[] are relative to given view, they're modified
    to real ones. */



More information about the dovecot-cvs mailing list