mail-index-data.c revision b045ca1be3be3c034584665f64ec3823c28c1229
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen/* Copyright (C) 2002 Timo Sirainen */
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen ((uoff_t) ((char *) (rec) - (char *) ((data)->mmap_base)))
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen/* Never compress the file if it's smaller than this */
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen/* Compress the file when deleted space reaches n% of total size */
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen/* Initial size for the file */
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen#define INDEX_DATA_INITIAL_SIZE (sizeof(MailIndexDataHeader) + 10240)
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen/* When more space is needed, grow the file n% larger than the previous size */
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainenint index_data_set_corrupted(MailIndexData *data, const char *fmt, ...)
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen index_set_error(data->index, "Corrupted index data file %s: %s",
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainenstatic int index_data_set_syscall_error(MailIndexData *data,
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen index_set_error(data->index, "%s failed with index data file %s: %m",
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainenstatic void mail_index_data_file_close(MailIndexData *data)
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen if (munmap_anon(data->mmap_base, data->mmap_full_length) < 0)
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen index_data_set_syscall_error(data, "munmap_anon()");
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen if (munmap(data->mmap_base, data->mmap_full_length) < 0)
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen index_data_set_syscall_error(data, "munmap()");
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen index_data_set_syscall_error(data, "close()");
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainenstatic int data_file_reopen(MailIndexData *data)
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen return index_data_set_syscall_error(data, "open()");
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainenstatic int mmap_update(MailIndexData *data, uoff_t pos, size_t size)
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen data->header->indexid != data->index->indexid) {
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen /* index was just rebuilt. we should have noticed
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen this before at index->set_lock() though. */
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen "Warning: Inconsistency - Index "
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen "%s was rebuilt while we had it open",
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen /* data file was deleted, reopen it */
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen /* force mmap refresh */
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen debug_mprotect(data->mmap_base, data->mmap_full_length,
6697a923d6768bf8d71f87f80b90747cf6870753Timo Sirainen data->mmap_used_length = data->header->used_file_size;
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen if (data->mmap_used_length <= data->mmap_full_length)
ab170d6cf8aeb515bac7c07b37e525cbad96c299Timo Sirainen /* file size changed, re-mmap() */
6697a923d6768bf8d71f87f80b90747cf6870753Timo Sirainen msync(data->mmap_base, data->mmap_used_length, MS_SYNC) < 0)
6697a923d6768bf8d71f87f80b90747cf6870753Timo Sirainen return index_data_set_syscall_error(data, "msync()");
80f6bd661f984145cd262445aba08a628758cde1Timo Sirainen if (munmap(data->mmap_base, data->mmap_full_length) < 0)
6697a923d6768bf8d71f87f80b90747cf6870753Timo Sirainen index_data_set_syscall_error(data, "munmap()");
6697a923d6768bf8d71f87f80b90747cf6870753Timo Sirainen data->mmap_base = mmap_rw_file(data->fd, &data->mmap_full_length);
80f6bd661f984145cd262445aba08a628758cde1Timo Sirainen return index_data_set_syscall_error(data, "mmap()");
80f6bd661f984145cd262445aba08a628758cde1Timo Sirainen if (data->mmap_full_length < sizeof(MailIndexDataHeader))
80f6bd661f984145cd262445aba08a628758cde1Timo Sirainen return index_data_set_corrupted(data, "File too small");
80f6bd661f984145cd262445aba08a628758cde1Timo Sirainen if (hdr->used_file_size < sizeof(MailIndexDataHeader)) {
80f6bd661f984145cd262445aba08a628758cde1Timo Sirainen index_data_set_corrupted(data, "used_file_size too small ("
80f6bd661f984145cd262445aba08a628758cde1Timo Sirainen if (hdr->used_file_size > data->mmap_full_length) {
80f6bd661f984145cd262445aba08a628758cde1Timo Sirainen "used_file_size larger than real file size "
80f6bd661f984145cd262445aba08a628758cde1Timo Sirainen debug_mprotect(data->mmap_base, data->mmap_full_length, data->index);
80f6bd661f984145cd262445aba08a628758cde1Timo Sirainen path = t_strconcat(index->filepath, DATA_FILE_PREFIX, NULL);
80f6bd661f984145cd262445aba08a628758cde1Timo Sirainen /* doesn't exist, rebuild the index */
80f6bd661f984145cd262445aba08a628758cde1Timo Sirainen return index_file_set_syscall_error(index, path, "open()");
return FALSE;
path);
return FALSE;
return TRUE;
const char *realpath;
return NULL;
return NULL;
return NULL;
return realpath;
int fd;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
return TRUE;
return TRUE;
return TRUE;
void *base;
return FALSE;
return TRUE;
if (pos < 0)
return FALSE;
return TRUE;
return offset;
return FALSE;
return TRUE;
return TRUE;
return TRUE;
if (pos == 0) {
return NULL;
return NULL;
return NULL;
return NULL;
return NULL;
return NULL;
return NULL;
return NULL;
return rec;
return NULL;
return NULL;
return NULL;
return NULL;
return rec;
return FALSE;
return TRUE;
return FALSE;
return NULL;