dovecot-2.2: lib-storage: Saving/copying no longer discards priv...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Feb 19 08:27:50 EET 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/02529503c59c
changeset: 15835:02529503c59c
user: Timo Sirainen <tss at iki.fi>
date: Tue Feb 19 08:27:40 2013 +0200
description:
lib-storage: Saving/copying no longer discards private message flags.
diffstat:
src/lib-storage/index/index-sync-private.h | 14 +-
src/lib-storage/index/index-sync-pvt.c | 266 ++++++++++++++++++++--------
src/lib-storage/index/index-sync.c | 9 +-
src/lib-storage/index/index-transaction.c | 17 +
src/lib-storage/mail-storage-private.h | 13 +
src/lib-storage/mail-storage.c | 51 ++++-
src/plugins/acl/acl-mailbox.c | 20 +-
src/plugins/virtual/virtual-save.c | 3 +-
8 files changed, 293 insertions(+), 100 deletions(-)
diffs (truncated from 716 to 300 lines):
diff -r be857a95b381 -r 02529503c59c src/lib-storage/index/index-sync-private.h
--- a/src/lib-storage/index/index-sync-private.h Tue Feb 19 08:17:50 2013 +0200
+++ b/src/lib-storage/index/index-sync-private.h Tue Feb 19 08:27:40 2013 +0200
@@ -3,6 +3,8 @@
#include "index-storage.h"
+struct index_mailbox_sync_pvt_context;
+
struct index_mailbox_sync_context {
struct mailbox_sync_context ctx;
@@ -22,8 +24,14 @@
void index_sync_search_results_update(struct index_mailbox_sync_context *ctx);
void index_sync_search_results_expunge(struct index_mailbox_sync_context *ctx);
-int index_storage_mailbox_sync_pvt(struct mailbox *box,
- ARRAY_TYPE(seq_range) *flag_updates,
- ARRAY_TYPE(seq_range) *hidden_updates);
+/* Returns 1 = ok, 0 = no private indexes, -1 = error */
+int index_mailbox_sync_pvt_init(struct mailbox *box, bool lock,
+ struct index_mailbox_sync_pvt_context **ctx_r);
+int index_mailbox_sync_pvt_newmails(struct index_mailbox_sync_pvt_context *ctx,
+ struct mailbox_transaction_context *trans);
+int index_mailbox_sync_pvt_view(struct index_mailbox_sync_pvt_context *ctx,
+ ARRAY_TYPE(seq_range) *flag_updates,
+ ARRAY_TYPE(seq_range) *hidden_updates);
+void index_mailbox_sync_pvt_deinit(struct index_mailbox_sync_pvt_context **ctx);
#endif
diff -r be857a95b381 -r 02529503c59c src/lib-storage/index/index-sync-pvt.c
--- a/src/lib-storage/index/index-sync-pvt.c Tue Feb 19 08:17:50 2013 +0200
+++ b/src/lib-storage/index/index-sync-pvt.c Tue Feb 19 08:27:40 2013 +0200
@@ -4,31 +4,37 @@
#include "mailbox-list-private.h"
#include "index-sync-private.h"
-static int sync_pvt_expunges(struct mailbox *box,
- struct mail_index_view *view_pvt,
- struct mail_index_transaction *trans_pvt,
- struct mail_index_view *view_shared)
+struct index_mailbox_sync_pvt_context {
+ struct mailbox *box;
+
+ struct mail_index_sync_ctx *sync_ctx;
+ struct mail_index_view *view_pvt;
+ struct mail_index_transaction *trans_pvt;
+ struct mail_index_view *view_shared;
+};
+
+static int sync_pvt_expunges(struct index_mailbox_sync_pvt_context *ctx)
{
uint32_t seq_shared, seq_pvt, count_shared, count_pvt;
uint32_t uid_shared, uid_pvt;
- count_shared = mail_index_view_get_messages_count(view_shared);
- count_pvt = mail_index_view_get_messages_count(view_pvt);
+ count_shared = mail_index_view_get_messages_count(ctx->view_shared);
+ count_pvt = mail_index_view_get_messages_count(ctx->view_pvt);
seq_shared = seq_pvt = 1;
while (seq_pvt <= count_pvt && seq_shared <= count_shared) {
- mail_index_lookup_uid(view_pvt, seq_pvt, &uid_pvt);
- mail_index_lookup_uid(view_shared, seq_shared, &uid_shared);
+ mail_index_lookup_uid(ctx->view_pvt, seq_pvt, &uid_pvt);
+ mail_index_lookup_uid(ctx->view_shared, seq_shared, &uid_shared);
if (uid_pvt == uid_shared) {
seq_pvt++;
seq_shared++;
} else if (uid_pvt < uid_shared) {
/* message expunged */
- mail_index_expunge(trans_pvt, seq_pvt);
+ mail_index_expunge(ctx->trans_pvt, seq_pvt);
seq_pvt++;
} else {
- mail_storage_set_critical(box->storage,
+ mail_storage_set_critical(ctx->box->storage,
"%s: Message UID=%u unexpectedly inserted to mailbox",
- box->index_pvt->filepath, uid_shared);
+ ctx->box->index_pvt->filepath, uid_shared);
return -1;
}
}
@@ -36,78 +42,122 @@
}
static void
-sync_pvt_copy_self_flags(struct mailbox *box,
- struct mail_index_view *view,
- struct mail_index_transaction *trans,
+sync_pvt_copy_self_flags(struct index_mailbox_sync_pvt_context *ctx,
ARRAY_TYPE(keyword_indexes) *keywords,
uint32_t seq_old, uint32_t seq_new)
{
const struct mail_index_record *old_rec;
- old_rec = mail_index_lookup(view, seq_old);
- mail_index_lookup_keywords(view, seq_old, keywords);
+ old_rec = mail_index_lookup(ctx->view_pvt, seq_old);
+ mail_index_lookup_keywords(ctx->view_pvt, seq_old, keywords);
if (old_rec->flags != 0) {
- mail_index_update_flags(trans, seq_new,
+ mail_index_update_flags(ctx->trans_pvt, seq_new,
MODIFY_ADD, old_rec->flags);
}
if (array_count(keywords) > 0) {
struct mail_keywords *kw;
- kw = mail_index_keywords_create_from_indexes(box->index_pvt,
+ kw = mail_index_keywords_create_from_indexes(ctx->box->index_pvt,
keywords);
- mail_index_update_keywords(trans, seq_new, MODIFY_ADD, kw);
+ mail_index_update_keywords(ctx->trans_pvt, seq_new,
+ MODIFY_ADD, kw);
mail_index_keywords_unref(&kw);
}
}
static int
-index_storage_mailbox_sync_pvt_index(struct mailbox *box)
+index_mailbox_sync_view_refresh(struct index_mailbox_sync_pvt_context *ctx)
{
- struct mail_index_sync_ctx *sync_ctx;
- struct mail_index_view *view_pvt;
- struct mail_index_transaction *trans_pvt;
+ /* open a view for the latest version of the index */
+ if (mail_index_refresh(ctx->box->index_pvt) < 0 ||
+ mail_index_refresh(ctx->box->index) < 0) {
+ mailbox_set_index_error(ctx->box);
+ return -1;
+ }
+ if (ctx->view_shared != NULL)
+ mail_index_view_close(&ctx->view_shared);
+ ctx->view_shared = mail_index_view_open(ctx->box->index);
+ return 0;
+}
+
+static int
+index_mailbox_sync_open(struct index_mailbox_sync_pvt_context *ctx, bool force)
+{
const struct mail_index_header *hdr_shared, *hdr_pvt;
- struct mail_index_view *view_shared;
+
+ if (index_mailbox_sync_view_refresh(ctx) < 0)
+ return -1;
+
+ hdr_shared = mail_index_get_header(ctx->view_shared);
+ if (hdr_shared->uid_validity == 0 && !force) {
+ /* the mailbox hasn't been fully created yet,
+ no need for a private index yet */
+ return 0;
+ }
+ hdr_pvt = mail_index_get_header(ctx->box->view_pvt);
+ if (hdr_pvt->next_uid == hdr_shared->next_uid &&
+ hdr_pvt->messages_count == hdr_shared->messages_count && !force) {
+ /* no new or expunged mails, don't bother syncing */
+ return 0;
+ }
+ if (mail_index_sync_begin(ctx->box->index_pvt, &ctx->sync_ctx,
+ &ctx->view_pvt, &ctx->trans_pvt, 0) < 0) {
+ mailbox_set_index_error(ctx->box);
+ return -1;
+ }
+ /* refresh once more now that we're locked */
+ if (index_mailbox_sync_view_refresh(ctx) < 0)
+ return -1;
+ return 1;
+}
+
+int index_mailbox_sync_pvt_init(struct mailbox *box, bool lock,
+ struct index_mailbox_sync_pvt_context **ctx_r)
+{
+ struct index_mailbox_sync_pvt_context *ctx;
+ int ret;
+
+ *ctx_r = NULL;
+
+ if ((ret = mailbox_open_index_pvt(box)) <= 0)
+ return ret;
+
+ ctx = i_new(struct index_mailbox_sync_pvt_context, 1);
+ ctx->box = box;
+ if (lock) {
+ if (index_mailbox_sync_open(ctx, TRUE) < 0) {
+ index_mailbox_sync_pvt_deinit(&ctx);
+ return -1;
+ }
+ }
+
+ *ctx_r = ctx;
+ return 1;
+}
+
+static int
+index_mailbox_sync_pvt_index(struct index_mailbox_sync_pvt_context *ctx,
+ const struct mail_save_private_changes *pvt_changes,
+ unsigned int pvt_changes_count)
+{
+ const struct mail_index_header *hdr_shared, *hdr_pvt;
ARRAY_TYPE(keyword_indexes) keywords;
uint32_t seq_shared, seq_pvt, seq_old_pvt, seq2, count_shared, uid;
+ unsigned int pc_idx = 0;
bool reset = FALSE, preserve_old_flags = FALSE;
int ret;
- /* open a view for the latest version of the index */
- if (mail_index_refresh(box->index) < 0 ||
- mail_index_refresh(box->index_pvt) < 0) {
- mailbox_set_index_error(box);
- return -1;
+ if (ctx->sync_ctx == NULL) {
+ if ((ret = index_mailbox_sync_open(ctx, FALSE)) <= 0)
+ return ret;
}
- view_shared = mail_index_view_open(box->index);
- hdr_shared = mail_index_get_header(view_shared);
- if (hdr_shared->uid_validity == 0) {
- /* the mailbox hasn't been fully created yet,
- no need for a private index yet */
- mail_index_view_close(&view_shared);
- return 0;
- }
- hdr_pvt = mail_index_get_header(box->view_pvt);
- if (hdr_pvt->next_uid == hdr_shared->next_uid &&
- hdr_pvt->messages_count == hdr_shared->messages_count) {
- /* no new or expunged mails, don't bother syncing */
- mail_index_view_close(&view_shared);
- return 0;
- }
-
- if (mail_index_sync_begin(box->index_pvt, &sync_ctx,
- &view_pvt, &trans_pvt, 0) < 0) {
- mailbox_set_index_error(box);
- mail_index_view_close(&view_shared);
- return -1;
- }
- /* get an updated private header */
- hdr_pvt = mail_index_get_header(view_pvt);
+ hdr_pvt = mail_index_get_header(ctx->view_pvt);
+ hdr_shared = mail_index_get_header(ctx->view_shared);
if (hdr_shared->uid_validity == hdr_pvt->uid_validity) {
/* same mailbox. expunge messages from private index that
no longer exist. */
- if (sync_pvt_expunges(box, view_pvt, trans_pvt, view_shared) < 0) {
+ if (sync_pvt_expunges(ctx) < 0) {
reset = TRUE;
preserve_old_flags = TRUE;
t_array_init(&keywords, 32);
@@ -117,17 +167,18 @@
reset = TRUE;
}
- count_shared = mail_index_view_get_messages_count(view_shared);
+ count_shared = mail_index_view_get_messages_count(ctx->view_shared);
if (!reset) {
- if (!mail_index_lookup_seq_range(view_shared, hdr_pvt->next_uid,
+ if (!mail_index_lookup_seq_range(ctx->view_shared,
+ hdr_pvt->next_uid,
hdr_shared->next_uid,
&seq_shared, &seq2)) {
/* no new messages */
seq_shared = count_shared+1;
}
} else {
- mail_index_reset(trans_pvt);
- mail_index_update_header(trans_pvt,
+ mail_index_reset(ctx->trans_pvt);
+ mail_index_update_header(ctx->trans_pvt,
offsetof(struct mail_index_header, uid_validity),
&hdr_shared->uid_validity,
sizeof(hdr_shared->uid_validity), TRUE);
@@ -136,56 +187,100 @@
uid = 0;
for (; seq_shared <= count_shared; seq_shared++) {
- mail_index_lookup_uid(view_shared, seq_shared, &uid);
- mail_index_append(trans_pvt, uid, &seq_pvt);
+ mail_index_lookup_uid(ctx->view_shared, seq_shared, &uid);
+ mail_index_append(ctx->trans_pvt, uid, &seq_pvt);
if (preserve_old_flags &&
- mail_index_lookup_seq(view_pvt, uid, &seq_old_pvt)) {
- /* copy flags from the original index */
- sync_pvt_copy_self_flags(box, view_pvt, trans_pvt,
- &keywords,
+ mail_index_lookup_seq(ctx->view_pvt, uid, &seq_old_pvt)) {
+ /* copy flags from the original private index */
+ sync_pvt_copy_self_flags(ctx, &keywords,
seq_old_pvt, seq_pvt);
}
+ /* add private flags for the recently saved/copied messages */
+ while (pc_idx < pvt_changes_count &&
+ pvt_changes[pc_idx].mailnum <= uid) {
+ if (pvt_changes[pc_idx].mailnum == uid) {
+ mail_index_update_flags(ctx->trans_pvt, seq_pvt,
+ MODIFY_ADD, pvt_changes[pc_idx].flags);
+ }
+ pc_idx++;
+ }
}
More information about the dovecot-cvs
mailing list