[dovecot-cvs] dovecot/src/lib-storage/index/mbox mbox-sync-parse.c, 1.56, 1.57 mbox-sync-private.h, 1.62, 1.63 mbox-sync.c, 1.199, 1.200

tss at dovecot.org tss at dovecot.org
Wed Feb 28 19:55:34 UTC 2007


Update of /var/lib/cvs/dovecot/src/lib-storage/index/mbox
In directory talvi:/tmp/cvs-serv13907

Modified Files:
	mbox-sync-parse.c mbox-sync-private.h mbox-sync.c 
Log Message:
If next_uid field gets to 2^31-1, handle it without crashing by creating a
new uidvalidity and renumbering the UIDs (although it requires selecting the
mailbox twice, first time to get index file deleted).



Index: mbox-sync-parse.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-parse.c,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -d -r1.56 -r1.57
--- mbox-sync-parse.c	25 Jan 2007 09:38:23 -0000	1.56
+++ mbox-sync-parse.c	28 Feb 2007 19:55:31 -0000	1.57
@@ -171,7 +171,8 @@
 	size_t i, j, uid_last_pos;
 	uint32_t uid_validity, uid_last;
 
-	if (ctx->seq != 1 || ctx->seen_imapbase) {
+	if (ctx->seq != 1 || ctx->seen_imapbase ||
+	    ctx->sync_ctx->renumber_uids) {
 		/* Valid only in first message */
 		return FALSE;
 	}
@@ -531,7 +532,8 @@
 		if (sync_ctx->base_uid_validity == 0) {
 			/* figure out a new UIDVALIDITY for us. */
 			sync_ctx->base_uid_validity =
-				sync_ctx->hdr->uid_validity != 0 ?
+				sync_ctx->hdr->uid_validity != 0 &&
+				!sync_ctx->renumber_uids ?
 				sync_ctx->hdr->uid_validity :
 				I_MAX((uint32_t)ioloop_time, 1);
 		}

Index: mbox-sync-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-private.h,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -d -r1.62 -r1.63
--- mbox-sync-private.h	19 Feb 2007 23:29:00 -0000	1.62
+++ mbox-sync-private.h	28 Feb 2007 19:55:31 -0000	1.63
@@ -131,6 +131,7 @@
 
 	/* global flags: */
 	unsigned int delay_writes:1;
+	unsigned int renumber_uids:1;
 };
 
 int mbox_sync(struct mbox_mailbox *mbox, enum mbox_sync_flags flags);

Index: mbox-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync.c,v
retrieving revision 1.199
retrieving revision 1.200
diff -u -d -r1.199 -r1.200
--- mbox-sync.c	19 Feb 2007 23:29:01 -0000	1.199
+++ mbox-sync.c	28 Feb 2007 19:55:32 -0000	1.200
@@ -1029,6 +1029,14 @@
 	if (ret <= 0)
 		return ret;
 
+	if (sync_ctx->renumber_uids) {
+		/* expunge everything */
+		while (sync_ctx->idx_seq <= messages_count) {
+			mail_index_expunge(sync_ctx->t,
+					   sync_ctx->idx_seq++);
+		}
+	}
+
 	skipped_mails = uids_broken = FALSE;
 	while ((ret = mbox_sync_read_next_mail(sync_ctx, mail_ctx)) > 0) {
 		uid = mail_ctx->mail.uid;
@@ -1123,6 +1131,19 @@
 				mail_index_expunge(sync_ctx->t,
 						   sync_ctx->idx_seq++);
 			}
+
+			if (sync_ctx->next_uid == (uint32_t)-1) {
+				/* oh no, we're out of UIDs. this shouldn't
+				   happen normally, so just try to get it fixed
+				   without crashing. */
+				mail_storage_set_critical(
+					STORAGE(sync_ctx->mbox->storage),
+					"Out of UIDs, renumbering them in mbox "
+					"file %s", sync_ctx->mbox->path);
+				sync_ctx->renumber_uids = TRUE;
+				return 0;
+			}
+
 			mail_ctx->need_rewrite = TRUE;
 			mail_ctx->mail.uid = sync_ctx->next_uid++;
 			sync_ctx->prev_msg_uid = mail_ctx->mail.uid;
@@ -1451,6 +1472,7 @@
 {
 	struct mbox_sync_mail_context mail_ctx;
 	const struct stat *st;
+	unsigned int i;
 	int ret, partial;
 
 	st = i_stream_stat(sync_ctx->file_input, FALSE);
@@ -1486,24 +1508,22 @@
 	}
 
 	mbox_sync_restart(sync_ctx);
-	ret = mbox_sync_loop(sync_ctx, &mail_ctx, partial);
-	if (ret <= 0) {
+	for (i = 0; i < 3; i++) {
+		ret = mbox_sync_loop(sync_ctx, &mail_ctx, partial);
+		if (ret > 0)
+			break;
 		if (ret < 0)
 			return -1;
 
-		/* partial syncing didn't work, do it again */
+		/* partial syncing didn't work, do it again. we get here
+		   also if we ran out of UIDs. */
 		i_assert(sync_ctx->mbox->mbox_sync_dirty);
 		mbox_sync_restart(sync_ctx);
 
 		mail_index_transaction_rollback(&sync_ctx->t);
 		sync_ctx->t = mail_index_transaction_begin(sync_ctx->sync_view,
 							   FALSE, TRUE);
-
-		ret = mbox_sync_loop(sync_ctx, &mail_ctx, FALSE);
-		if (ret <= 0) {
-			i_assert(ret != 0);
-			return -1;
-		}
+		partial = FALSE;
 	}
 
 	if (mbox_sync_handle_eof_updates(sync_ctx, &mail_ctx) < 0)



More information about the dovecot-cvs mailing list