mail-index.c revision 82282b4d57f9ff95344d09b3b762608ea067ad94
76b43e4417bab52e913da39b5f5bc2a130d3f149Timo Sirainen/* Copyright (C) 2002 Timo Sirainen */
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainenstatic const char *index_file_prefixes[] =
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainen unsigned int extra;
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainen index->header = (MailIndexHeader *) index->mmap_base;
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainen (void)munmap(index->mmap_base, index->mmap_length);
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainen index->mmap_base = mmap_rw_file(index->fd, &index->mmap_length);
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainen index_set_error(index, "index: mmap() failed with file %s: %m",
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainen if (index->mmap_length < sizeof(MailIndexHeader)) {
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainen index_set_error(index, "truncated index file %s",
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainen extra = (index->mmap_length - sizeof(MailIndexHeader)) %
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen /* partial write or corrupted -
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen truncate the file to valid length */
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen (void)ftruncate(index->fd, (off_t)index->mmap_length);
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen index->header = (MailIndexHeader *) index->mmap_base;
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen (void)munmap(index->mmap_base, index->mmap_length);
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen if (msync(index->mmap_base, index->mmap_length, MS_SYNC) == -1) {
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen index_set_error(index, "msync() failed for %s: %m",
ab1236617440e654d5c5a043b677512714b788ddTimo Sirainen if (!mail_modifylog_sync_file(index->modifylog))
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen /* keep index's modify stamp same as the sync file's stamp */
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen index_set_error(index, "utime() failed for %s: %m",
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen index_set_error(index, "fsync() failed for %s: %m",
8e50329e2c5e3a199674ae9f6d3dfcddab02487bTimo Sirainenint mail_index_fmsync(MailIndex *index, size_t size)
8e50329e2c5e3a199674ae9f6d3dfcddab02487bTimo Sirainen i_assert(index->lock_type == MAIL_LOCK_EXCLUSIVE);
d67848ba944a3172c4834c591ddc921fa4ff16b1Timo Sirainen if (msync(index->mmap_base, size, MS_SYNC) == -1) {
d67848ba944a3172c4834c591ddc921fa4ff16b1Timo Sirainen index_set_error(index, "msync() failed for %s: %m",
d67848ba944a3172c4834c591ddc921fa4ff16b1Timo Sirainen index_set_error(index, "fsync() failed for %s: %m",
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainenstatic void mail_index_update_header_changes(MailIndex *index)
4b6ddd3770c8484da7308032b75fc93b91aa1b49Timo Sirainen i_assert(index->lock_type == MAIL_LOCK_EXCLUSIVE);
4b6ddd3770c8484da7308032b75fc93b91aa1b49Timo Sirainen index->header->cache_fields = index->set_cache_fields;
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen ((lock_type) == MAIL_LOCK_UNLOCK ? F_UNLCK : \
6e8ad595d0603295f57bef576da8a3a00b55c5e2Timo Sirainen (lock_type) == MAIL_LOCK_SHARED ? F_RDLCK : F_WRLCK)
6e8ad595d0603295f57bef576da8a3a00b55c5e2Timo Sirainenint mail_index_try_lock(MailIndex *index, MailLockType lock_type)
6e8ad595d0603295f57bef576da8a3a00b55c5e2Timo Sirainen /* lock whole file */
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainenint mail_index_set_lock(MailIndex *index, MailLockType lock_type)
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen /* yeah, this function is a bit messy. besides locking, it keeps
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen the index synced and in a good shape. */
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen /* index is in inconsistent state and nothing else than
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen free() is allowed for it. */
d7cd49f01fad7c87c5a0865ebf54a548275e9feeTimo Sirainen /* shared -> exclusive isn't allowed */
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen if (index->lock_type == MAIL_LOCK_EXCLUSIVE) {
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen /* releasing exclusive lock */
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen index->header->flags &= ~MAIL_INDEX_FLAG_FSCK;
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen /* sync mmaped memory */
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen index->lock_type == MAIL_LOCK_UNLOCK && !index->updating) {
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen /* unlock -> lock */
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen /* lock whole file */
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen while (fcntl(index->fd, F_SETLKW, &fl) == -1) {
ba90e657bc68a72ab3b3021e2f4a874fac9965baTimo Sirainen /* reset last_lookup so rebuilds don't try to use it */
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen /* we're always mmap()ed when we're locked */
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen (void)mail_index_set_lock(index, MAIL_LOCK_UNLOCK);
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen if (index->indexid != index->header->indexid) {
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen /* index was rebuilt, there's no way we can maintain
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen consistency */
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen index_set_error(index, "Warning: Inconsistency - Index "
ba90e657bc68a72ab3b3021e2f4a874fac9965baTimo Sirainen "%s was rebuilt while we had it open",
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen } else if (old_lock_type == MAIL_LOCK_SHARED) {
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen /* releasing shared lock */
ba90e657bc68a72ab3b3021e2f4a874fac9965baTimo Sirainen if ((old_flags | index->set_flags) != old_flags ||
return FALSE;
return FALSE;
return ret;
return TRUE;
return FALSE;
return FALSE;
return TRUE;
int check_version)
return FALSE;
return FALSE;
return FALSE;
return compatible;
const char *name;
hostpid_init();
return name;
return name;
return NULL;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
int update_recent)
const char *path;
return FALSE;
return FALSE;
} while (FALSE);
if (failed)
return !failed;
int update_recent)
const char *path;
return FALSE;
path);
return FALSE;
return FALSE;
hostpid_init();
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
const char *name;
return FALSE;
return FALSE;
return TRUE;
const char *name;
return TRUE;
return FALSE;
return FALSE;
if (failed)
return FALSE;
return TRUE;
return TRUE;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
unsigned int lookup_seq)
unsigned int seq;
return NULL;
return NULL;
return NULL;
sizeof(MailIndexHeader));
sizeof(MailIndexRecord));
return NULL;
return rec;
seq++;
rec++;
return rec;
return NULL;
return NULL;
return rec;
return NULL;
unsigned int first_uid,
unsigned int last_uid)
return NULL;
if (pos != 0) {
return (MailIndexRecord *)
return NULL;
sizeof(MailIndexHeader));
return NULL;
return rec;
rec++;
return NULL;
return NULL;
return NULL;
return NULL;
unsigned int seq;
return INDEX_POSITION_INDEX(
return INDEX_POSITION_INDEX(
seq++;
return seq;
rec++;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
if (seq != 0) {
return FALSE;
if (seq != 0) {
return FALSE;
return FALSE;
return TRUE;
int external_change)
if (pos < 0) {
return FALSE;
return FALSE;
return FALSE;
return TRUE;