mail-index-write.c revision 4df91bfe1e537c19a07f3f30b9cc4aa5f586c915
/* Copyright (c) 2003-2009 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "read-full.h"
#include "write-full.h"
#include "ostream.h"
#include "mail-index-private.h"
#include "mail-transaction-log-private.h"
#include <stdio.h>
#define MAIL_INDEX_MIN_UPDATE_SIZE 1024
/* if we're updating >= count-n messages, recreate the index */
#define MAIL_INDEX_MAX_OVERWRITE_NEG_SEQ_COUNT 10
{
const char *backup_path, *tmp_backup_path;
int ret;
return -1;
}
}
if (ret < 0) {
/* no dovecot.index file, ignore */
return 0;
}
return -1;
}
return -1;
}
return 0;
}
{
unsigned int base_size;
const char *path;
if (fd == -1)
return -1;
o_stream_flush(output) < 0) {
ret = -1;
}
ret = -1;
}
ret = -1;
}
if (index->keep_backups)
ret = -1;
}
if (ret < 0) {
path);
}
}
return ret;
}
{
unsigned int base_size;
if (MAIL_INDEX_IS_IN_MEMORY(index))
return 0;
/* write extended headers */
if (map->write_ext_header) {
base_size) < 0)
return -1;
}
/* write records. */
if (rec_map->write_seq_first != 0) {
return -1;
}
/* Write base header last. If we happen to crash in above pwrites, it
doesn't matter because we haven't yet written log file offsets, so
stay valid.
The base header changes practically always, so
map->write_base_header might not be TRUE here in all situations.
It's used only to figure out if we want to write the map at all. */
return -1;
return 0;
}
{
struct mail_index_header hdr;
int ret;
return TRUE;
}
return hdr.log_file_head_offset !=
}
#define mail_index_map_has_changed(map) \
{
unsigned int lock_id;
int ret;
if (!mail_index_map_has_changed(map))
return;
/* header size growed. we can't update this file anymore. */
}
/* index file doesn't exist, it's corrupted or we haven't
opened it for some reason */
}
/* the file is so small that we don't even bother trying to
update it / changes are so large we might as well recreate */
}
if (!map->write_atomic) {
/* we can't update the file unless it's the same as it was
when we last read it. this is the first quick check before
locking. */
}
if (!map->write_atomic) {
/* locking failed, recreate */
} else if (mail_index_has_last_changed(index)) {
/* changed, we can't trust updating it anymore */
}
}
if (map->write_atomic) {
if (!MAIL_INDEX_IS_IN_MEMORY(index)) {
if (mail_index_recreate(index) < 0) {
return;
}
}
} else {
if (ret < 0)
if (ret < 0) {
"fdatasync()");
}
}
if (ret < 0) {
/* hopefully didn't break badly */
return;
}
}
if (want_rotate &&
}