mail-transaction-log-append.c revision 0c909e3461607eadcd66f4eac69b7f34e37fccf1
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (c) 2003-2009 Dovecot authors, see the included COPYING file */
d48a2f3288eba53dd10d9d8029ec583d78a977e0Timo Sirainen
d48a2f3288eba53dd10d9d8029ec583d78a977e0Timo Sirainen#include "lib.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "array.h"
d48a2f3288eba53dd10d9d8029ec583d78a977e0Timo Sirainen#include "write-full.h"
d48a2f3288eba53dd10d9d8029ec583d78a977e0Timo Sirainen#include "mail-index-private.h"
d48a2f3288eba53dd10d9d8029ec583d78a977e0Timo Sirainen#include "mail-transaction-log-private.h"
d48a2f3288eba53dd10d9d8029ec583d78a977e0Timo Sirainen
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainenvoid mail_transaction_log_append_add(struct mail_transaction_log_append_ctx *ctx,
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen enum mail_transaction_type type,
40a5aeebf6b4858b93f0ddff0bf12fba769cf903Timo Sirainen const void *data, size_t size)
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen{
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen struct mail_transaction_header hdr;
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen i_assert((type & MAIL_TRANSACTION_TYPE_MASK) != 0);
40a5aeebf6b4858b93f0ddff0bf12fba769cf903Timo Sirainen i_assert((size % 4) == 0);
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen
40a5aeebf6b4858b93f0ddff0bf12fba769cf903Timo Sirainen if (size == 0)
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen return;
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen memset(&hdr, 0, sizeof(hdr));
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen hdr.type = type;
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen if (type == MAIL_TRANSACTION_EXPUNGE ||
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen type == MAIL_TRANSACTION_EXPUNGE_GUID)
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen hdr.type |= MAIL_TRANSACTION_EXPUNGE_PROT;
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen if (ctx->external)
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen hdr.type |= MAIL_TRANSACTION_EXTERNAL;
40a5aeebf6b4858b93f0ddff0bf12fba769cf903Timo Sirainen hdr.size = sizeof(hdr) + size;
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen hdr.size = mail_index_uint32_to_offset(hdr.size);
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen buffer_append(ctx->output, &hdr, sizeof(hdr));
40a5aeebf6b4858b93f0ddff0bf12fba769cf903Timo Sirainen buffer_append(ctx->output, data, size);
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen
ab11c996ff754af701b03c63db20e434469064e0Timo Sirainen if (mail_transaction_header_has_modseq(&hdr, data,
ab11c996ff754af701b03c63db20e434469064e0Timo Sirainen ctx->new_highest_modseq))
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen ctx->new_highest_modseq++;
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen}
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic int
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenlog_buffer_move_to_memory(struct mail_transaction_log_append_ctx *ctx)
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen{
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct mail_transaction_log_file *file = ctx->log->head;
0d0451206a91e9f96e522075dce28a89adc2325dTimo Sirainen
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen /* first we need to truncate this latest write so that log syncing
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen doesn't break */
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen if (ftruncate(file->fd, file->sync_offset) < 0) {
ab11c996ff754af701b03c63db20e434469064e0Timo Sirainen mail_index_file_set_syscall_error(ctx->log->index,
41e09cca158ab614961e03deac60f12a58235cd3Timo Sirainen file->filepath,
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen "ftruncate()");
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen }
0d0451206a91e9f96e522075dce28a89adc2325dTimo Sirainen
ab11c996ff754af701b03c63db20e434469064e0Timo Sirainen if (mail_index_move_to_memory(ctx->log->index) < 0)
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen return -1;
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen i_assert(MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file));
0d0451206a91e9f96e522075dce28a89adc2325dTimo Sirainen
ab11c996ff754af701b03c63db20e434469064e0Timo Sirainen i_assert(file->buffer_offset + file->buffer->used == file->sync_offset);
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen buffer_append_buf(file->buffer, ctx->output, 0, (size_t)-1);
0d0451206a91e9f96e522075dce28a89adc2325dTimo Sirainen file->sync_offset = file->buffer_offset + file->buffer->used;
d48a2f3288eba53dd10d9d8029ec583d78a977e0Timo Sirainen return 0;
d48a2f3288eba53dd10d9d8029ec583d78a977e0Timo Sirainen}
d48a2f3288eba53dd10d9d8029ec583d78a977e0Timo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic int log_buffer_write(struct mail_transaction_log_append_ctx *ctx)
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen{
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct mail_transaction_log_file *file = ctx->log->head;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct mail_transaction_header *hdr;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen uint32_t first_size;
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen
ab11c996ff754af701b03c63db20e434469064e0Timo Sirainen if (ctx->output->used == 0)
ab11c996ff754af701b03c63db20e434469064e0Timo Sirainen return 0;
ab11c996ff754af701b03c63db20e434469064e0Timo Sirainen
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen if (MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) {
6f90ce01176bd920609d9d12e6419b9ba27c1359Timo Sirainen if (file->buffer == NULL) {
6f90ce01176bd920609d9d12e6419b9ba27c1359Timo Sirainen file->buffer = buffer_create_dynamic(default_pool, 4096);
6f90ce01176bd920609d9d12e6419b9ba27c1359Timo Sirainen file->buffer_offset = sizeof(file->hdr);
6f90ce01176bd920609d9d12e6419b9ba27c1359Timo Sirainen }
a23197a5232f34121b1d32b73f2279c5d2f4491cTimo Sirainen buffer_append_buf(file->buffer, ctx->output, 0, (size_t)-1);
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen file->sync_offset = file->buffer_offset + file->buffer->used;
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen return 0;
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen }
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen /* size will be written later once everything is in disk */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen hdr = buffer_get_space_unsafe(ctx->output, 0, sizeof(*hdr));
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen first_size = hdr->size;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen i_assert(first_size != 0);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen hdr->size = 0;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen if (pwrite_full(file->fd, ctx->output->data, ctx->output->used,
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen file->sync_offset) < 0) {
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen /* write failure, fallback to in-memory indexes. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen hdr->size = first_size;
ab11c996ff754af701b03c63db20e434469064e0Timo Sirainen mail_index_file_set_syscall_error(ctx->log->index,
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen file->filepath,
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen "pwrite_full()");
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen return log_buffer_move_to_memory(ctx);
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen }
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen i_assert(!ctx->sync_includes_this ||
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen file->sync_offset + ctx->output->used ==
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen file->max_tail_offset);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen /* now that the whole transaction has been written, rewrite the first
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen record's size so the transaction becomes visible */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (pwrite_full(file->fd, &first_size, sizeof(uint32_t),
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen file->sync_offset +
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen offsetof(struct mail_transaction_header, size)) < 0) {
ab11c996ff754af701b03c63db20e434469064e0Timo Sirainen mail_index_file_set_syscall_error(ctx->log->index,
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen file->filepath,
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen "pwrite_full()");
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen return log_buffer_move_to_memory(ctx);
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
ab11c996ff754af701b03c63db20e434469064e0Timo Sirainen if ((ctx->want_fsync && !ctx->log->index->fsync_disable) ||
ab11c996ff754af701b03c63db20e434469064e0Timo Sirainen ctx->log->index->nfs_flush) {
9b5a8e766112d24c12499aca85da5ddf24baad25Timo Sirainen if (fdatasync(file->fd) < 0) {
ab11c996ff754af701b03c63db20e434469064e0Timo Sirainen mail_index_file_set_syscall_error(ctx->log->index,
9b5a8e766112d24c12499aca85da5ddf24baad25Timo Sirainen file->filepath,
9b5a8e766112d24c12499aca85da5ddf24baad25Timo Sirainen "fdatasync()");
9b5a8e766112d24c12499aca85da5ddf24baad25Timo Sirainen return log_buffer_move_to_memory(ctx);
9b5a8e766112d24c12499aca85da5ddf24baad25Timo Sirainen }
9b5a8e766112d24c12499aca85da5ddf24baad25Timo Sirainen }
9b5a8e766112d24c12499aca85da5ddf24baad25Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* FIXME: when we're relying on O_APPEND and someone else wrote a
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen transaction, we'll need to wait for it to commit its transaction.
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if it crashes before doing that, we'll need to overwrite it with
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen a dummy record */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen file->sync_offset += ctx->output->used;
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen return 0;
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen}
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainenstatic void
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenlog_append_sync_offset_if_needed(struct mail_transaction_log_append_ctx *ctx)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct mail_transaction_log_file *file = ctx->log->head;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct mail_transaction_header_update *u;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct mail_transaction_header *hdr;
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen buffer_t *buf;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uint32_t offset;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (file->max_tail_offset == file->sync_offset) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* FIXME: when we remove exclusive log locking, we
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen can't rely on this. then write non-changed offset + check
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen real offset + rewrite the new offset if other transactions
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen weren't written in the middle */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen file->max_tail_offset += ctx->output->used +
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen sizeof(*hdr) + sizeof(*u) + sizeof(offset);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen ctx->sync_includes_this = TRUE;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen offset = file->max_tail_offset;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (file->saved_tail_offset == offset)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen i_assert(offset > file->saved_tail_offset);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen buf = buffer_create_static_hard(pool_datastack_create(),
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen sizeof(*u) + sizeof(offset));
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen u = buffer_append_space_unsafe(buf, sizeof(*u));
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen u->offset = offsetof(struct mail_index_header, log_file_tail_offset);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen u->size = sizeof(offset);
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen buffer_append(buf, &offset, sizeof(offset));
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen mail_transaction_log_append_add(ctx, MAIL_TRANSACTION_HEADER_UPDATE,
40a5aeebf6b4858b93f0ddff0bf12fba769cf903Timo Sirainen buf->data, buf->used);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
75ef04fc62a3955d3a5310410e09735cbd4e972bTimo Sirainen
b529a94ab17fe69cdcfab08d7030266cb2a564e4Timo Sirainenstatic int
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenmail_transaction_log_append_locked(struct mail_transaction_log_append_ctx *ctx)
d48a2f3288eba53dd10d9d8029ec583d78a977e0Timo Sirainen{
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct mail_transaction_log_file *file = ctx->log->head;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen if (file->sync_offset < file->last_size) {
4d5d16ff85dacf56ddd70f76e0ccdb12b9d314d0Timo Sirainen /* there is some garbage at the end of the transaction log
4d5d16ff85dacf56ddd70f76e0ccdb12b9d314d0Timo Sirainen (eg. previous write failed). remove it so reader doesn't
4d5d16ff85dacf56ddd70f76e0ccdb12b9d314d0Timo Sirainen break because of it. */
4d5d16ff85dacf56ddd70f76e0ccdb12b9d314d0Timo Sirainen buffer_set_used_size(file->buffer,
4d5d16ff85dacf56ddd70f76e0ccdb12b9d314d0Timo Sirainen file->sync_offset - file->buffer_offset);
4d5d16ff85dacf56ddd70f76e0ccdb12b9d314d0Timo Sirainen if (!MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) {
4d5d16ff85dacf56ddd70f76e0ccdb12b9d314d0Timo Sirainen if (ftruncate(file->fd, file->sync_offset) < 0) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen mail_index_file_set_syscall_error(ctx->log->index,
4d5d16ff85dacf56ddd70f76e0ccdb12b9d314d0Timo Sirainen file->filepath, "ftruncate()");
4d5d16ff85dacf56ddd70f76e0ccdb12b9d314d0Timo Sirainen }
4d5d16ff85dacf56ddd70f76e0ccdb12b9d314d0Timo Sirainen }
4d5d16ff85dacf56ddd70f76e0ccdb12b9d314d0Timo Sirainen }
4d5d16ff85dacf56ddd70f76e0ccdb12b9d314d0Timo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (ctx->append_sync_offset)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen log_append_sync_offset_if_needed(ctx);
d48a2f3288eba53dd10d9d8029ec583d78a977e0Timo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (log_buffer_write(ctx) < 0)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return -1;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen file->sync_highest_modseq = ctx->new_highest_modseq;
137c1851d63c6575ebab35d261380423c4cf2b47Timo Sirainen return 0;
d48a2f3288eba53dd10d9d8029ec583d78a977e0Timo Sirainen}
d48a2f3288eba53dd10d9d8029ec583d78a977e0Timo Sirainen
40a5aeebf6b4858b93f0ddff0bf12fba769cf903Timo Sirainenint mail_transaction_log_append_begin(struct mail_index *index, bool external,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct mail_transaction_log_append_ctx **ctx_r)
b529a94ab17fe69cdcfab08d7030266cb2a564e4Timo Sirainen{
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct mail_transaction_log_append_ctx *ctx;
b529a94ab17fe69cdcfab08d7030266cb2a564e4Timo Sirainen
346ee8b23fe6187632efe5930e59dafa17625138Timo Sirainen if (!index->log_locked) {
b529a94ab17fe69cdcfab08d7030266cb2a564e4Timo Sirainen if (mail_transaction_log_lock_head(index->log) < 0)
b529a94ab17fe69cdcfab08d7030266cb2a564e4Timo Sirainen return -1;
b529a94ab17fe69cdcfab08d7030266cb2a564e4Timo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen ctx = i_new(struct mail_transaction_log_append_ctx, 1);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen ctx->log = index->log;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen ctx->output = buffer_create_dynamic(default_pool, 1024);
40a5aeebf6b4858b93f0ddff0bf12fba769cf903Timo Sirainen ctx->external = external;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen *ctx_r = ctx;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return 0;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen}
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenint mail_transaction_log_append_commit(struct mail_transaction_log_append_ctx **_ctx)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen{
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct mail_transaction_log_append_ctx *ctx = *_ctx;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct mail_index *index = ctx->log->index;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen int ret = 0;
b529a94ab17fe69cdcfab08d7030266cb2a564e4Timo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen *_ctx = NULL;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
ab11c996ff754af701b03c63db20e434469064e0Timo Sirainen ret = mail_transaction_log_append_locked(ctx);
b529a94ab17fe69cdcfab08d7030266cb2a564e4Timo Sirainen if (!index->log_locked)
b529a94ab17fe69cdcfab08d7030266cb2a564e4Timo Sirainen mail_transaction_log_file_unlock(index->log->head);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen buffer_free(&ctx->output);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen i_free(ctx);
b529a94ab17fe69cdcfab08d7030266cb2a564e4Timo Sirainen return ret;
b529a94ab17fe69cdcfab08d7030266cb2a564e4Timo Sirainen}