int index_transaction_commit(struct mailbox_transaction_context *t, struct mail_transaction_commit_changes *changes_r) { struct mailbox *box = t->box; struct mail_index_transaction *itrans = t->itrans; struct mail_index_transaction_commit_result result; int ret = 0; memset(changes_r, 0, sizeof(*changes_r)); changes_r->pool = pool_alloconly_create(MEMPOOL_GROWING "transaction changes", 512); p_array_init(&changes_r->saved_uids, changes_r->pool, 32); t->changes = changes_r; if (t->itrans_pvt != NULL) ret = mail_index_transaction_commit(&t->itrans_pvt); if (mail_index_transaction_commit_full(&itrans, &result) < 0) ret = -1; t = NULL; if (ret < 0 && mail_index_is_deleted(box->index)) mailbox_set_deleted(box); changes_r->ignored_modseq_changes = result.ignored_modseq_changes; return ret; }
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; }