/* Copyright (c) 2003-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "write-full.h"
#include "mail-index-private.h"
#include "mail-transaction-log-private.h"
enum mail_transaction_type type,
{
if (size == 0)
return;
if (type == MAIL_TRANSACTION_EXPUNGE ||
if (type == MAIL_TRANSACTION_BOUNDARY)
ctx->transaction_count++;
}
static int
{
/* first we need to truncate this latest write so that log syncing
doesn't break */
"ftruncate()");
}
return -1;
return 0;
}
{
return 0;
}
return 0;
}
/* write failure, fallback to in-memory indexes. */
"write_full()");
return log_buffer_move_to_memory(ctx);
}
if ((ctx->want_fsync &&
"fdatasync()");
return log_buffer_move_to_memory(ctx);
}
}
/* we're reading from a file. avoid re-reading the data that
we just wrote. this is also important for some NFS clients,
which for some reason sometimes can't read() this data we
just wrote in the same process */
}
return 0;
}
static void
{
struct mail_transaction_header_update *u;
if (!ctx->index_sync_transaction) {
/* this is a non-syncing transaction. update the tail offset
only if we're already writing something else to transaction
log anyway. */
/* FIXME: For now we never do this update, because it would
cause errors about shrinking tail offsets with old Dovecot
versions. This is anyway just an optimization, so it doesn't
matter all that much if we don't do it here. Finish this
in v2.3. */
/*if (ctx->output->used == 0)*/
return;
/* we're synced all the way to tail offset, so this sync
transaction can also be included in the same tail offset. */
/* nothing to write here after all (e.g. all unchanged
flag updates were dropped by export) */
return;
}
/* FIXME: when we remove exclusive log locking, we
can't rely on this. then write non-changed offset + check
real offset + rewrite the new offset if other transactions
weren't written in the middle */
} else {
/* This is a syncing transaction. Since we're finishing a sync,
we may need to update the tail offset even if we don't have
anything else to do. */
}
return;
u = buffer_append_space_unsafe(&buf, sizeof(*u));
}
static int
{
/* there is some garbage at the end of the transaction log
(eg. previous write failed). remove it so reader doesn't
break because of it. */
if (!MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) {
}
}
}
/* don't include log_file_tail_offset update in the transaction */
sizeof(struct mail_transaction_header),
sizeof(*boundary));
/* 0-1 changes. don't bother with the boundary */
unsigned int boundary_size =
sizeof(struct mail_transaction_header) +
sizeof(*boundary);
}
if (log_buffer_write(ctx) < 0)
return -1;
return 0;
}
enum mail_transaction_type flags,
struct mail_transaction_log_append_ctx **ctx_r)
{
if (!index->log_sync_locked) {
return -1;
}
return 0;
}
{
int ret = 0;
if (!index->log_sync_locked)
return ret;
}