changeset 45:d8ff9a34ed03 HEAD

Hash is now properly rebuilt if errors are noticed while opening it.
author Timo Sirainen <tss@iki.fi>
date Tue, 27 Aug 2002 06:26:18 +0300
parents e399e33d033d
children b2bc8d2e56ff
files src/lib-index/mail-hash.c
diffstat 1 files changed, 28 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-hash.c	Tue Aug 27 05:28:16 2002 +0300
+++ b/src/lib-index/mail-hash.c	Tue Aug 27 06:26:18 2002 +0300
@@ -52,17 +52,8 @@
 	unsigned int modified:1;
 };
 
-static int mmap_update(MailHash *hash)
+static int mmap_update_real(MailHash *hash)
 {
-	if (hash->fd == -1)
-		return FALSE;
-
-	if (!hash->dirty_mmap) {
-		/* see if someone else modified it */
-		if (hash->header->updateid == hash->updateid)
-			return TRUE;
-	}
-
 	if (hash->mmap_base != NULL)
 		(void)munmap(hash->mmap_base, hash->mmap_length);
 
@@ -76,6 +67,11 @@
 		return FALSE;
 	}
 
+	return TRUE;
+}
+
+static int hash_verify_header(MailHash *hash)
+{
 	if (hash->mmap_length <= sizeof(MailHashHeader) ||
 	    (hash->mmap_length - sizeof(MailHashHeader)) %
 	    sizeof(MailHashRecord) != 0) {
@@ -88,9 +84,7 @@
 		return FALSE;
 	}
 
-	hash->dirty_mmap = FALSE;
 	hash->header = hash->mmap_base;
-
 	hash->updateid = hash->header->updateid;
 	hash->size = (hash->mmap_length - sizeof(MailHashHeader)) /
 		sizeof(MailHashRecord);
@@ -102,9 +96,26 @@
 				"Invalid size %u", hash->filepath, hash->size);
 		return FALSE;
 	}
+
+	hash->dirty_mmap = FALSE;
 	return TRUE;
 }
 
+static int mmap_update(MailHash *hash)
+{
+	if (hash->fd == -1)
+		return FALSE;
+
+	if (!hash->dirty_mmap) {
+		/* see if someone else modified it */
+		if (hash->header->updateid == hash->updateid)
+			return TRUE;
+	}
+
+	return mmap_update_real(hash) && hash_verify_header(hash);
+
+}
+
 static MailHash *mail_hash_new(MailIndex *index)
 {
 	MailHash *hash;
@@ -143,15 +154,16 @@
 	if (hash->fd == -1)
 		return mail_hash_lock_and_rebuild(hash);
 
-	if (!mmap_update(hash)) {
+	if (!mmap_update_real(hash)) {
 		/* mmap() failure is fatal */
 		mail_hash_free(hash);
 		return FALSE;
 	}
 
-	/* verify that this really is the hash file for wanted index */
-	if (hash->header->indexid != index->indexid) {
-		/* mismatch - just recreate it */
+	/* make sure the header looks fine */
+	if (!hash_verify_header(hash) ||
+	    hash->header->indexid != hash->index->indexid) {
+		/* just recreate it */
 		(void)munmap(hash->mmap_base, hash->mmap_length);
 		hash->mmap_base = NULL;
 		hash->dirty_mmap = TRUE;