mail-transaction-log.c revision e8579686b20f2bee8468834ca221180ef1dddfc1
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen/* this lock should never exist for a long time.. */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen#define LOG_DOTLOCK_IMMEDIATE_STALE_TIMEOUT 300
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainenmail_transaction_log_file_open_or_create(struct mail_transaction_log *log,
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen const char *path);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainenstatic int mail_transaction_log_rotate(struct mail_transaction_log *log,
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainenstatic int mail_transaction_log_lock_head(struct mail_transaction_log *log);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainenmail_transaction_log_file_set_corrupted(struct mail_transaction_log_file *file,
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen const char *fmt, ...)
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_index_file_set_syscall_error(file->log->index,
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen "Corrupted transaction log file %s: %s",
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainenmail_transaction_log_file_dotlock(struct mail_transaction_log_file *file)
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen ret = file_lock_dotlock(file->filepath, NULL, FALSE,
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_index_file_set_syscall_error(file->log->index,
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen "file_lock_dotlock()");
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen "Timeout while waiting for release of "
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen "dotlock for transaction log file %s",
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainenmail_transaction_log_file_undotlock(struct mail_transaction_log_file *file)
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen ret = file_unlock_dotlock(file->filepath, &file->log->dotlock);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_index_file_set_syscall_error(file->log->index,
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen "Dotlock was lost for transaction log file %s",
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainenmail_transaction_log_file_lock(struct mail_transaction_log_file *file)
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen if (file->log->index->lock_method == MAIL_INDEX_LOCK_DOTLOCK)
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen return mail_transaction_log_file_dotlock(file);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen ret = mail_index_lock_fd(file->log->index, file->fd, F_WRLCK,
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_index_file_set_syscall_error(file->log->index,
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen "mail_index_wait_lock_fd()");
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen "Timeout while waiting for release of "
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen "fcntl() lock for transaction log file %s",
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainenmail_transaction_log_file_unlock(struct mail_transaction_log_file *file)
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen if (file->log->index->lock_method == MAIL_INDEX_LOCK_DOTLOCK) {
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen ret = mail_index_lock_fd(file->log->index, file->fd, F_UNLCK, 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_index_file_set_syscall_error(file->log->index,
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen "mail_index_wait_lock_fd()");
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen !(((file)->hdr.file_seq == (index)->hdr->log_file_seq && \
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen sizeof(struct mail_transaction_log_header)) || \
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen ((file)->hdr.prev_file_seq == (index)->hdr->log_file_seq && \
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen (file)->hdr.prev_file_offset == (index)->hdr->log_file_offset))
unsigned int lock_id;
int ret;
if (ret == 0) {
if (ret <= 0)
return ret;
struct mail_transaction_log *
const char *path;
return NULL;
return log;
int ret;
if (ret < 0) {
if (ret == 0) {
unsigned int lock_id;
fd);
return fd2;
if (ret < 0)
if (fd2 < 0) {
return fd2;
if (fd2 < 0) {
return fd2;
static struct mail_transaction_log_file *
struct mail_transaction_log_file **p;
int ret;
return NULL;
if (ret == 0) {
if (ret <= 0) {
return NULL;
*p = file;
return file;
static struct mail_transaction_log_file *
const char *path)
int fd;
return NULL;
return NULL;
if ((*p)->refcount != 0)
p = &(*p)->next;
*p = next;
int fd;
if (lock) {
unsigned int lock_id;
int ret;
return ret;
const char *path;
const void *data;
if (hdr_size == 0) {
void *data;
int ret;
if (ret == 0) {
if (ret < 0) {
if (ret > 0)
if (ret == 0) {
if (!use_mmap) {
if (ret <= 0) {
return ret;
MADV_SEQUENTIAL) < 0) {
int ret = 0;
if (ret < 0)
return ret;
const void *data)
if (deleted) {
dest++;
const char *name;
t_push();
t_pop();
struct mail_index_transaction *t)
const void *data;
int ret;
case MAIL_TRANSACTION_APPEND:
case MAIL_TRANSACTION_CACHE_RESET: {
case MAIL_TRANSACTION_EXT_INTRO: {
uint32_t i;
for (i = 0; i < size; i++)
return ret;
if (size == 0)
hdr_data_size = 0;
if (external)
hdr_size =
if (hdr_data_size > 0) {
struct mail_transaction_cache_reset u;
memset(&u, 0, sizeof(u));
return buf;
static const buffer_t *
struct mail_transaction_header_update u;
int state = 0;
memset(&u, 0, sizeof(u));
if (state == 0) {
state++;
if (state > 0) {
u.size);
state = 0;
return buf;
static uint32_t
return idx;
struct mail_index_transaction *t)
for (i = 0; i < size; i++) {
for (i = 0; i < size; i++) {
for (i = 0; i < size; i++) {
static uint32_t
return idx;
unsigned int i, lock_id;
int ret;
if (!t->log_updates) {
*log_file_seq_r = 0;
*log_file_offset_r = 0;
sizeof(struct mail_index_ext));
ret = 0;
if (t->new_cache_file_seq != 0) {
size = 0;
if (ret < 0) {
t->hide_transaction) {
if (ret < 0) {
if (ret < 0)
return ret;