static void ext_reset_update_atomic(struct mail_index_transaction *t, uint32_t ext_id, uint32_t expected_reset_id) { const struct mail_index_ext *map_ext; struct mail_transaction_ext_reset *reset; uint32_t idx, reset_id; if (!mail_index_map_get_ext_idx(t->view->index->map, ext_id, &idx)) { /* new extension */ reset_id = 1; } else { map_ext = array_idx(&t->view->index->map->extensions, idx); reset_id = map_ext->reset_id + 1; } if (reset_id != expected_reset_id) { /* ignore this extension update */ mail_index_ext_set_reset_id(t, ext_id, 0); return; } if (reset_id == 0) reset_id++; array_idx_set(&t->ext_reset_ids, ext_id, &reset_id); /* reseting existing data is optional */ if (array_is_created(&t->ext_resets)) { reset = array_idx_modifiable(&t->ext_resets, ext_id); if (reset->new_reset_id == (uint32_t)-1) reset->new_reset_id = reset_id; } }
static void log_append_ext_intro(struct mail_index_export_context *ctx, uint32_t ext_id, uint32_t reset_id) { struct mail_index_transaction *t = ctx->trans; const struct mail_index_registered_ext *rext; struct mail_transaction_ext_intro *intro, *resizes; buffer_t *buf; uint32_t idx; unsigned int count; i_assert(ext_id != (uint32_t)-1); if (t->reset || !mail_index_map_get_ext_idx(t->view->index->map, ext_id, &idx)) { /* new extension */ idx = (uint32_t)-1; } rext = array_idx(&t->view->index->extensions, ext_id); if (!array_is_created(&t->ext_resizes)) { resizes = NULL; count = 0; } else { resizes = array_get_modifiable(&t->ext_resizes, &count); } buf = buffer_create_dynamic(pool_datastack_create(), 128); if (ext_id < count && resizes[ext_id].name_size != 0) { /* we're resizing the extension. use the resize struct. */ intro = &resizes[ext_id]; i_assert(intro->ext_id == idx); intro->name_size = idx != (uint32_t)-1 ? 0 : strlen(rext->name); buffer_append(buf, intro, sizeof(*intro)); } else { /* generate a new intro structure */ intro = buffer_append_space_unsafe(buf, sizeof(*intro)); intro->ext_id = idx; intro->hdr_size = rext->hdr_size; intro->record_size = rext->record_size; intro->record_align = rext->record_align; intro->flags = MAIL_TRANSACTION_EXT_INTRO_FLAG_NO_SHRINK; intro->name_size = idx != (uint32_t)-1 ? 0 : strlen(rext->name); } if (reset_id != 0) { /* we're going to reset this extension in this transaction */ intro->reset_id = reset_id; } else if (idx != (uint32_t)-1) { /* use the existing reset_id */ const struct mail_index_ext *map_ext = array_idx(&t->view->index->map->extensions, idx); intro->reset_id = map_ext->reset_id; } else { /* new extension, reset_id defaults to 0 */ } buffer_append(buf, rext->name, intro->name_size); if ((buf->used % 4) != 0) buffer_append_zero(buf, 4 - (buf->used % 4)); if (ctx->append_ctx->new_highest_modseq == 0 && strcmp(rext->name, MAIL_INDEX_MODSEQ_EXT_NAME) == 0) { /* modseq tracking started */ ctx->append_ctx->new_highest_modseq = 1; } log_append_buffer(ctx, buf, MAIL_TRANSACTION_EXT_INTRO); }