mail-transaction-log-append.c revision 0d0451206a91e9f96e522075dce28a89adc2325d
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainenstatic int log_append_buffer(struct mail_transaction_log_file *file,
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen enum mail_transaction_type type, int external)
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen i_assert((type & MAIL_TRANSACTION_TYPE_MASK) != 0);
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen hdr_data = buffer_get_data(hdr_buf, &hdr_data_size);
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen hdr_size = mail_index_uint32_to_offset(sizeof(hdr) + size +
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen if (!MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) {
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen /* size will be written later once everything
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen is in disk */
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen if (pwrite_full(file->fd, data, size, offset) < 0)
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen /* write failure. */
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen mail_index_file_set_syscall_error(file->log->index,
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen "pwrite_full()");
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen /* not enough space. fallback to in-memory indexes. */
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen if (mail_index_move_to_memory(file->log->index) < 0)
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen i_assert(MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file));
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen i_assert(file->buffer_offset + file->buffer->used ==
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen buffer_append(file->buffer, &hdr, sizeof(hdr));
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen buffer_append(file->buffer, hdr_data, hdr_data_size);
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen file->sync_offset = file->buffer_offset + file->buffer->used;
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainenlog_get_hdr_update_buffer(struct mail_index_transaction *t, int prepend)
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen memset(&u, 0, sizeof(u));
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen data = prepend ? t->pre_hdr_change : t->post_hdr_change;
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen mask = prepend ? t->pre_hdr_mask : t->post_hdr_mask;
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen buf = buffer_create_dynamic(pool_datastack_create(), 256);
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen for (offset = 0; offset <= sizeof(t->pre_hdr_change); offset++) {
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen if (offset < sizeof(t->pre_hdr_change) && mask[offset]) {
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainenstatic int log_append_ext_intro(struct mail_transaction_log_file *file,
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen unsigned int count;
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen if (!mail_index_map_get_ext_idx(t->view->map, ext_id, &idx)) {
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen /* new extension */
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen rext = array_idx(&t->view->index->extensions, ext_id);
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen intro = array_get_modifyable(&t->ext_resizes, &count);
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen buf = buffer_create_dynamic(pool_datastack_create(), 128);
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen if (ext_id < count && intro[ext_id].name_size != 0) {
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen /* we're resizing it */
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen /* generate a new intro structure */
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen intro = buffer_append_space_unsafe(buf, sizeof(*intro));
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen /* we're going to reset this extension in this transaction */
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen /* use the existing reset_id */
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen /* new extension, reset_id defaults to 0 */
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen buffer_append(buf, rext->name, intro->name_size);
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen return log_append_buffer(file, buf, NULL, MAIL_TRANSACTION_EXT_INTRO,
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainenmail_transaction_log_append_ext_intros(struct mail_transaction_log_file *file,
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen const struct mail_transaction_ext_intro *resize;
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen unsigned int update_count, resize_count, reset_count, ext_count;
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen update = array_get(&t->ext_rec_updates, &update_count);
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen resize = array_get(&t->ext_resizes, &resize_count);
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen reset = array_get(&t->ext_resets, &reset_count);
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen buf = buffer_create_data(pool_datastack_create(),
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen ext_count = I_MAX(I_MAX(update_count, resize_count), reset_count);
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen for (ext_id = 0; ext_id < ext_count; ext_id++) {
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen if ((ext_id < resize_count && resize[ext_id].name_size) ||
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen if (log_append_ext_intro(file, t, ext_id, 0) < 0)
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainenstatic int log_append_ext_rec_updates(struct mail_transaction_log_file *file,
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen updates = array_get_modifyable(&t->ext_rec_updates, &count);
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen reset = array_get_modifyable(&t->ext_resets, &reset_count);
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen reset_id = ext_id < reset_count && reset[ext_id] != 0 ?
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen if (log_append_ext_intro(file, t, ext_id, reset_id) < 0)
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen if (log_append_buffer(file, updates[ext_id].buffer, NULL,
struct mail_index_transaction *t,
if (t->hide_transaction) {
struct mail_index_transaction *t)
const char *const *keywords;
for (i = 0; i < count; i++) {
unsigned int old_log_syncs_pos;
unsigned int lock_id;
int ret;
if (!t->log_updates) {
*log_file_seq_r = 0;
*log_file_offset_r = 0;
ret = 0;
t->external);
if (t->hide_transaction) {
if (t->hide_transaction) {
t->external);
if (t->hide_transaction) {
t->external);
t->external);
if (ret < 0) {
if (ret < 0) {
return ret;