[dovecot-cvs] dovecot/src/lib-storage/index/mbox mbox-sync-parse.c, 1.49.2.4, 1.49.2.5 mbox-sync-private.h, 1.56.2.5, 1.56.2.6 mbox-sync.c, 1.181.2.11, 1.181.2.12

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


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

Modified Files:
      Tag: branch_1_0
	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.49.2.4
retrieving revision 1.49.2.5
diff -u -d -r1.49.2.4 -r1.49.2.5
--- mbox-sync-parse.c	25 Jan 2007 09:38:21 -0000	1.49.2.4
+++ mbox-sync-parse.c	28 Feb 2007 19:55:27 -0000	1.49.2.5
@@ -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.56.2.5
retrieving revision 1.56.2.6
diff -u -d -r1.56.2.5 -r1.56.2.6
--- mbox-sync-private.h	19 Feb 2007 23:28:57 -0000	1.56.2.5
+++ mbox-sync-private.h	28 Feb 2007 19:55:27 -0000	1.56.2.6
@@ -129,6 +129,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.181.2.11
retrieving revision 1.181.2.12
diff -u -d -r1.181.2.11 -r1.181.2.12
--- mbox-sync.c	19 Feb 2007 23:28:57 -0000	1.181.2.11
+++ mbox-sync.c	28 Feb 2007 19:55:27 -0000	1.181.2.12
@@ -1033,6 +1033,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;
@@ -1127,6 +1135,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;
@@ -1455,6 +1476,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);
@@ -1490,24 +1512,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