changeset 1365:6f65cc862649 HEAD

Some fixes to opening index.
author Timo Sirainen <tss@iki.fi>
date Wed, 16 Apr 2003 18:13:24 +0300
parents 33426716797a
children b2005542fc93
files src/lib-index/mail-index-open.c src/lib-index/mail-tree.c src/lib-index/mail-tree.h src/lib-index/maildir/maildir-rebuild.c src/lib-index/maildir/maildir-sync.c
diffstat 5 files changed, 107 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-index-open.c	Wed Apr 16 17:30:58 2003 +0300
+++ b/src/lib-index/mail-index-open.c	Wed Apr 16 18:13:24 2003 +0300
@@ -301,11 +301,86 @@
 	return TRUE;
 }
 
+static int mail_index_open_index(struct mail_index *index,
+				 enum mail_index_open_flags flags)
+{
+	struct mail_index_header hdr;
+	int ret;
+
+	if ((flags & _MAIL_INDEX_OPEN_FLAG_CREATING) == 0)
+		index->lock_type = MAIL_LOCK_SHARED;
+	else
+		index->lock_type = MAIL_LOCK_EXCLUSIVE;
+
+	/* if index is being created, we'll wait here until it's finished */
+	if (!mail_index_wait_lock(index, MAIL_LOCK_TO_FLOCK(index->lock_type)))
+		return FALSE;
+#ifdef DEBUG
+	if (index->mmap_base != NULL) {
+		mprotect(index->mmap_base, index->mmap_used_length,
+			 PROT_READ|PROT_WRITE);
+	}
+#endif
+
+	if ((ret = mail_index_read_header(index, &hdr)) < 0)
+		return FALSE;
+
+	if (ret == 0 || !mail_index_is_compatible(&hdr)) {
+		if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
+			return FALSE;
+
+		flags |= _MAIL_INDEX_OPEN_FLAG_CREATING;
+
+		/* so, we're creating the index */
+		if (index->lock_type != MAIL_LOCK_EXCLUSIVE) {
+			/* have to get exclusive lock first */
+			if (!mail_index_wait_lock(index, F_UNLCK))
+				return FALSE;
+			return mail_index_open_index(index, flags);
+		}
+
+		mail_index_init_header(index, &hdr);
+		if (!mail_index_init_file(index, &hdr))
+			return FALSE;
+	}
+
+	index->indexid = hdr.indexid;
+
+	if (!mail_index_mmap_update(index))
+		return FALSE;
+
+	if (index->lock_type == MAIL_LOCK_SHARED) {
+		/* we don't want to keep the shared lock while opening
+		   indexes. opening should work unlocked and some
+		   things want exclusive lock */
+		if (!mail_index_wait_lock(index, F_UNLCK))
+			return FALSE;
+		index->lock_type = MAIL_LOCK_UNLOCK;
+	}
+
+	if (!index_open_and_fix(index, flags)) {
+		if ((index->set_flags & MAIL_INDEX_FLAG_REBUILD) == 0 ||
+		    (flags & _MAIL_INDEX_OPEN_FLAG_CREATING) != 0)
+			return FALSE;
+
+		/* needs a rebuild */
+		if (!index->set_lock(index, MAIL_LOCK_UNLOCK))
+			return FALSE;
+
+		flags |= _MAIL_INDEX_OPEN_FLAG_CREATING;
+		return mail_index_open_index(index, flags);
+	}
+
+	if (!index->set_lock(index, MAIL_LOCK_UNLOCK))
+		return FALSE;
+
+	index->opened = TRUE;
+	return TRUE;
+}
+
 int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags)
 {
-        struct mail_index_header hdr;
 	const char *path;
-	int ret;
 
 	i_assert(!index->opened);
 
@@ -328,68 +403,10 @@
 
 	index->filepath = i_strdup(path);
 
-	for (;;) {
-		/* if index is being created, we'll wait here until it's
-		   finished */
-		if ((flags & _MAIL_INDEX_OPEN_FLAG_CREATING) == 0)
-			index->lock_type = MAIL_LOCK_SHARED;
-		else
-			index->lock_type = MAIL_LOCK_EXCLUSIVE;
-		if (!mail_index_wait_lock(index,
-					  MAIL_LOCK_TO_FLOCK(index->lock_type)))
-			break;
-
-		if ((ret = mail_index_read_header(index, &hdr)) < 0)
-			break;
-
-		if (ret == 0 || !mail_index_is_compatible(&hdr)) {
-			if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
-				break;
-
-			flags |= _MAIL_INDEX_OPEN_FLAG_CREATING;
-
-			/* so, we're creating the index */
-			if (index->lock_type != MAIL_LOCK_EXCLUSIVE) {
-				/* have to get exclusive lock first */
-				if (!mail_index_wait_lock(index, F_UNLCK))
-					break;
-				continue;
-			}
-
-			mail_index_init_header(index, &hdr);
-			if (!mail_index_init_file(index, &hdr))
-				break;
-		}
-
-		index->indexid = hdr.indexid;
-
-		if (!mail_index_mmap_update(index))
-			break;
-
-		if (index->lock_type == MAIL_LOCK_SHARED) {
-			/* we don't want to keep the shared lock while opening
-			   indexes. opening should work unlocked and some
-			   things want exclusive lock */
-			if (!mail_index_wait_lock(index, F_UNLCK))
-				break;
-			index->lock_type = MAIL_LOCK_UNLOCK;
-		}
-
-		if (!index_open_and_fix(index, flags) ||
-		    !index->set_lock(index, MAIL_LOCK_UNLOCK)) {
-			mail_index_close(index);
-			return mail_index_create_memory(index, flags);
-		}
-
-		index->opened = TRUE;
-		return TRUE;
+	if (!mail_index_open_index(index, flags)) {
+		mail_index_close(index);
+		return mail_index_create_memory(index, flags);
 	}
 
-	(void)close(index->fd);
-	index->fd = -1;
-
-	i_free(index->filepath);
-	index->filepath = NULL;
-
-	return mail_index_create_memory(index, flags);
+	return TRUE;
 }
--- a/src/lib-index/mail-tree.c	Wed Apr 16 17:30:58 2003 +0300
+++ b/src/lib-index/mail-tree.c	Wed Apr 16 18:13:24 2003 +0300
@@ -318,6 +318,19 @@
 	return TRUE;
 }
 
+int mail_tree_reset(struct mail_tree *tree)
+{
+	i_assert(tree->index->lock_type == MAIL_LOCK_EXCLUSIVE);
+
+	if (!mail_tree_init(tree) ||
+	    (!tree->anon_mmap && !_mail_tree_mmap_update(tree, TRUE))) {
+		tree->index->header->flags |= MAIL_INDEX_FLAG_REBUILD_TREE;
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
 int mail_tree_rebuild(struct mail_tree *tree)
 {
 	struct mail_index_record *rec;
@@ -325,11 +338,8 @@
 	if (!tree->index->set_lock(tree->index, MAIL_LOCK_EXCLUSIVE))
 		return FALSE;
 
-	if (!mail_tree_init(tree) ||
-	    (!tree->anon_mmap && !_mail_tree_mmap_update(tree, TRUE))) {
-		tree->index->header->flags |= MAIL_INDEX_FLAG_REBUILD_TREE;
+	if (!mail_tree_reset(tree))
 		return FALSE;
-	}
 
 	rec = tree->index->lookup(tree->index, 1);
 	while (rec != NULL) {
--- a/src/lib-index/mail-tree.h	Wed Apr 16 17:30:58 2003 +0300
+++ b/src/lib-index/mail-tree.h	Wed Apr 16 18:13:24 2003 +0300
@@ -47,6 +47,7 @@
 int mail_tree_open_or_create(struct mail_index *index);
 void mail_tree_free(struct mail_tree *tree);
 
+int mail_tree_reset(struct mail_tree *tree);
 int mail_tree_rebuild(struct mail_tree *tree);
 int mail_tree_sync_file(struct mail_tree *tree, int *fsync_fd);
 
--- a/src/lib-index/maildir/maildir-rebuild.c	Wed Apr 16 17:30:58 2003 +0300
+++ b/src/lib-index/maildir/maildir-rebuild.c	Wed Apr 16 18:13:24 2003 +0300
@@ -4,6 +4,7 @@
 #include "maildir-index.h"
 #include "mail-index-data.h"
 #include "mail-index-util.h"
+#include "mail-tree.h"
 
 #include <unistd.h>
 #include <sys/stat.h>
@@ -35,6 +36,9 @@
 	if (!mail_index_data_reset(index->data))
 		return FALSE;
 
+	if (!mail_tree_reset(index->tree))
+		return FALSE;
+
 	/* read the mails by syncing */
 	if (!index->sync_and_lock(index, MAIL_LOCK_UNLOCK, NULL))
 		return FALSE;
--- a/src/lib-index/maildir/maildir-sync.c	Wed Apr 16 17:30:58 2003 +0300
+++ b/src/lib-index/maildir/maildir-sync.c	Wed Apr 16 18:13:24 2003 +0300
@@ -484,13 +484,19 @@
 		if (uidlist != NULL &&
 		    uidlist->uid_validity != index->header->uid_validity) {
 			/* uidvalidity changed */
-			if (!index->rebuilding) {
+			if (!index->rebuilding && index->opened) {
 				index_set_corrupted(index,
 					"UIDVALIDITY changed in uidlist");
 				return FALSE;
 			}
 
+			if (!index->rebuilding) {
+				index->set_flags |= MAIL_INDEX_FLAG_REBUILD;
+				return FALSE;
+			}
+
 			index->header->uid_validity = uidlist->uid_validity;
+			i_assert(index->header->next_uid == 1);
 		}
 
 		if (uidlist != NULL &&