changeset 263:30ee462a6457 HEAD

if hash was rebuilt, it wasn't always mmap()ed. recent-status wasn't updated properly when opening mails. maildir sync() didn't always expunge messages with correct sequence number. added some checks for messages_count in header.
author Timo Sirainen <tss@iki.fi>
date Mon, 16 Sep 2002 16:51:46 +0300
parents f5b444bf9157
children 483f4afe5da2
files src/lib-index/mail-hash.c src/lib-index/mail-index-open.c src/lib-index/mail-index.c src/lib-index/mail-index.h src/lib-index/maildir/maildir-rebuild.c src/lib-index/maildir/maildir-sync.c src/lib-index/mbox/mbox-rebuild.c src/lib-storage/index/index-status.c
diffstat 8 files changed, 65 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-hash.c	Mon Sep 16 16:09:47 2002 +0300
+++ b/src/lib-index/mail-hash.c	Mon Sep 16 16:51:46 2002 +0300
@@ -460,6 +460,12 @@
 		(void)close(hash->fd);
 	hash->fd = fd;
 	hash->anon_mmap = fd == -1;
+
+	if (fd != -1) {
+		if (!mmap_update_real(hash))
+			return FALSE;
+	}
+
 	return TRUE;
 }
 
--- a/src/lib-index/mail-index-open.c	Mon Sep 16 16:09:47 2002 +0300
+++ b/src/lib-index/mail-index-open.c	Mon Sep 16 16:51:46 2002 +0300
@@ -113,9 +113,12 @@
 	return NULL;
 }
 
-static int mail_index_open_init(MailIndex *index, MailIndexHeader *hdr,
-				int update_recent)
+static int mail_index_open_init(MailIndex *index, int update_recent)
 {
+	MailIndexHeader *hdr;
+
+	hdr = index->header;
+
 	/* update \Recent message counters */
 	if (update_recent && hdr->last_nonrecent_uid != hdr->next_uid-1) {
 		/* keep last_recent_uid to next_uid-1 */
@@ -149,16 +152,24 @@
 	return TRUE;
 }
 
-static int index_open_and_fix(MailIndex *index, MailIndexHeader *hdr,
-			      int update_recent)
+static int index_open_and_fix(MailIndex *index, int update_recent)
 {
+	MailIndexHeader *hdr;
+	int rebuild;
+
+	if (!mail_index_mmap_update(index))
+		return FALSE;
+
+	hdr = index->header;
+	rebuild = FALSE;
+
 	/* open/create the index files */
 	if (!mail_index_data_open(index)) {
 		if ((index->set_flags & MAIL_INDEX_FLAG_REBUILD) == 0)
 			return FALSE;
 
 		/* data file is corrupted, need to rebuild index */
-		hdr->flags |= MAIL_INDEX_FLAG_REBUILD;
+		rebuild = TRUE;
 		index->set_flags = 0;
 
 		if (!mail_index_data_create(index))
@@ -170,7 +181,7 @@
 	if (!mail_custom_flags_open_or_create(index))
 		return FALSE;
 
-	if (hdr->flags & MAIL_INDEX_FLAG_REBUILD) {
+	if (rebuild || (hdr->flags & MAIL_INDEX_FLAG_REBUILD)) {
 		/* index is corrupted, rebuild */
 		if (!index->rebuild(index))
 			return FALSE;
@@ -221,7 +232,7 @@
 			return FALSE;
 	}
 
-	if (!mail_index_open_init(index, hdr, update_recent))
+	if (!mail_index_open_init(index, update_recent))
 		return FALSE;
 
 	if (!index->set_lock(index, MAIL_LOCK_UNLOCK))
@@ -267,7 +278,7 @@
 	index->filepath = i_strdup(path);
 	index->indexid = hdr.indexid;
 
-	if (!index_open_and_fix(index, &hdr, update_recent)) {
+	if (!index_open_and_fix(index, update_recent)) {
 		mail_index_close(index);
 		return FALSE;
 	}
@@ -432,7 +443,7 @@
 
 		index->inconsistent = FALSE;
 
-		if (!mail_index_open_init(index, index->header, update_recent))
+		if (!mail_index_open_init(index, update_recent))
 			break;
 
 		if (!index->set_lock(index, MAIL_LOCK_UNLOCK))
--- a/src/lib-index/mail-index.c	Mon Sep 16 16:09:47 2002 +0300
+++ b/src/lib-index/mail-index.c	Mon Sep 16 16:51:46 2002 +0300
@@ -82,7 +82,7 @@
 	return TRUE;
 }
 
-static int mmap_update(MailIndex *index)
+int mail_index_mmap_update(MailIndex *index)
 {
 	if (index->anon_mmap)
 		return mmap_verify(index);
@@ -330,7 +330,7 @@
 		return index_set_syscall_error(index, "file_wait_lock()");
 	index->lock_type = lock_type;
 
-	if (!mmap_update(index)) {
+	if (!mail_index_mmap_update(index)) {
 		(void)mail_index_set_lock(index, MAIL_LOCK_UNLOCK);
 		return FALSE;
 	}
@@ -698,7 +698,8 @@
 	return datarec->data;
 }
 
-unsigned int mail_index_get_sequence(MailIndex *index, MailIndexRecord *rec)
+static unsigned int mail_index_get_sequence_real(MailIndex *index,
+						 MailIndexRecord *rec)
 {
 	MailIndexRecord *seekrec;
 	unsigned int seq;
@@ -740,6 +741,21 @@
 	return seq;
 }
 
+unsigned int mail_index_get_sequence(MailIndex *index, MailIndexRecord *rec)
+{
+	unsigned int seq;
+
+	seq = mail_index_get_sequence_real(index, rec);
+	if (seq > index->header->messages_count) {
+		index_set_corrupted(index, "Too small messages_count in header "
+				    "(found %u > %u)", seq,
+				    index->header->messages_count);
+		return 0;
+	}
+
+	return seq;
+}
+
 void mail_index_mark_flag_changes(MailIndex *index, MailIndexRecord *rec,
 				  MailFlags old_flags, MailFlags new_flags)
 {
@@ -970,7 +986,7 @@
 	   sync_id in header. */
 	index->header->sync_id++;
 
-	if (!mmap_update(index))
+	if (!mail_index_mmap_update(index))
 		return FALSE;
 
 	return TRUE;
--- a/src/lib-index/mail-index.h	Mon Sep 16 16:09:47 2002 +0300
+++ b/src/lib-index/mail-index.h	Mon Sep 16 16:51:46 2002 +0300
@@ -390,6 +390,7 @@
 int mail_index_is_inconsistency_error(MailIndex *index);
 
 /* INTERNAL: */
+int mail_index_mmap_update(MailIndex *index);
 void mail_index_init_header(MailIndexHeader *hdr);
 void mail_index_close(MailIndex *index);
 int mail_index_fmsync(MailIndex *index, size_t size);
--- a/src/lib-index/maildir/maildir-rebuild.c	Mon Sep 16 16:09:47 2002 +0300
+++ b/src/lib-index/maildir/maildir-rebuild.c	Mon Sep 16 16:51:46 2002 +0300
@@ -22,6 +22,7 @@
 
 	/* reset the header */
 	mail_index_init_header(index->header);
+	index->mmap_used_length = index->header->used_file_size;
 
 	/* update indexid, which also means that our state has completely
 	   changed */
--- a/src/lib-index/maildir/maildir-sync.c	Mon Sep 16 16:09:47 2002 +0300
+++ b/src/lib-index/maildir/maildir-sync.c	Mon Sep 16 16:51:46 2002 +0300
@@ -77,7 +77,7 @@
 	i_assert(dir != NULL);
 
 	rec = index->lookup(index, 1);
-	for (seq = 1; rec != NULL; rec = index->next(index, rec), seq++) {
+	for (seq = 1; rec != NULL; rec = index->next(index, rec)) {
 		fname = index->lookup_field(index, rec, FIELD_TYPE_LOCATION);
 		if (fname == NULL) {
 			index_data_set_corrupted(index->data,
@@ -128,6 +128,14 @@
 						     file_changed))
 				return FALSE;
 		}
+
+		seq++;
+	}
+
+	if (seq-1 != index->header->messages_count) {
+		index_set_corrupted(index, "Wrong messages_count in header "
+				    "(%u != %u)", seq-1,
+				    index->header->messages_count);
 	}
 
 	return TRUE;
--- a/src/lib-index/mbox/mbox-rebuild.c	Mon Sep 16 16:09:47 2002 +0300
+++ b/src/lib-index/mbox/mbox-rebuild.c	Mon Sep 16 16:51:46 2002 +0300
@@ -26,6 +26,7 @@
 
 	/* reset the header */
 	mail_index_init_header(index->header);
+	index->mmap_used_length = index->header->used_file_size;
 
 	/* we require MD5 to be cached */
 	index->header->cache_fields |= FIELD_TYPE_MD5;
--- a/src/lib-storage/index/index-status.c	Mon Sep 16 16:09:47 2002 +0300
+++ b/src/lib-storage/index/index-status.c	Mon Sep 16 16:51:46 2002 +0300
@@ -8,6 +8,7 @@
 {
 	MailIndexHeader *hdr;
 	MailIndexRecord *rec;
+	unsigned int seq;
 
 	hdr = mail_index_get_header(index);
 	if (index->first_recent_uid <= 1) {
@@ -31,7 +32,12 @@
 	   the end (fast assuming there's only a few recent messages).
 	   it's a bit easier to use the first method and often it should be
 	   faster too.. */
-	return hdr->messages_count - index->get_sequence(index, rec) + 1;
+	seq = index->get_sequence(index, rec);
+	if (seq == 0) {
+		i_error("Couldn't get sequence for UID %u", rec->uid);
+		return 0;
+	}
+	return hdr->messages_count+1 - seq;
 }
 
 static unsigned int get_first_unseen_seq(MailIndex *index)