mail-index.c revision 1d9db95775ffa2dae26cd6914f89333b8c69ef8e
/* Copyright (C) 2002 Timo Sirainen */
#include "lib.h"
#include "ioloop.h"
#include "file-lock.h"
#include "file-set-size.h"
#include "mmap-util.h"
#include "mail-index.h"
#include "mail-index-util.h"
#include "mail-cache.h"
#include "mail-modifylog.h"
#include "mail-custom-flags.h"
#include <unistd.h>
#include <fcntl.h>
{
}
{
struct mail_index_header *hdr;
unsigned int extra;
index->mmap_used_length = 0;
return FALSE;
}
/* keep the header set even if we fail, so we can update the flags */
return FALSE;
}
sizeof(struct mail_index_record);
if (extra != 0) {
/* partial write or corrupted -
truncate the file to valid length */
}
"used_file_size larger than real file size "
return FALSE;
}
sizeof(struct mail_index_record) != 0) {
return FALSE;
}
return FALSE;
}
return FALSE;
}
return TRUE;
}
{
return mmap_verify(index);
if (index->mmap_invalidate) {
MS_SYNC | MS_INVALIDATE) < 0) {
return FALSE;
}
}
/* make sure file size hasn't changed */
i_panic("Index file size was grown without "
"updating sync_id");
}
return TRUE;
}
if (!index->mmap_invalidate) {
return FALSE;
}
}
}
index->mmap_used_length = 0;
return FALSE;
}
return mmap_verify(index);
}
{
#ifdef DEBUG
#endif
MS_SYNC);
}
}
}
}
}
}
}
}
}
}
{
unsigned int i;
return TRUE;
fsync_fds[i] = -1;
}
}
return !failed;
}
{
}
return TRUE;
}
{
}
}
{
/* use our own locking here so we don't mess up with any other
index states, like inconsistency. */
return FALSE;
#ifdef DEBUG
#endif
}
}
#ifdef DEBUG
#endif
return FALSE;
return !failed;
}
{
enum mail_lock_type old_lock_type;
while (index->cache_later_locks > 0) {
}
return FALSE;
if (old_lock_type == MAIL_LOCK_SHARED) {
/* releasing shared lock. we may need to update some
flags in header. */
unsigned int old_flags;
return mail_index_write_header_changes(index);
}
return ret;
}
{
int ret, fd_lock_type;
/* shared -> exclusive can deadlock */
/* locking index when cache is locked can deadlock */
if (index->inconsistent) {
/* index is in inconsistent state and nothing else than
free() is allowed for it. */
i_strdup("Index is in inconsistent state");
}
return FALSE;
}
if (try_lock) {
if (ret < 0)
if (ret <= 0)
return FALSE;
} else {
return FALSE;
}
if (!mail_index_mmap_update(index)) {
return FALSE;
}
/* index was rebuilt, there's no way we can maintain
consistency */
"%s was rebuilt while we had it open",
return FALSE;
}
/* someone just partially updated the index, need to fsck it */
if (lock_type == MAIL_LOCK_SHARED) {
/* we need exclusive lock so fsck()'s set_lock() won't
get us back here */
if (!mail_index_lock_remove(index))
return FALSE;
return FALSE;
}
/* check again, in case it was already fscked while we had
it unlocked for a while */
return FALSE;
}
if (lock_type == MAIL_LOCK_SHARED) {
/* drop exclusive lock */
}
}
if (lock_type == MAIL_LOCK_EXCLUSIVE) {
/* while holding exclusive lock, keep the FSCK flag on.
when the lock is released, the FSCK flag will also be
removed. */
return FALSE;
}
}
return TRUE;
}
{
int keep_fsck;
return TRUE;
/* anonymous mmaps are private and don't need any locking */
#ifdef DEBUG
#endif
index);
return TRUE;
}
/* dropping exclusive lock (either unlock or to shared) */
if (index->sync_dirty_stamp == 0) {
}
/* remove the FSCK flag only after successful fsync() */
MS_SYNC) < 0) {
/* we only failed to remove the fsck flag,
so this isn't fatal. */
}
}
}
if (lock_type == MAIL_LOCK_UNLOCK)
return mail_index_lock_remove(index);
else
}
{
}
{
}
void *context)
{
}
{
}
struct mail_index_record *rec,
enum mail_flags old_flags,
enum mail_flags new_flags)
{
/* unseen -> seen */
/* seen -> unseen */
/* this is the first unseen message */
"seen_messages_count in header is invalid");
} else {
}
}
/* undeleted -> deleted */
/* this is the first deleted message */
} else if ((old_flags & MAIL_DELETED) &&
(new_flags & MAIL_DELETED) == 0) {
/* deleted -> undeleted */
"deleted_messages_count in header is invalid");
} else {
}
}
}
((records) > INDEX_MIN_RECORDS_COUNT && \
(hdr)->messages_count)
struct mail_index_record *first_rec,
struct mail_index_record *last_rec,
int external_change)
{
index->expunge_counter++;
return FALSE;
return FALSE;
}
/* all mail was deleted, truncate cache file */
return FALSE;
}
return TRUE;
}
int external_change)
{
enum mail_flags new_flags;
switch (modify_type) {
case MODIFY_ADD:
break;
case MODIFY_REMOVE:
break;
case MODIFY_REPLACE:
break;
default:
new_flags = 0;
i_unreached();
}
return TRUE; /* no changes */
}
{
unsigned int grow_count;
void *base;
INDEX_GROW_PERCENTAGE / 100;
if (grow_count < 16)
grow_count = 16;
(grow_count * sizeof(struct mail_index_record));
if (base == MAP_FAILED)
return mmap_verify(index);
}
/* file size changed, let others know about it too by changing
sync_id in header. */
if (!mail_index_mmap_update(index))
return FALSE;
return TRUE;
}
{
struct mail_index_record *rec;
return NULL;
}
if (!mail_index_grow(index))
return NULL;
}
rec->cache_offset = 0;
return rec;
}
{
if (index->inconsistent)
return MAIL_INDEX_ERROR_INCONSISTENT;
if (index->nodiskspace)
return MAIL_INDEX_ERROR_DISKSPACE;
if (index->index_lock_timeout)
if (index->mailbox_lock_timeout)
return MAIL_INDEX_ERROR_INTERNAL;
return MAIL_INDEX_ERROR_NONE;
}
{
}