mail-transaction-log.c revision 2a6af811ea3de3cf9e2f15e446674dd21b0705f3
/* Copyright (C) 2003-2007 Timo Sirainen */
#include "lib.h"
#include "ioloop.h"
#include "buffer.h"
#include "file-dotlock.h"
#include "nfs-workarounds.h"
#include "close-keep-errno.h"
#include "mmap-util.h"
#include "mail-index-private.h"
#include "mail-transaction-log-private.h"
#include <stddef.h>
#include <stdio.h>
/* this lock should never exist for a long time.. */
#define LOG_DOTLOCK_TIMEOUT 60
#define LOG_DOTLOCK_STALE_TIMEOUT 60
#define MAIL_TRANSACTION_LOG_SUFFIX ".log"
#define LOG_NEW_DOTLOCK_SUFFIX ".newlock"
static void
struct mail_transaction_log_file *file)
{
}
struct mail_transaction_log *
{
struct mail_transaction_log *log;
return log;
}
{
struct mail_transaction_log_file *file;
const char *path;
int ret;
return 0;
/* leave the file for _create() */
return ret;
}
return 1;
}
{
struct mail_transaction_log_file *file;
const char *path;
return 0;
}
/* remember what file we tried to open. if someone else created
a new file, use it instead of recreating it */
}
if (mail_transaction_log_file_create(file) < 0)
return 1;
}
{
}
{
}
{
return 0;
/* read the whole file to memory. we might currently be appending
data into it, so we want to read it up to end of file */
file->buffer_offset = 0;
}
"munmap()");
}
}
if (mail_transaction_log_file_read(file, 0) <= 0)
return -1;
/* after we've read the file into memory, make it into in-memory
log file */
}
return 0;
}
{
}
}
#define LOG_WANT_ROTATE(file) \
{
}
{
struct mail_transaction_log_file *file;
else {
/* we're locked, we shouldn't need to worry about ESTALE
problems in here. */
return -1;
}
if (mail_transaction_log_file_create(file) < 0) {
return -1;
}
}
else
return 0;
}
{
struct mail_transaction_log_file *file;
const char *path;
return 0;
"stat()");
return -1;
}
return -1;
} else {
/* same file */
return 0;
}
}
return -1;
}
return 0;
}
{
}
{
}
struct mail_transaction_log_file **file_r)
{
struct mail_transaction_log_file *file;
const char *path;
int ret;
/* see if the .log file has been recreated */
/* transaction log is locked. there's no way a newer
file exists. */
return 0;
}
if (mail_transaction_log_refresh(log) < 0)
return -1;
return 0;
}
return 1;
}
}
return 0;
/* see if we have it in log.2 file */
return ret;
/* but is it what we expected? */
return 0;
return 1;
}
{
struct mail_transaction_log_file *file;
int ret = 0;
/* we want to get the head file locked. this is a bit racy,
since by the time we have it locked a new log file may have been
created.
creating new log file requires locking the head file, so if we
can lock it and don't see another file, we can be sure no-one is
creating a new log at the moment */
for (;;) {
if (mail_transaction_log_file_lock(file) < 0)
return -1;
}
/* success */
break;
}
if (ret < 0)
break;
/* try again */
}
return ret;
}
{
if (mail_transaction_log_lock_head(log) < 0)
return -1;
/* update sync_offset */
(uoff_t)-1) < 0) {
return -1;
}
return 0;
}
{
}
{
}
{
}