mail-index.c revision 006c7de040ef939a4a6bb6c75913a41a7791001a
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (C) 2002 Timo Sirainen */
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen unsigned int extra;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen index->header = (MailIndexHeader *) index->mmap_base;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen (void)munmap(index->mmap_base, index->mmap_length);
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen index->mmap_base = mmap_rw_file(index->fd, &index->mmap_length);
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen index_set_error(index, "index: mmap() failed with file %s: %m",
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen if (index->mmap_length < sizeof(MailIndexHeader)) {
635df5b4cbcd7b24c825e01d9dd66d3a4274c4c7Timo Sirainen index_set_error(index, "truncated index file %s",
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen extra = (index->mmap_length - sizeof(MailIndexHeader)) %
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen /* partial write or corrupted -
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen truncate the file to valid length */
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen (void)ftruncate(index->fd, (off_t)index->mmap_length);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen index->header = (MailIndexHeader *) index->mmap_base;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen (void)munmap(index->mmap_base, index->mmap_length);
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen if (msync(index->mmap_base, index->mmap_length, MS_SYNC) == -1) {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen index_set_error(index, "msync() failed for %s: %m",
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen if (!mail_modifylog_sync_file(index->modifylog))
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* keep index's modify stamp same as the sync file's stamp */
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen index_set_error(index, "utime() failed for %s: %m",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen index_set_error(index, "fsync() failed for %s: %m",
1b823b2b7790a1e1b7974fcf11a4c48a28e70f37Timo Sirainenint mail_index_fmsync(MailIndex *index, size_t size)
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen i_assert(index->lock_type == MAIL_LOCK_EXCLUSIVE);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (msync(index->mmap_base, size, MS_SYNC) == -1) {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen index_set_error(index, "msync() failed for %s: %m",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen index_set_error(index, "fsync() failed for %s: %m",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic void mail_index_update_header_changes(MailIndex *index)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen i_assert(index->lock_type == MAIL_LOCK_EXCLUSIVE);
c6f894e1522f7b0b6068c228900914073c145175Timo Sirainen index->header->cache_fields = index->set_cache_fields;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ((lock_type) == MAIL_LOCK_UNLOCK ? F_UNLCK : \
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen (lock_type) == MAIL_LOCK_SHARED ? F_RDLCK : F_WRLCK)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenint mail_index_try_lock(MailIndex *index, MailLockType lock_type)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen /* lock whole file */
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainenint mail_index_set_lock(MailIndex *index, MailLockType lock_type)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen /* yeah, this function is a bit messy. besides locking, it keeps
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen the index synced and in a good shape. */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* index is in inconsistent state and nothing else than
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen free() is allowed for it. */
383d0e8c24451468d6bea17e4b55d74de744abe6Timo Sirainen /* shared -> exclusive isn't allowed */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (index->lock_type == MAIL_LOCK_EXCLUSIVE) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* releasing exclusive lock */
d477acb83e14a776ece4ca94dcd1869e75d0c6eeTimo Sirainen index->header->flags &= ~MAIL_INDEX_FLAG_FSCK;
d477acb83e14a776ece4ca94dcd1869e75d0c6eeTimo Sirainen /* sync mmaped memory */
15f526e5ac611b4532568d131fcd0abf664abe41Timo Sirainen index->lock_type == MAIL_LOCK_UNLOCK && !index->updating) {
15f526e5ac611b4532568d131fcd0abf664abe41Timo Sirainen /* unlock -> lock */
7289c5600711b45f30fe289ab5b0293b51d87041Timo Sirainen /* lock whole file */
7289c5600711b45f30fe289ab5b0293b51d87041Timo Sirainen while (fcntl(index->fd, F_SETLKW, &fl) == -1) {
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen /* reset last_lookup so rebuilds don't try to use it */
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen /* we're always mmap()ed when we're locked */
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen (void)mail_index_set_lock(index, MAIL_LOCK_UNLOCK);
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen if (index->indexid != index->header->indexid) {
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen /* index was rebuilt, there's no way we can maintain
272aca0a772140d3a45a425a3fd67854ae2ccec2Timo Sirainen consistency */
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen index_set_error(index, "Warning: Inconsistency - Index "
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen "%s was rebuilt while we had it open",
1d22eaac93de41319918a1fc6de42bb302e25c1aTimo Sirainen } else if (old_lock_type == MAIL_LOCK_SHARED) {
1d22eaac93de41319918a1fc6de42bb302e25c1aTimo Sirainen /* releasing shared lock */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if ((old_flags | index->set_flags) != old_flags ||
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen (old_cache | index->set_cache_fields) != old_cache) {
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen /* need to update the header */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (mail_index_set_lock(index, MAIL_LOCK_EXCLUSIVE))
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen return mail_index_set_lock(index, MAIL_LOCK_UNLOCK);
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen /* while holding exclusive lock, keep the FSCK flag on.
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen when the lock is released, the FSCK flag will also be
return FALSE;
return FALSE;
return ret;
return TRUE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return compatible;
struct dirent *d;
const char *name;
unsigned int len;
return INDEX_FILE_PREFIX;
return NULL;
return name;
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;
/* fallback to index.hostname - we require each system to
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;