mail-transaction-log-file.c revision b397665e90fa0fc7c6a9156fdd6cf28b571e8e39
89a126810703c666309310d0f3189e9834d70b5bTimo Sirainen/* Copyright (c) 2003-2009 Dovecot authors, see the included COPYING file */
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen#define MEMORY_LOG_NAME "(in-memory transaction log file)"
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainenmail_transaction_log_file_set_corrupted(struct mail_transaction_log_file *file,
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen const char *fmt, ...)
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen if (!MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) {
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen /* indexid=0 marks the log file as corrupted */
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen mail_index_file_set_syscall_error(file->log->index,
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen "Corrupted transaction log file %s seq %u: %s "
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen t_strdup_vprintf(fmt, va), file->sync_offset);
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainenmail_transaction_log_file_alloc(struct mail_transaction_log *log,
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen file = i_new(struct mail_transaction_log_file, 1);
f923659c0e5298263d80622c99f4dc4132b4675bTimo Sirainenvoid mail_transaction_log_file_free(struct mail_transaction_log_file **_file)
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen struct mail_transaction_log_file *file = *_file;
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen for (p = &file->log->files; *p != NULL; p = &(*p)->next) {
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen if (munmap(file->mmap_base, file->mmap_size) < 0) {
fab050cbfdf3da692441d2e2fb4b2a4c6ac9e0daTimo Sirainen mail_index_file_set_syscall_error(file->log->index,
2a3fc652e13a574ca14ff2405b5c29a59232db49Timo Sirainen mail_index_file_set_syscall_error(file->log->index,
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainenmail_transaction_log_file_skip_to_head(struct mail_transaction_log_file *file)
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen const struct mail_index_modseq_header *modseq_hdr;
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen if (map == NULL || file->hdr.file_seq != map->hdr.log_file_seq ||
d65a556a5ec078cd7f1d0060adb16fc860d66b27Timo Sirainen /* we can get a valid log offset from index file. initialize
e4ded29bff0662a590c2439ef2df8cda8a7cdd9bTimo Sirainen sync_offset from it so we don't have to read the whole log
e4ded29bff0662a590c2439ef2df8cda8a7cdd9bTimo Sirainen file from beginning. */
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen modseq_hdr = mail_index_map_get_modseq_header(map);
bc2d4f1c18222a3bd2a6b2b8b5f6abb560a865b3Timo Sirainen "%s: log_file_head_offset too small",
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen file->sync_highest_modseq = file->hdr.initial_modseq;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen } else if (modseq_hdr == NULL && file->hdr.initial_modseq == 0) {
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen /* modseqs not used yet */
a4ee24a4d5eefa80bbefc5acba16587ae36c3b5bTimo Sirainen /* highest_modseq not synced, start from beginning */
bc2d4f1c18222a3bd2a6b2b8b5f6abb560a865b3Timo Sirainen file->sync_highest_modseq = file->hdr.initial_modseq;
a93de780c3b78cfaace287026e468f3c3e34683aTimo Sirainen } else if (modseq_hdr->log_offset > head_offset) {
bc2d4f1c18222a3bd2a6b2b8b5f6abb560a865b3Timo Sirainen "%s: modseq_hdr.log_offset too large",
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen file->sync_highest_modseq = file->hdr.initial_modseq;
345253fb28498b2e0a60f4a2a8644c65feee7e75Timo Sirainen /* start from where we last stopped tracking modseqs */
65988f5a8abed57e9894fec77105941e046d3490Timo Sirainen file->sync_highest_modseq = modseq_hdr->highest_modseq;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen file->saved_tail_offset = log->index->map->hdr.log_file_tail_offset;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen file->saved_tail_sync_offset = file->saved_tail_offset;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen if (file->saved_tail_offset > file->max_tail_offset)
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen file->max_tail_offset = file->saved_tail_offset;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainenmail_transaction_log_file_add_to_list(struct mail_transaction_log_file *file)
055f4599bba1874fa1148a8fa488517fa077619cTimo Sirainen file->sync_highest_modseq = file->hdr.initial_modseq;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen /* insert it to correct position */
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen for (p = &file->log->files; *p != NULL; p = &(*p)->next) {
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen i_assert((*p)->hdr.file_seq < file->hdr.file_seq);
a93de780c3b78cfaace287026e468f3c3e34683aTimo Sirainenmail_transaction_log_init_hdr(struct mail_transaction_log *log,
#ifndef WORDS_BIGENDIAN
MAIL_INDEX_SYNC_HANDLER_HEAD) <= 0)
struct mail_transaction_log_file *
return NULL;
return file;
int ret;
if (ret > 0) {
if (ret < 0) {
int ret;
if (ret < 0) {
if (ret == 0) {
int ret;
if (ret > 0) {
if (ret < 0) {
static ssize_t
int ret;
pos = 0;
if (ret > 0)
bool ignore_estale)
struct mail_transaction_log_file *f;
int ret;
if (ret < 0) {
#ifndef WORDS_BIGENDIAN
bool ignore_estale)
return TRUE;
return FALSE;
const char *path2;
bool rename_existing;
if (reset)
FALSE) > 0 &&
if (reset) {
if (ret < 0)
if (rename_existing) {
path2);
bool reset)
int fd;
bool check_existing)
bool ignore_estale;
int ret;
else if (check_existing &&
if (ret > 0) {
if (ret == 0) {
i == MAIL_INDEX_ESTALE_RETRY_COUNT) {
const unsigned int offset_pos =
sizeof(sync_offset));
const void *data,
if (cur_modseq != 0) {
const unsigned int modseq_ext_len =
modseq_ext_len) == 0) {
return TRUE;
return FALSE;
case MAIL_TRANSACTION_APPEND:
return TRUE;
return FALSE;
static struct modseq_cache *
if (idx > 0) {
static struct modseq_cache *
return NULL;
best = i;
return NULL;
static struct modseq_cache *
return NULL;
best = i;
return NULL;
int ret;
if (ret <= 0) {
if (ret < 0)
cur_modseq++;
int ret;
if (ret <= 0) {
if (ret < 0)
cur_modseq)) {
unsigned int trans_size)
int ret;
sizeof(*hdr));
if (ret != 0)
const void *data;
if (trans_size == 0) {
trans_size = 0;
if (trans_size != 0) {
void *data;
if (ret > 0) {
if (ret == 0) {
void *data;
if (ret > 0)
if (ret < 0) {
return TRUE;
return TRUE;
return FALSE;
int ret;
if (ret <= 0)
return ret;
return ret;
MADV_SEQUENTIAL) < 0) {
int ret;
if (ret > 0)
FALSE);
} while (ret == 0);
int ret;
end_offset) == 0)
*file)