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