static int index_list_update_mail_index(struct index_mailbox_list *ilist, struct mailbox *box) { struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box); struct mail_index_sync_ctx *mail_sync_ctx; struct mail_index_view *view; struct mail_index_transaction *trans; struct mail_index_sync_rec sync_rec; int ret; if (ibox->log_seq == 0) return 0; ret = mail_index_sync_begin_to(ilist->mail_index, &mail_sync_ctx, &view, &trans, ibox->log_seq, ibox->log_offset, 0); if (ret <= 0) return ret; /* we should have only external transactions in here, for which we don't need to do anything but write them to the index */ while (mail_index_sync_next(mail_sync_ctx, &sync_rec)) ; return mail_index_sync_commit(&mail_sync_ctx); }
static int mdbox_sync_index(struct mdbox_sync_context *ctx) { struct mailbox *box = &ctx->mbox->box; const struct mail_index_header *hdr; struct mail_index_sync_rec sync_rec; uint32_t seq1, seq2; int ret = 0; hdr = mail_index_get_header(ctx->sync_view); if (hdr->uid_validity == 0) { /* newly created index file */ mail_storage_set_critical(box->storage, "Mailbox %s: Corrupted index, uidvalidity=0", box->vname); return 0; } /* mark the newly seen messages as recent */ if (mail_index_lookup_seq_range(ctx->sync_view, hdr->first_recent_uid, hdr->next_uid, &seq1, &seq2)) { index_mailbox_set_recent_seq(&ctx->mbox->box, ctx->sync_view, seq1, seq2); } /* handle syncing records without map being locked. */ if (mdbox_map_atomic_is_locked(ctx->atomic)) { ctx->map_trans = mdbox_map_transaction_begin(ctx->atomic, FALSE); i_array_init(&ctx->expunged_seqs, 64); } while (mail_index_sync_next(ctx->index_sync_ctx, &sync_rec)) { if ((ret = mdbox_sync_rec(ctx, &sync_rec)) < 0) break; } /* write refcount changes to map index. transaction commit updates the log head, while tail is left behind. */ if (mdbox_map_atomic_is_locked(ctx->atomic)) { if (ret == 0) ret = mdbox_map_transaction_commit(ctx->map_trans); /* write changes to mailbox index */ if (ret == 0) ret = dbox_sync_mark_expunges(ctx); /* finish the map changes and unlock the map. this also updates map's tail -> head. */ if (ret < 0) mdbox_map_atomic_set_failed(ctx->atomic); mdbox_map_transaction_free(&ctx->map_trans); array_free(&ctx->expunged_seqs); } if (box->v.sync_notify != NULL) box->v.sync_notify(box, 0, 0); return ret == 0 ? 1 : (ctx->mbox->storage->corrupted ? 0 : -1); }
static void cydir_sync_index(struct cydir_sync_context *ctx) { struct mailbox *box = &ctx->mbox->box; const struct mail_index_header *hdr; struct mail_index_sync_rec sync_rec; uint32_t seq1, seq2; hdr = mail_index_get_header(ctx->sync_view); if (hdr->uid_validity != 0) ctx->uid_validity = hdr->uid_validity; else cydir_sync_set_uidvalidity(ctx); /* mark the newly seen messages as recent */ if (mail_index_lookup_seq_range(ctx->sync_view, hdr->first_recent_uid, hdr->next_uid, &seq1, &seq2)) { mailbox_recent_flags_set_seqs(&ctx->mbox->box, ctx->sync_view, seq1, seq2); } while (mail_index_sync_next(ctx->index_sync_ctx, &sync_rec)) { if (!mail_index_lookup_seq_range(ctx->sync_view, sync_rec.uid1, sync_rec.uid2, &seq1, &seq2)) { /* already expunged, nothing to do. */ continue; } switch (sync_rec.type) { case MAIL_INDEX_SYNC_TYPE_EXPUNGE: cydir_sync_expunge(ctx, seq1, seq2); break; case MAIL_INDEX_SYNC_TYPE_FLAGS: case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD: case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE: /* FIXME: should be bother calling sync_notify()? */ break; } } if (box->v.sync_notify != NULL) box->v.sync_notify(box, 0, 0); }
void index_sync_changes_read(struct index_sync_changes_context *ctx, uint32_t uid, bool *sync_expunge_r, guid_128_t expunged_guid_128_r) { struct mail_index_sync_rec *sync_rec = &ctx->sync_rec; uint32_t seq1, seq2; unsigned int orig_count; *sync_expunge_r = FALSE; index_sync_changes_delete_to(ctx, uid); orig_count = array_count(&ctx->syncs); while (uid >= sync_rec->uid1) { if (uid <= sync_rec->uid2) { array_append(&ctx->syncs, sync_rec, 1); if (sync_rec->type == MAIL_INDEX_SYNC_TYPE_EXPUNGE) { *sync_expunge_r = TRUE; memcpy(expunged_guid_128_r, sync_rec->guid_128, GUID_128_SIZE); } } if (!mail_index_sync_next(ctx->index_sync_ctx, sync_rec)) { memset(sync_rec, 0, sizeof(*sync_rec)); break; } switch (sync_rec->type) { case MAIL_INDEX_SYNC_TYPE_EXPUNGE: break; case MAIL_INDEX_SYNC_TYPE_FLAGS: case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD: case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE: if (!ctx->dirty_flag_updates) break; /* mark the changes as dirty */ (void)mail_index_lookup_seq_range(ctx->sync_view, sync_rec->uid1, sync_rec->uid2, &seq1, &seq2); memset(sync_rec, 0, sizeof(*sync_rec)); if (seq1 == 0) break; mail_index_update_flags_range(ctx->sync_trans, seq1, seq2, MODIFY_ADD, (enum mail_flags)MAIL_INDEX_MAIL_FLAG_DIRTY); break; } } if (!*sync_expunge_r && orig_count > 0) { *sync_expunge_r = index_sync_changes_have_expunges(ctx, orig_count, expunged_guid_128_r); } }