dovecot-2.0: maildir: mail_update_uid() now updates uidlist also.

dovecot at dovecot.org dovecot at dovecot.org
Thu Aug 6 03:30:51 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/7315aa70dfcf
changeset: 9729:7315aa70dfcf
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Aug 05 20:17:13 2009 -0400
description:
maildir: mail_update_uid() now updates uidlist also.

diffstat:

3 files changed, 76 insertions(+), 1 deletion(-)
src/lib-storage/index/maildir/maildir-mail.c    |    8 ++
src/lib-storage/index/maildir/maildir-save.c    |   66 +++++++++++++++++++++++
src/lib-storage/index/maildir/maildir-storage.h |    3 +

diffs (162 lines):

diff -r 64ab55223d69 -r 7315aa70dfcf src/lib-storage/index/maildir/maildir-mail.c
--- a/src/lib-storage/index/maildir/maildir-mail.c	Wed Aug 05 20:15:47 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-mail.c	Wed Aug 05 20:17:13 2009 -0400
@@ -482,6 +482,12 @@ static int maildir_mail_get_stream(struc
 	}
 
 	return index_mail_init_stream(mail, hdr_size, body_size, stream_r);
+}
+
+static void maildir_mail_update_uid(struct mail *_mail, uint32_t new_uid)
+{
+	maildir_save_add_conflict(_mail->transaction, _mail->uid, new_uid);
+	index_mail_update_uid(_mail, new_uid);
 }
 
 static void maildir_mail_set_cache_corrupted(struct mail *_mail,
@@ -544,7 +550,7 @@ struct mail_vfuncs maildir_mail_vfuncs =
 	index_mail_update_flags,
 	index_mail_update_keywords,
 	index_mail_update_modseq,
-	index_mail_update_uid,
+	maildir_mail_update_uid,
 	index_mail_expunge,
 	maildir_mail_set_cache_corrupted,
 	index_mail_get_index_mail
diff -r 64ab55223d69 -r 7315aa70dfcf src/lib-storage/index/maildir/maildir-save.c
--- a/src/lib-storage/index/maildir/maildir-save.c	Wed Aug 05 20:15:47 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-save.c	Wed Aug 05 20:17:13 2009 -0400
@@ -37,6 +37,10 @@ struct maildir_filename {
 	/* unsigned int keywords[]; */
 };
 
+struct maildir_save_conflict {
+	uint32_t old_uid, new_uid;
+};
+
 struct maildir_save_context {
 	struct mail_save_context ctx;
 	pool_t pool;
@@ -51,6 +55,8 @@ struct maildir_save_context {
 	const char *tmpdir, *newdir, *curdir;
 	struct maildir_filename *files, **files_tail, *file_last;
 	unsigned int files_count;
+
+	ARRAY_DEFINE(conflicts, struct maildir_save_conflict);
 
 	buffer_t keywords_buffer;
 	ARRAY_TYPE(keyword_indexes) keywords_array;
@@ -602,6 +608,55 @@ void maildir_save_cancel(struct mail_sav
 	(void)maildir_save_finish(_ctx);
 }
 
+void maildir_save_add_conflict(struct mailbox_transaction_context *t,
+			       uint32_t old_uid, uint32_t new_uid)
+{
+	struct maildir_save_context *save_ctx;
+	struct maildir_save_conflict *c;
+
+	save_ctx = (struct maildir_save_context *)maildir_save_alloc(t);
+
+	if (!array_is_created(&save_ctx->conflicts))
+		i_array_init(&save_ctx->conflicts, 64);
+
+	c = array_append_space(&save_ctx->conflicts);
+	c->old_uid = old_uid;
+	c->new_uid = new_uid;
+}
+
+static void maildir_sync_conflict(struct maildir_save_context *ctx,
+				  const struct maildir_save_conflict *conflict)
+{
+	const char *filename;
+	enum maildir_uidlist_rec_flag flags;
+
+	if (maildir_uidlist_lookup(ctx->mbox->uidlist, conflict->old_uid,
+				   &flags, &filename) <= 0) {
+		i_error("maildir %s: uid %u update failed: lost filename",
+			ctx->mbox->ibox.box.path, conflict->old_uid);
+		return;
+	}
+	maildir_uidlist_sync_remove(ctx->uidlist_sync_ctx, filename);
+	if (maildir_uidlist_sync_next_uid(ctx->uidlist_sync_ctx, filename,
+					  conflict->new_uid, 0) < 0) {
+		i_error("maildir %s: uid %u update failed: sync failed",
+			ctx->mbox->ibox.box.path, conflict->old_uid);
+	}
+}
+
+static void maildir_sync_conflicts(struct maildir_save_context *ctx)
+{
+	const struct maildir_save_conflict *conflicts;
+	unsigned int i, count;
+
+	if (!array_is_created(&ctx->conflicts))
+		return;
+
+	conflicts = array_get(&ctx->conflicts, &count);
+	for (i = 0; i < count; i++)
+		maildir_sync_conflict(ctx, &conflicts[i]);
+}
+
 static void
 maildir_save_unlink_files(struct maildir_save_context *ctx)
 {
@@ -739,6 +794,9 @@ maildir_save_rollback_index_changes(stru
 	struct index_transaction_context *t =
 		(struct index_transaction_context *)ctx->ctx.transaction;
 	uint32_t seq;
+
+	if (ctx->seq == 0)
+		return;
 
 	for (seq = ctx->seq; seq >= ctx->first_seq; seq--)
 		mail_index_expunge(ctx->trans, seq);
@@ -817,6 +875,9 @@ int maildir_transaction_save_commit_pre(
 	i_assert(_ctx->output == NULL);
 	i_assert(ctx->last_save_finished);
 
+	if (ctx->files_count == 0 && !array_is_created(&ctx->conflicts))
+		return 0;
+
 	sync_flags = MAILDIR_UIDLIST_SYNC_PARTIAL |
 		MAILDIR_UIDLIST_SYNC_NOREFRESH;
 
@@ -837,6 +898,7 @@ int maildir_transaction_save_commit_pre(
 			maildir_transaction_save_rollback(_ctx);
 			return -1;
 		}
+		maildir_sync_conflicts(ctx);
 	} else if (ret == 0 &&
 		   (sync_flags & MAILDIR_UIDLIST_SYNC_TRYLOCK) != 0) {
 		ctx->locked = FALSE;
@@ -909,6 +971,8 @@ void maildir_transaction_save_commit_pos
 
 	if (ctx->locked)
 		maildir_uidlist_unlock(ctx->mbox->uidlist);
+	if (array_is_created(&ctx->conflicts))
+		array_free(&ctx->conflicts);
 	pool_unref(&ctx->pool);
 }
 
@@ -933,5 +997,7 @@ void maildir_transaction_save_rollback(s
 
 	if (ctx->mail != NULL)
 		mail_free(&ctx->mail);
+	if (array_is_created(&ctx->conflicts))
+		array_free(&ctx->conflicts);
 	pool_unref(&ctx->pool);
 }
diff -r 64ab55223d69 -r 7315aa70dfcf src/lib-storage/index/maildir/maildir-storage.h
--- a/src/lib-storage/index/maildir/maildir-storage.h	Wed Aug 05 20:15:47 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-storage.h	Wed Aug 05 20:17:13 2009 -0400
@@ -121,6 +121,9 @@ int maildir_save_finish(struct mail_save
 int maildir_save_finish(struct mail_save_context *ctx);
 void maildir_save_cancel(struct mail_save_context *ctx);
 
+void maildir_save_add_conflict(struct mailbox_transaction_context *t,
+			       uint32_t old_uid, uint32_t new_uid);
+
 struct maildir_filename *
 maildir_save_add(struct mail_save_context *_ctx, const char *base_fname);
 const char *maildir_save_file_get_path(struct mailbox_transaction_context *t,


More information about the dovecot-cvs mailing list