mail-transaction-log.c revision b886e3df92063a741201d5c37c4d52412ede2269
/* Copyright (c) 2003-2012 Dovecot authors, see the included COPYING file */
#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>
static void
struct mail_transaction_log_file *file)
{
}
struct mail_transaction_log *
{
struct mail_transaction_log *log;
return log;
}
{
return;
}
return;
}
}
}
}
{
struct mail_transaction_log_file *file;
int ret;
/* these settings aren't available at alloc() time, so we need to
set them here: */
return 0;
/* leave the file for _create() */
return ret;
}
return 1;
}
{
struct mail_transaction_log_file *file;
return 0;
}
/* remember what file we tried to open. if someone else created
a new file, use it instead of recreating it */
}
return -1;
}
return 1;
}
{
}
{
}
{
struct mail_transaction_log_file *file;
/* we couldn't read dovecot.index and we don't have the first
.log file, so just start from scratch */
}
else {
}
}
{
struct mail_transaction_log_file *file;
"indexid changed: %u -> %u",
}
}
}
}
{
/* remove only files from the beginning. this way if a view has
referenced an old file, it can still find the new files even if
there aren't any references to it currently. */
break;
}
/* if we still have locked files with refcount=0, unlock them */
}
}
#define LOG_WANT_ROTATE(file) \
{
}
{
struct mail_transaction_log_file *file;
if (reset) {
}
} else {
/* we're locked, we shouldn't need to worry about ESTALE
problems in here. */
return -1;
}
return -1;
}
}
else
return 0;
}
static int
{
struct mail_transaction_log_file *file;
return 0;
"stat()");
return -1;
}
/* see if the whole directory got deleted */
return -1;
}
/* the file should always exist at this point. if it doesn't,
someone deleted it manually while the index was open. try to
handle this nicely by creating a new log file. */
return -1;
return 0;
/* NFS: log files get rotated to .log.2 files instead
of being unlinked, so we don't bother checking if
the existing file has already been unlinked here
(in which case inodes could match but point to
different files) */
return 0;
}
return -1;
}
return 0;
}
{
}
{
}
struct mail_transaction_log_file **file_r)
{
struct mail_transaction_log_file *file;
int ret;
/* see if the .log file has been recreated */
/* transaction log is locked. there's no way a newer
file exists. */
return 0;
}
/* we're opening the index and we just opened the
log file. don't waste time checking if there's a
newer one. */
return 0;
}
return -1;
return 0;
/* try again, this time flush attribute cache */
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;
if (!log->log_2_unlink_checked) {
/* we need to check once in a while if .log.2 should be deleted
to avoid wasting space on such old files. but we also don't
want to waste time on checking it when the same mailbox
gets opened over and over again rapidly (e.g. pop3). so
do this only when there have actually been some changes
to mailbox (i.e. when it's being locked here) */
}
/* 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 */
}
i_warning("Locking transaction log file %s took %ld seconds",
}
return ret;
}
{
if (mail_transaction_log_lock_head(log) < 0)
return -1;
/* update sync_offset */
(uoff_t)-1) <= 0) {
return -1;
}
return 0;
}
{
}
{
}
{
}
}
{
}
{
*mtime_r = 0;
return 0;
"stat()");
return -1;
}
return 0;
}
{
"unlink()");
return -1;
}
return 0;
}
struct dotlock_settings *set_r)
{
}