dovecot-1.2: maildir uidlist: Added better next_uid error tracking.

dovecot at dovecot.org dovecot at dovecot.org
Mon Jul 27 06:38:25 EEST 2009


details:   http://hg.dovecot.org/dovecot-1.2/rev/5a4875e92829
changeset: 9262:5a4875e92829
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Jul 26 23:37:15 2009 -0400
description:
maildir uidlist: Added better next_uid error tracking.

diffstat:

1 file changed, 18 insertions(+), 12 deletions(-)
src/lib-storage/index/maildir/maildir-uidlist.c |   30 +++++++++++++----------

diffs (86 lines):

diff -r 51aee73e49a5 -r 5a4875e92829 src/lib-storage/index/maildir/maildir-uidlist.c
--- 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 @@ struct maildir_uidlist {
 
 	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(s
 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;
@@ -589,13 +590,6 @@ static int maildir_uidlist_read_header(s
 		if (sscanf(line, "%u %u", &uid_validity, &next_uid) != 2) {
 			maildir_uidlist_set_corrupted(uidlist,
 				"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;
@@ -640,8 +634,17 @@ static int maildir_uidlist_read_header(s
 		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 @@ maildir_uidlist_update_read(struct maild
 {
 	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 @@ maildir_uidlist_update_read(struct maild
 	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 @@ maildir_uidlist_update_read(struct maild
 		}
 		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;
 		}


More information about the dovecot-cvs mailing list