changeset 206:0bb7bf7266ab HEAD

cleanups / reliability fixes
author Timo Sirainen <tss@iki.fi>
date Tue, 10 Sep 2002 01:49:34 +0300
parents ad2ceb287fce
children 9f78db959fdc
files src/lib-index/mail-index.c src/lib-index/mail-index.h src/lib-index/maildir/maildir-build.c src/lib-index/mbox/mbox-append.c
diffstat 4 files changed, 52 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-index.c	Tue Sep 10 00:45:39 2002 +0300
+++ b/src/lib-index/mail-index.c	Tue Sep 10 01:49:34 2002 +0300
@@ -1235,16 +1235,24 @@
 
 static int mail_index_truncate(MailIndex *index)
 {
+	if (msync(index->mmap_base, index->mmap_length, MS_SYNC) == -1) {
+		index_set_error(index, "msync() failed for %s: %m",
+				index->filepath);
+		return FALSE;
+	}
+
 	/* truncate index file */
-	if (ftruncate(index->fd, (off_t)index->header->first_hole_position) < 0)
+	if (ftruncate(index->fd,
+		      (off_t)index->header->first_hole_position) < 0) {
+		index_set_error(index, "ftruncate() failed for index file "
+				"%s: %m", index->filepath);
 		return FALSE;
+	}
 
 	/* update header */
 	index->header->first_hole_position = 0;
 	index->header->first_hole_records = 0;
-
 	index->header->sync_id++;
-	index->dirty_mmap = TRUE;
 
 	if (index->header->messages_count == 0) {
 		/* all mail was deleted, truncate data file */
@@ -1373,13 +1381,13 @@
 					 rec->uid, external_change);
 }
 
-int mail_index_append(MailIndex *index, MailIndexRecord **rec)
+int mail_index_append(MailIndex *index, MailIndexRecord **rec,
+		      unsigned int *uid)
 {
 	off_t pos;
 
 	i_assert(index->lock_type == MAIL_LOCK_EXCLUSIVE);
-
-	(*rec)->uid = index->header->next_uid++;
+	i_assert((*rec)->uid == 0);
 
 	pos = lseek(index->fd, 0, SEEK_END);
 	if (pos < 0) {
@@ -1405,10 +1413,17 @@
 	index->header->sync_id++;
 	index->dirty_mmap = TRUE;
 
+	if (msync(index->mmap_base, sizeof(MailIndexHeader), MS_SYNC) == -1) {
+		index_set_error(index, "msync() failed for %s: %m",
+				index->filepath);
+		return FALSE;
+	}
+
 	if (!mmap_update(index))
 		return FALSE;
 
 	*rec = (MailIndexRecord *) ((char *) index->mmap_base + pos);
+	*uid = index->header->next_uid++;
 	return TRUE;
 }
 
--- a/src/lib-index/mail-index.h	Tue Sep 10 00:45:39 2002 +0300
+++ b/src/lib-index/mail-index.h	Tue Sep 10 01:49:34 2002 +0300
@@ -259,9 +259,10 @@
 
 	/* Append a new record to index. The index must be exclusively
 	   locked before calling this function. The record pointer is
-	   updated to the mmap()ed record. rec->uid field is updated by this
-	   function, nothing else is touched. */
-	int (*append)(MailIndex *index, MailIndexRecord **rec);
+	   updated to the mmap()ed record. *uid is set to the UID which
+	   should be set to rec->uid once the update is fully done. */
+	int (*append)(MailIndex *index, MailIndexRecord **rec,
+		      unsigned int *uid);
 
 	/* Updating fields happens by calling update_begin(), one or more
 	   update_field()s and finally update_end() which does the actual
@@ -366,7 +367,8 @@
 int mail_index_update_flags(MailIndex *index, MailIndexRecord *rec,
 			    unsigned int seq, MailFlags flags,
 			    int external_change);
-int mail_index_append(MailIndex *index, MailIndexRecord **rec);
+int mail_index_append(MailIndex *index, MailIndexRecord **rec,
+		      unsigned int *uid);
 MailIndexUpdate *mail_index_update_begin(MailIndex *index,
 					 MailIndexRecord *rec);
 int mail_index_update_end(MailIndexUpdate *update);
--- a/src/lib-index/maildir/maildir-build.c	Tue Sep 10 00:45:39 2002 +0300
+++ b/src/lib-index/maildir/maildir-build.c	Tue Sep 10 01:49:34 2002 +0300
@@ -12,7 +12,8 @@
 #include <sys/stat.h>
 
 static MailIndexRecord *
-mail_index_record_append(MailIndex *index, time_t internal_date)
+mail_index_record_append(MailIndex *index, time_t internal_date,
+			 unsigned int *uid)
 {
 	MailIndexRecord trec, *rec;
 
@@ -20,7 +21,7 @@
 	trec.internal_date = internal_date;
 
 	rec = &trec;
-	if (!index->append(index, &rec))
+	if (!index->append(index, &rec, uid))
 		return NULL;
 
 	return rec;
@@ -32,6 +33,7 @@
 	MailIndexRecord *rec;
 	MailIndexUpdate *update;
 	struct stat st;
+	unsigned int uid;
 	int failed;
 
 	i_assert(path != NULL);
@@ -55,7 +57,7 @@
 		return FALSE;
 
 	/* append the file into index */
-	rec = mail_index_record_append(index, st.st_mtime);
+	rec = mail_index_record_append(index, st.st_mtime, &uid);
 	if (rec == NULL)
 		return FALSE;
 
@@ -72,11 +74,14 @@
 	/* parse the header and update record's fields */
 	failed = !maildir_record_update(update, fd, path);
 
-	if (!index->update_end(update) || failed) {
-		/* failed - delete the record */
-		(void)index->expunge(index, rec, 0, FALSE);
+	if (!index->update_end(update) || failed)
 		return FALSE;
-	}
+
+	/* make sure everything is written before setting it's UID
+	   to mark it as non-deleted. */
+	if (!mail_index_fmsync(index, index->mmap_length))
+		return FALSE;
+	rec->uid = uid;
 
 	return TRUE;
 }
--- a/src/lib-index/mbox/mbox-append.c	Tue Sep 10 00:45:39 2002 +0300
+++ b/src/lib-index/mbox/mbox-append.c	Tue Sep 10 01:49:34 2002 +0300
@@ -9,7 +9,8 @@
 #include "mail-index-util.h"
 
 static MailIndexRecord *mail_index_record_append(MailIndex *index,
-						 time_t internal_date)
+						 time_t internal_date,
+						 unsigned int *uid)
 {
 	MailIndexRecord trec, *rec;
 
@@ -17,7 +18,7 @@
 	trec.internal_date = internal_date;
 
 	rec = &trec;
-	if (!index->append(index, &rec))
+	if (!index->append(index, &rec, uid))
 		return NULL;
 
 	return rec;
@@ -83,6 +84,7 @@
 	time_t internal_date;
 	uoff_t abs_start_offset, stop_offset, old_size;
 	unsigned char *data, md5_digest[16];
+	unsigned int uid;
 	size_t size, pos;
 	int failed;
 
@@ -121,7 +123,7 @@
 	stop_offset = inbuf->offset;
 
 	/* add message to index */
-	rec = mail_index_record_append(index, internal_date);
+	rec = mail_index_record_append(index, internal_date, &uid);
 	if (rec == NULL)
 		return FALSE;
 
@@ -151,15 +153,19 @@
 	index->update_field_raw(update, FIELD_TYPE_MD5,
 				md5_digest, sizeof(md5_digest));
 
-	if (!index->update_end(update)) {
-		/* failed - delete the record */
-		(void)index->expunge(index, rec, 0, FALSE);
+	if (!index->update_end(update))
 		failed = TRUE;
-	} else {
+	else {
 		/* save message flags */
 		rec->msg_flags = ctx.flags;
 		mail_index_mark_flag_changes(index, rec, 0, rec->msg_flags);
 		failed = FALSE;
+
+		/* make sure everything is written before setting it's UID
+		   to mark it as non-deleted. */
+		if (!mail_index_fmsync(index, index->mmap_length))
+			return FALSE;
+		rec->uid = uid;
 	}
 
 	mbox_header_free_context(&ctx);