changeset 150:cb05d392ad24 HEAD

index wasn't re-mmap()ed when it's size was changed. this is now done by updating "updateid" field in header and checking if it has changed. also the previous hash-rebuild-check was broken.
author Timo Sirainen <tss@iki.fi>
date Wed, 04 Sep 2002 18:19:42 +0300
parents e1a810a57d4e
children e0f995ee5969
files src/lib-index/mail-index-compress.c src/lib-index/mail-index.c src/lib-index/mail-index.h
diffstat 3 files changed, 36 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-index-compress.c	Wed Sep 04 17:45:59 2002 +0300
+++ b/src/lib-index/mail-index-compress.c	Wed Sep 04 18:19:42 2002 +0300
@@ -61,6 +61,9 @@
 	index->header->first_hole_position = 0;
 	index->header->first_hole_records = 0;
 
+	index->header->updateid++;
+	index->dirty_mmap = TRUE;
+
 	/* make sure the whole file is synced before removing rebuild-flag */
 	if (!mail_index_fmsync(index, fsize))
 		return FALSE;
--- a/src/lib-index/mail-index.c	Wed Sep 04 17:45:59 2002 +0300
+++ b/src/lib-index/mail-index.c	Wed Sep 04 18:19:42 2002 +0300
@@ -27,7 +27,10 @@
 
 	if (!index->dirty_mmap) {
 		index->header = (MailIndexHeader *) index->mmap_base;
-		return TRUE;
+
+		/* make sure file size hasn't changed */
+		if (index->header->updateid == index->updateid)
+			return TRUE;
 	}
 
 	if (index->mmap_base != NULL)
@@ -62,6 +65,7 @@
 	index->last_lookup = NULL;
 
 	index->header = (MailIndexHeader *) index->mmap_base;
+	index->updateid = index->header->updateid;
 	index->dirty_mmap = FALSE;
 	return TRUE;
 }
@@ -842,6 +846,7 @@
 	MailIndexRecord *rec, *last_rec;
 	unsigned int seq;
 	uoff_t seekpos;
+	off_t pos;
 
 	if (lookup_seq == index->last_lookup_seq &&
 	    index->last_lookup != NULL && index->last_lookup->uid != 0) {
@@ -861,7 +866,19 @@
 	seekpos = sizeof(MailIndexHeader) +
 		(uoff_t)(lookup_seq-1) * sizeof(MailIndexRecord);
 	if (seekpos + sizeof(MailIndexRecord) > index->mmap_length) {
-		/* out of range */
+		/* minimum file position for wanted sequence would point
+		   ouside file, so it can't exist. however, header said it
+		   should be found.. fsck. */
+		pos = lseek(index->fd, 0, SEEK_END);
+		if (pos >= 0 && (uoff_t)pos > seekpos) {
+			i_panic("Index lookup failed because whole file "
+				"isn't mmap()ed (dirty_mmap not properly set)");
+		}
+
+		index_set_error(index, "Error in index file %s: "
+				"Header contains invalid message count",
+				index->filepath);
+		index->set_flags |= MAIL_INDEX_FLAG_FSCK;
 		return NULL;
 	}
 
@@ -1216,6 +1233,9 @@
 	index->header->first_hole_position = 0;
 	index->header->first_hole_records = 0;
 
+	index->header->updateid++;
+	index->dirty_mmap = TRUE;
+
 	if (index->header->messages_count == 0) {
 		/* all mail was deleted, truncate data file */
 		if (!mail_index_data_reset(index->data))
@@ -1251,7 +1271,7 @@
 		mail_hash_update(index->hash, rec->uid, 0);
 	else {
 		/* make sure it also gets updated */
-		index->flags |= MAIL_INDEX_FLAG_REBUILD_HASH;
+		index->header->flags |= MAIL_INDEX_FLAG_REBUILD_HASH;
 	}
 
 	/* setting UID to 0 is enough for deleting the mail from index */
@@ -1370,7 +1390,11 @@
 	if (index->hash != NULL)
 		mail_hash_update(index->hash, (*rec)->uid, (uoff_t)pos);
 
+	/* file size changed, let others know about it too by changing
+	   updateid in header. */
+	index->header->updateid++;
 	index->dirty_mmap = TRUE;
+
 	if (!mmap_update(index))
 		return FALSE;
 
--- a/src/lib-index/mail-index.h	Wed Sep 04 17:45:59 2002 +0300
+++ b/src/lib-index/mail-index.h	Wed Sep 04 18:19:42 2002 +0300
@@ -86,13 +86,15 @@
 	   5 = MEM_ALIGN_SIZE */
 
 	unsigned int indexid;
+	unsigned int updateid; /* re-mmap() when changed, required only
+	                          if file size is changed */
+
 	unsigned int flags;
+	unsigned int cache_fields;
 
 	uoff_t first_hole_position;
 	unsigned int first_hole_records;
 
-	unsigned int cache_fields;
-
 	unsigned int uid_validity;
 	unsigned int next_uid;
 
@@ -287,6 +289,7 @@
 	char *dir; /* directory where to place the index files */
 	char *filepath; /* index file path */
 	unsigned int indexid;
+	unsigned int updateid;
 
 	char *mbox_path; /* mbox-specific path to the actual mbox file */
 	uoff_t mbox_size; /* last synced size of mbox file */
@@ -324,7 +327,7 @@
 #define MAIL_INDEX_PRIVATE_FILL \
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-	0, 0, 0, 0, 0, 0
+	0, 0, 0, 0, 0, 0, 0
 
 /* defaults - same as above but prefixed with mail_index_. */
 int mail_index_open(MailIndex *index, int update_recent);