mail-cache.c revision 97144a346898fb62f9fae44fa5c076986553c66b
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen/* Copyright (c) 2003-2012 Dovecot authors, see the included COPYING file */
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainenvoid mail_cache_set_syscall_error(struct mail_cache *cache,
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen mail_index_file_set_syscall_error(cache->index, cache->filepath,
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainenstatic void mail_cache_unlink(struct mail_cache *cache)
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainenvoid mail_cache_reset(struct mail_cache *cache)
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen /* mark the cache as unusable */
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainenvoid mail_cache_set_corrupted(struct mail_cache *cache, const char *fmt, ...)
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen "Corrupted index cache file %s: %s",
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainenvoid mail_cache_file_close(struct mail_cache *cache)
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen if (munmap(cache->mmap_base, cache->mmap_length) < 0)
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen mail_cache_set_syscall_error(cache, "munmap()");
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen mail_cache_set_syscall_error(cache, "close()");
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainenstatic void mail_cache_init_file_cache(struct mail_cache *cache)
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen file_cache_set_fd(cache->file_cache, cache->fd);
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen file_cache_set_size(cache->file_cache, st.st_size);
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen mail_cache_set_syscall_error(cache, "fstat()");
04dff721d2a63566a4dbe1c856f8218b6550aa3eTimo Sirainenstatic bool mail_cache_need_reopen(struct mail_cache *cache)
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen /* we're waiting for compression */
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen /* disabled */
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen /* see if the file has changed */
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen if ((cache->index->flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0) {
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen if (nfs_safe_stat(cache->filepath, &st) < 0) {
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen mail_cache_set_syscall_error(cache, "stat()");
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen /* file changed */
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen if ((cache->index->flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0) {
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen /* if the old file has been deleted, the new file may have
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen the same inode as the old one. we'll catch this here by
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen checking if fstat() fails with ESTALE */
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen mail_cache_set_syscall_error(cache, "fstat()");
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainenint mail_cache_reopen(struct mail_cache *cache)
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen /* reopening does no good */
e10d8b1291090c26b9ef499637e6e632485ca5beTimo Sirainen mail_cache_set_syscall_error(cache, "open()");
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen ext = mail_index_view_get_ext(view, cache->ext_id);
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen if (ext == NULL || cache->hdr->file_seq != ext->reset_id) {
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen /* still different - maybe a race condition or maybe the
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen file_seq really is corrupted. either way, this shouldn't
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen happen often so we'll just mark cache to be compressed
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen later which fixes this. */
04dff721d2a63566a4dbe1c856f8218b6550aa3eTimo Sirainen cache->need_compress_file_seq = cache->hdr->file_seq;
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainenstatic void mail_cache_update_need_compress(struct mail_cache *cache)
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen const struct mail_cache_header *hdr = cache->hdr;
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen cont_percentage = hdr->continued_record_count * 100 /
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen (cache->index->map->rec_map->records_count == 0 ? 1 :
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen if (cont_percentage >= MAIL_CACHE_COMPRESS_CONTINUED_PERCENTAGE &&
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen hdr->used_file_size >= MAIL_CACHE_COMPRESS_MIN_SIZE) {
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen /* too many continued rows, compress */
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen cache->need_compress_file_seq = hdr->file_seq;
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen /* see if we've reached the max. deleted space in file */
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen hdr->used_file_size >= MAIL_CACHE_COMPRESS_MIN_SIZE)
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen cache->need_compress_file_seq = hdr->file_seq;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
if (offset == 0) {
if (!copy_hdr)
const void **data_r)
const void *hdr_data;
void *data;
if (ret < 0) {
const void **data_r)
const void *data;
if (size == 0)
if (ret < 0) {
const void *data;
int ret;
if (ret > 0)
if (ret < 0) {
return ret;
return cache;
return cache;
return cache;
unsigned int timeout_secs;
int ret;
if (ret < 0) {
if (ret <= 0)
return ret;
TRUE);
bool nonblock)
const void *data;
int i, ret;
(require_same_reset_id || i == 0)) {
ret = 0;
ret = 0;
if (ret > 0) {
sizeof(struct mail_cache_header));
return ret;
int ret = 0;
return ret;
struct mail_cache_view *
return view;
bool update)
&message_count)) {
return first_new_seq;