changeset 9262:5a4875e92829 HEAD

maildir uidlist: Added better next_uid error tracking.
author Timo Sirainen <tss@iki.fi>
date Sun, 26 Jul 2009 23:37:15 -0400
parents 51aee73e49a5
children 3f25c2a13a71
files src/lib-storage/index/maildir/maildir-uidlist.c
diffstat 1 files changed, 18 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/maildir/maildir-uidlist.c	Sun Jul 26 23:36:12 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-uidlist.c	Sun Jul 26 23:37:15 2009 -0400
@@ -83,6 +83,7 @@
 
 	unsigned int version;
 	unsigned int uid_validity, next_uid, prev_read_uid, last_seen_uid;
+	unsigned int hdr_next_uid;
 	unsigned int read_records_count, read_line_count;
 	uoff_t last_read_offset;
 	string_t *hdr_extensions;
@@ -563,7 +564,7 @@
 static int maildir_uidlist_read_header(struct maildir_uidlist *uidlist,
 				       struct istream *input)
 {
-	unsigned int uid_validity, next_uid;
+	unsigned int uid_validity = 0, next_uid = 0;
 	string_t *ext_hdr;
 	const char *line;
 	char key;
@@ -591,13 +592,6 @@
 				"Corrupted header (version 1)");
 			return 0;
 		}
-		if (uid_validity == uidlist->uid_validity &&
-		    next_uid < uidlist->next_uid) {
-			maildir_uidlist_set_corrupted(uidlist,
-				"next_uid was lowered (v1, %u -> %u)",
-				uidlist->next_uid, next_uid);
-			return 0;
-		}
 		break;
 	case UIDLIST_VERSION:
 		ext_hdr = uidlist->hdr_extensions;
@@ -640,8 +634,17 @@
 		return 0;
 	}
 
+	if (uid_validity == uidlist->uid_validity &&
+	    next_uid < uidlist->hdr_next_uid) {
+		maildir_uidlist_set_corrupted(uidlist,
+			"next_uid header was lowered (%u -> %u)",
+			uidlist->hdr_next_uid, next_uid);
+		return 0;
+	}
+
 	uidlist->uid_validity = uid_validity;
 	uidlist->next_uid = next_uid;
+	uidlist->hdr_next_uid = next_uid;
 	return 1;
 }
 
@@ -662,7 +665,7 @@
 {
 	struct mail_storage *storage = uidlist->ibox->box.storage;
 	const char *line;
-	unsigned int orig_next_uid;
+	uint32_t orig_next_uid, orig_uid_validity;
 	struct istream *input;
 	struct stat st;
 	uoff_t last_read_offset;
@@ -721,6 +724,7 @@
 	input = i_stream_create_fd(fd, 4096, FALSE);
 	i_stream_seek(input, last_read_offset);
 
+	orig_uid_validity = uidlist->uid_validity;
 	orig_next_uid = uidlist->next_uid;
 	ret = input->v_offset != 0 ? 1 :
 		maildir_uidlist_read_header(uidlist, input);
@@ -754,11 +758,13 @@
 		}
 		if (uidlist->next_uid <= uidlist->prev_read_uid)
 			uidlist->next_uid = uidlist->prev_read_uid + 1;
-		if (ret > 0 && uidlist->next_uid < orig_next_uid) {
+		if (ret > 0 && uidlist->uid_validity != orig_uid_validity) {
+			uidlist->recreate = TRUE;
+		} else if (ret > 0 && uidlist->next_uid < orig_next_uid) {
 			mail_storage_set_critical(storage,
-				"%s: next_uid was lowered (%u -> %u)",
+				"%s: next_uid was lowered (%u -> %u, hdr=%u)",
 				uidlist->path, orig_next_uid,
-				uidlist->next_uid);
+				uidlist->next_uid, uidlist->hdr_next_uid);
 			uidlist->recreate = TRUE;
 			uidlist->next_uid = orig_next_uid;
 		}