changeset 3296:c2b8904dc21b HEAD

mmap_disable=yes: Transaction log might have been rotated before everything was committed to index.
author Timo Sirainen <tss@iki.fi>
date Sun, 17 Apr 2005 01:01:11 +0300
parents 98923db29e39
children b596431525d3
files src/lib-index/mail-index-private.h src/lib-index/mail-index.c src/lib-index/mail-transaction-log-append.c
diffstat 3 files changed, 37 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-index-private.h	Sun Apr 17 00:41:22 2005 +0300
+++ b/src/lib-index/mail-index-private.h	Sun Apr 17 01:01:11 2005 +0300
@@ -206,6 +206,12 @@
    Returns 1 = ok, 0 = corrupted, -1 = error. If index needs fscking, it
    returns 1 but sets index->fsck = TRUE. */
 int mail_index_map(struct mail_index *index, int force);
+/* Read the latest available header. Normally this is pretty much the same as
+   calling mail_index_map(), but with mmap_disable the header can be generated
+   by reading just log files, so eg. log_file_*_offset values can be wrong.
+   Returns 1 = ok, 0 = EOF, -1 = error. */
+int mail_index_get_latest_header(struct mail_index *index,
+				 struct mail_index_header *hdr_r);
 /* Unreference given mapping and unmap it if it's dropped to zero. */
 void mail_index_unmap(struct mail_index *index, struct mail_index_map *map);
 struct mail_index_map *
--- a/src/lib-index/mail-index.c	Sun Apr 17 00:41:22 2005 +0300
+++ b/src/lib-index/mail-index.c	Sun Apr 17 01:01:11 2005 +0300
@@ -1021,6 +1021,24 @@
 	return 1;
 }
 
+int mail_index_get_latest_header(struct mail_index *index,
+				 struct mail_index_header *hdr_r)
+{
+	size_t pos;
+	int ret;
+
+	if (!index->mmap_disable) {
+		ret = mail_index_map(index, FALSE);
+		if (ret > 0)
+			*hdr_r = *index->hdr;
+		else
+			memset(hdr_r, 0, sizeof(*hdr_r));
+	} else {
+		ret = mail_index_read_header(index, hdr_r, &pos);
+	}
+	return ret;
+}
+
 struct mail_index_map *
 mail_index_map_clone(struct mail_index_map *map, uint32_t new_record_size)
 {
--- a/src/lib-index/mail-transaction-log-append.c	Sun Apr 17 00:41:22 2005 +0300
+++ b/src/lib-index/mail-transaction-log-append.c	Sun Apr 17 01:01:11 2005 +0300
@@ -327,6 +327,11 @@
 	return 0;
 }
 
+#define ARE_ALL_TRANSACTIONS_IN_INDEX(log, idx_hdr) \
+	((log)->head->hdr.file_seq == (idx_hdr)->log_file_seq && \
+	 (log)->head->sync_offset == (idx_hdr)->log_file_int_offset && \
+	 (log)->head->sync_offset == (idx_hdr)->log_file_ext_offset)
+
 int mail_transaction_log_append(struct mail_index_transaction *t,
 				uint32_t *log_file_seq_r,
 				uoff_t *log_file_offset_r)
@@ -367,7 +372,8 @@
 
 	if (log->head->sync_offset > MAIL_TRANSACTION_LOG_ROTATE_SIZE &&
 	    (time_t)log->head->hdr.create_stamp <
-	    ioloop_time - MAIL_TRANSACTION_LOG_ROTATE_TIME) {
+	    ioloop_time - MAIL_TRANSACTION_LOG_ROTATE_TIME &&
+	    ARE_ALL_TRANSACTIONS_IN_INDEX(log, index->hdr)) {
 		/* we might want to rotate, but check first that everything is
 		   synced in index. */
 		if (mail_index_lock_shared(log->index, TRUE, &lock_id) < 0) {
@@ -375,19 +381,19 @@
 				mail_transaction_log_file_unlock(log->head);
 			return -1;
 		}
-		if (mail_index_map(index, FALSE) <= 0) {
+
+		/* we need the latest log_file_*_offsets. It's important to
+		   use this function instead of mail_index_map() as it may
+		   have generated them by reading log files. */
+		if (mail_index_get_latest_header(index, &idx_hdr) <= 0) {
 			mail_index_unlock(index, lock_id);
 			if (!log->index->log_locked)
 				mail_transaction_log_file_unlock(log->head);
 			return -1;
 		}
-
-		idx_hdr = *log->index->hdr;
 		mail_index_unlock(log->index, lock_id);
 
-		if (log->head->hdr.file_seq == idx_hdr.log_file_seq &&
-		    log->head->sync_offset == idx_hdr.log_file_int_offset &&
-		    log->head->sync_offset == idx_hdr.log_file_ext_offset) {
+		if (ARE_ALL_TRANSACTIONS_IN_INDEX(log, &idx_hdr)) {
 			if (mail_transaction_log_rotate(log, TRUE) < 0) {
 				/* that didn't work. well, try to continue
 				   anyway */