mdbox-sync.c revision 8bdb2e6bb77bd40c891c39cd7911887bcfda656e
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainendbox_sync_verify_expunge_guid(struct mdbox_sync_context *ctx, uint32_t seq,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_lookup_uid(ctx->sync_view, seq, &uid);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen memcmp(data, guid_128, MAIL_GUID_128_SIZE) == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_storage_set_critical(&ctx->mbox->storage->storage.storage,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "Mailbox %s: Expunged GUID mismatch for UID %u: %s vs %s",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->mbox->storage->storage.files_corrupted = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int mdbox_sync_expunge(struct mdbox_sync_context *ctx, uint32_t seq,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (seq_range_exists(&ctx->expunged_seqs, seq)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* already marked as expunged in this sync */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (dbox_sync_verify_expunge_guid(ctx, seq, guid_128) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mdbox_mail_lookup(ctx->mbox, ctx->sync_view, seq, &map_uid) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen seq_range_array_add(&ctx->expunged_seqs, 0, seq);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen array_append(&ctx->expunged_map_uids, &map_uid, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int mdbox_sync_add(struct mdbox_sync_context *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (sync_rec->type != MAIL_INDEX_SYNC_TYPE_EXPUNGE) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* not interested */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!mail_index_lookup_seq_range(ctx->sync_view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* already expunged everything. nothing to do. */
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen if (mdbox_sync_expunge(ctx, seq, sync_rec->guid_128) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int dbox_sync_mark_expunges(struct mdbox_sync_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int n;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* use a separate transaction here so that we can commit the changes
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen during map transaction */
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen trans = mail_index_transaction_begin(ctx->sync_view, flags);
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen seq_range_array_iter_init(&iter, &ctx->expunged_seqs); n = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen while (seq_range_array_iter_nth(&iter, n++, &seq)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_lookup_uid(ctx->sync_view, seq, &uid);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_transaction_commit(&trans) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* do notifications after commit finished successfully */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen seq_range_array_iter_init(&iter, &ctx->expunged_seqs); n = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen while (seq_range_array_iter_nth(&iter, n++, &seq)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_lookup_uid(ctx->sync_view, seq, &uid);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen box->v.sync_notify(box, uid, MAILBOX_SYNC_TYPE_EXPUNGE);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int mdbox_sync_index_finish_expunges(struct mdbox_sync_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct dbox_map_transaction_context *map_trans;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen map_trans = dbox_map_transaction_begin(ctx->mbox->storage->map, FALSE);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = dbox_map_update_refcounts(map_trans, &ctx->expunged_map_uids, -1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* write refcount changes to map index */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* write changes to mailbox index */
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen /* this finally finishes the map sync and makes it clear that the
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen map transaction was successfully finished. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int mdbox_sync_index(struct mdbox_sync_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* newly created index file */
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen /* mark the newly seen messages as recent */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_lookup_seq_range(ctx->sync_view, hdr->first_recent_uid,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index_mailbox_set_recent_seq(&ctx->mbox->box, ctx->sync_view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* read all changes and group changes to same file_id together */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen while (mail_index_sync_next(ctx->index_sync_ctx, &sync_rec)) {
439980f88f421039dea8335e92d3fa82b3f470a1Timo Sirainen if ((ret = mdbox_sync_add(ctx, &sync_rec)) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret == 0 && array_count(&ctx->expunged_seqs) > 0)
int ret;
if (ret == 0) {
} else if (retry) {
return ret;
int ret;
if (rebuild) {
if (ret <= 0) {
if (ret < 0)
return ret;
ret = 0;
if (ret == 0) {
if (!storage_rebuilt) {
if (ret < 0) {
if (success) {
return ret;
struct mailbox_sync_context *
int ret = 0;
struct dirent *d;
int ret = 0;
&file_id) < 0)
if (errno != 0) {
return ret;
bool deleted;
int ret = 0;
} T_END;
return ret;