void index_transaction_init(struct mailbox_transaction_context *t, struct mailbox *box, enum mailbox_transaction_flags flags) { enum mail_index_transaction_flags itrans_flags; i_assert(box->opened); itrans_flags = index_transaction_flags_get(flags); if ((flags & MAILBOX_TRANSACTION_FLAG_REFRESH) != 0) mail_index_refresh(box->index); t->box = box; t->itrans = mail_index_transaction_begin(box->view, itrans_flags); t->view = mail_index_transaction_open_updated_view(t->itrans); array_create(&t->module_contexts, default_pool, sizeof(void *), 5); t->cache_view = mail_cache_view_open(box->cache, t->view); t->cache_trans = mail_cache_get_transaction(t->cache_view, t->itrans); if ((flags & MAILBOX_TRANSACTION_FLAG_NO_CACHE_DEC) != 0) mail_cache_view_update_cache_decisions(t->cache_view, FALSE); /* set up after mail_cache_get_transaction(), so that we'll still have the cache_trans available in _index_commit() */ t->super = t->itrans->v; t->itrans->v.commit = index_transaction_index_commit; t->itrans->v.rollback = index_transaction_index_rollback; MODULE_CONTEXT_SET(t->itrans, mail_storage_mail_index_module, t); }
mdbox_write_index_header(struct mailbox *box, const struct mailbox_update *update, struct mail_index_transaction *trans) { struct mdbox_mailbox *mbox = (struct mdbox_mailbox *)box; struct mail_index_transaction *new_trans = NULL; struct mail_index_view *view; const struct mail_index_header *hdr; uint32_t uid_validity, uid_next; if (mdbox_map_open_or_create(mbox->storage->map) < 0) return -1; if (trans == NULL) { new_trans = mail_index_transaction_begin(box->view, 0); trans = new_trans; } view = mail_index_view_open(box->index); hdr = mail_index_get_header(view); uid_validity = hdr->uid_validity; if (update != NULL && update->uid_validity != 0) uid_validity = update->uid_validity; else if (uid_validity == 0) { /* set uidvalidity */ uid_validity = dbox_get_uidvalidity_next(box->list); } if (hdr->uid_validity != uid_validity) { mail_index_update_header(trans, offsetof(struct mail_index_header, uid_validity), &uid_validity, sizeof(uid_validity), TRUE); }
void mailbox_list_index_refresh_later(struct mailbox_list *list) { struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list); struct mailbox_list_index_header new_hdr; struct mail_index_view *view; struct mail_index_transaction *trans; if (!ilist->has_backing_store) return; (void)mailbox_list_index_index_open(list); view = mail_index_view_open(ilist->index); if (!mailbox_list_index_need_refresh(ilist, view)) { new_hdr.refresh_flag = 1; trans = mail_index_transaction_begin(view, MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL); mail_index_update_header_ext(trans, ilist->ext_id, offsetof(struct mailbox_list_index_header, refresh_flag), &new_hdr.refresh_flag, sizeof(new_hdr.refresh_flag)); if (mail_index_transaction_commit(&trans) < 0) mail_index_mark_corrupted(ilist->index); }
int sdbox_mailbox_create_indexes(struct mailbox *box, const struct mailbox_update *update, struct mail_index_transaction *trans) { struct sdbox_mailbox *mbox = SDBOX_MAILBOX(box); struct mail_index_transaction *new_trans = NULL; const struct mail_index_header *hdr; uint32_t uid_validity, uid_next; if (trans == NULL) { new_trans = mail_index_transaction_begin(box->view, 0); trans = new_trans; } hdr = mail_index_get_header(box->view); if (update != NULL && update->uid_validity != 0) uid_validity = update->uid_validity; else if (hdr->uid_validity != 0) uid_validity = hdr->uid_validity; else { /* set uidvalidity */ uid_validity = dbox_get_uidvalidity_next(box->list); } if (hdr->uid_validity != uid_validity) { mail_index_update_header(trans, offsetof(struct mail_index_header, uid_validity), &uid_validity, sizeof(uid_validity), TRUE); }
static int index_storage_mailbox_update_pvt(struct mailbox *box, const struct mailbox_update *update) { struct mail_index_transaction *trans; struct mail_index_view *view; int ret; if ((ret = mailbox_open_index_pvt(box)) <= 0) return ret; mail_index_refresh(box->index_pvt); view = mail_index_view_open(box->index_pvt); trans = mail_index_transaction_begin(view, MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL); if (update->min_highest_modseq != 0 && mail_index_modseq_get_highest(view) < update->min_highest_pvt_modseq) { mail_index_modseq_enable(box->index_pvt); mail_index_update_highest_modseq(trans, update->min_highest_pvt_modseq); } if ((ret = mail_index_transaction_commit(&trans)) < 0) mailbox_set_index_error(box); mail_index_view_close(&view); return ret; }
int index_storage_mailbox_update(struct mailbox *box, const struct mailbox_update *update) { const struct mail_index_header *hdr; struct mail_index_view *view; struct mail_index_transaction *trans; int ret; if (mailbox_open(box) < 0) return -1; /* make sure we get the latest index info */ mail_index_refresh(box->index); view = mail_index_view_open(box->index); hdr = mail_index_get_header(view); trans = mail_index_transaction_begin(view, MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL); if (update->uid_validity != 0 && hdr->uid_validity != update->uid_validity) { uint32_t uid_validity = update->uid_validity; if (hdr->uid_validity != 0) { /* UIDVALIDITY change requires index to be reset */ mail_index_reset(trans); } mail_index_update_header(trans, offsetof(struct mail_index_header, uid_validity), &uid_validity, sizeof(uid_validity), TRUE); }
void index_transaction_init(struct index_transaction_context *it, struct mailbox *box, enum mailbox_transaction_flags flags) { struct mailbox_transaction_context *t = &it->mailbox_ctx; enum mail_index_transaction_flags trans_flags; i_assert(box->opened); trans_flags = MAIL_INDEX_TRANSACTION_FLAG_AVOID_FLAG_UPDATES; if ((flags & MAILBOX_TRANSACTION_FLAG_HIDE) != 0) trans_flags |= MAIL_INDEX_TRANSACTION_FLAG_HIDE; if ((flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0) trans_flags |= MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL; if ((flags & MAILBOX_TRANSACTION_FLAG_REFRESH) != 0) (void)mail_index_refresh(box->index); t->box = box; t->itrans = mail_index_transaction_begin(box->view, trans_flags); t->view = mail_index_transaction_open_updated_view(t->itrans); array_create(&t->module_contexts, default_pool, sizeof(void *), 5); it->cache_view = mail_cache_view_open(box->cache, t->view); it->cache_trans = mail_cache_get_transaction(it->cache_view, t->itrans); /* set up after mail_cache_get_transaction(), so that we'll still have the cache_trans available in _index_commit() */ it->super = t->itrans->v; t->itrans->v.commit = index_transaction_index_commit; t->itrans->v.rollback = index_transaction_index_rollback; MODULE_CONTEXT_SET(t->itrans, mail_storage_mail_index_module, it); }
void index_transaction_init_pvt(struct mailbox_transaction_context *t) { enum mail_index_transaction_flags itrans_flags; if (t->box->view_pvt == NULL || t->itrans_pvt != NULL) return; itrans_flags = index_transaction_flags_get(t->flags); t->itrans_pvt = mail_index_transaction_begin(t->box->view_pvt, itrans_flags); t->view_pvt = mail_index_transaction_open_updated_view(t->itrans_pvt); }
static int index_list_update(struct index_mailbox_list *ilist, struct mailbox *box, struct mail_index_view *view, uint32_t seq, const struct mailbox_status *status) { struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box); struct mail_index_transaction *trans; struct mail_index_transaction_commit_result result; const void *data; const uint32_t *counter_p; uint32_t *ext_id_p; unsigned int i; bool expunged; int ret = 0; trans = mail_index_transaction_begin(view, MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL); /* update counters */ for (i = 0; index_list_map[i].name != NULL; i++) { ext_id_p = PTR_OFFSET(ilist, index_list_map[i].eid_offset); mail_index_lookup_ext(view, seq, *ext_id_p, &data, &expunged); if (expunged) { ret = -1; break; } counter_p = CONST_PTR_OFFSET(status, index_list_map[i].status_offset); if (data == NULL || *(const uint32_t *)data != *counter_p) { mail_index_update_ext(trans, seq, *ext_id_p, counter_p, NULL); } } if (box->v.list_index_update_sync(box, trans, seq) < 0) ret = -1; if (ret < 0) { mail_index_transaction_rollback(&trans); return -1; } if (mail_index_transaction_commit_full(&trans, &result) < 0) return -1; ibox->log_seq = result.log_file_seq; ibox->log_offset = result.log_file_offset; return 0; }
static void imapc_mailbox_init_delayed_trans(struct imapc_mailbox *mbox) { if (mbox->delayed_sync_trans != NULL) return; i_assert(mbox->delayed_sync_cache_view == NULL); i_assert(mbox->delayed_sync_cache_trans == NULL); mbox->delayed_sync_trans = mail_index_transaction_begin(imapc_mailbox_get_sync_view(mbox), MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL); mbox->delayed_sync_view = mail_index_transaction_open_updated_view(mbox->delayed_sync_trans); mbox->delayed_sync_cache_view = mail_cache_view_open(mbox->box.cache, mbox->delayed_sync_view); mbox->delayed_sync_cache_trans = mail_cache_get_transaction(mbox->delayed_sync_cache_view, mbox->delayed_sync_trans); }
static int imapc_mailbox_commit_delayed_expunges(struct imapc_mailbox *mbox) { struct mail_index_view *view = imapc_mailbox_get_sync_view(mbox); struct mail_index_transaction *trans; struct seq_range_iter iter; unsigned int n; uint32_t lseq, uid; int ret; trans = mail_index_transaction_begin(view, MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL); seq_range_array_iter_init(&iter, &mbox->delayed_expunged_uids); n = 0; while (seq_range_array_iter_nth(&iter, n++, &uid)) { if (mail_index_lookup_seq(view, uid, &lseq)) mail_index_expunge(trans, lseq); } array_clear(&mbox->delayed_expunged_uids); ret = mail_index_transaction_commit(&trans); if (ret < 0) mailbox_set_index_error(&mbox->box); return ret; }
static int dbox_sync_mark_expunges(struct mdbox_sync_context *ctx) { enum mail_index_transaction_flags flags = MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL; struct mailbox *box = &ctx->mbox->box; struct mail_index_transaction *trans; struct seq_range_iter iter; unsigned int n; const void *data; uint32_t seq, uid; /* use a separate transaction here so that we can commit the changes during map transaction */ trans = mail_index_transaction_begin(ctx->sync_view, flags); seq_range_array_iter_init(&iter, &ctx->expunged_seqs); n = 0; while (seq_range_array_iter_nth(&iter, n++, &seq)) { mail_index_lookup_uid(ctx->sync_view, seq, &uid); mail_index_lookup_ext(ctx->sync_view, seq, ctx->mbox->guid_ext_id, &data, NULL); mail_index_expunge_guid(trans, seq, data); } if (mail_index_transaction_commit(&trans) < 0) return -1; if (box->v.sync_notify != NULL) { /* do notifications after commit finished successfully */ box->tmp_sync_view = ctx->sync_view; seq_range_array_iter_init(&iter, &ctx->expunged_seqs); n = 0; while (seq_range_array_iter_nth(&iter, n++, &seq)) { mail_index_lookup_uid(ctx->sync_view, seq, &uid); box->v.sync_notify(box, uid, MAILBOX_SYNC_TYPE_EXPUNGE); } box->tmp_sync_view = NULL; } return 0; }
static int mdbox_deleted_mailbox_create_indexes(struct mailbox *box, const struct mailbox_update *update, struct mail_index_transaction *trans) { struct mdbox_mailbox *mbox = (struct mdbox_mailbox *)box; struct mail_index_transaction *new_trans = NULL; uint32_t uid_validity = ioloop_time; uint32_t uid_next = 1; if (update != NULL && update->uid_validity != 0) uid_validity = update->uid_validity; if (trans == NULL) { new_trans = mail_index_transaction_begin(box->view, 0); trans = new_trans; } mail_index_update_header(trans, offsetof(struct mail_index_header, uid_validity), &uid_validity, sizeof(uid_validity), TRUE); mail_index_update_header(trans, offsetof(struct mail_index_header, next_uid), &uid_next, sizeof(uid_next), TRUE); mbox->creating = TRUE; mdbox_update_header(mbox, trans, update); mbox->creating = FALSE; if (new_trans != NULL) { if (mail_index_transaction_commit(&new_trans) < 0) { mailbox_set_index_error(box); return -1; } } return 0; }