mail-cache.c revision ba482d3624ca4f1b3d638e6e8470ba5134f21493
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen#include "buffer.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "byteorder.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "file-lock.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "file-set-size.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mmap-util.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "write-full.h"
463e82bdf0e990f4f2252d2b53ea23a5abe5883cTimo Sirainen#include "mail-cache-private.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen#include <stddef.h>
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen#include <unistd.h>
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen#include <sys/stat.h>
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainenunsigned int mail_cache_field_sizes[32] = {
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen sizeof(enum mail_cache_record_flag),
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen sizeof(uoff_t),
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen 16,
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen sizeof(struct mail_sent_date),
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen sizeof(time_t),
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen sizeof(uoff_t),
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen sizeof(uoff_t),
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen 0, 0, 0, 0, 0,
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen /* variable sized */
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen (unsigned int)-1, (unsigned int)-1, (unsigned int)-1, (unsigned int)-1,
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen (unsigned int)-1, (unsigned int)-1, (unsigned int)-1, (unsigned int)-1,
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen (unsigned int)-1, (unsigned int)-1, (unsigned int)-1, (unsigned int)-1,
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen (unsigned int)-1, (unsigned int)-1, (unsigned int)-1, (unsigned int)-1,
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen (unsigned int)-1, (unsigned int)-1, (unsigned int)-1, (unsigned int)-1
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen};
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainenenum mail_cache_field mail_cache_header_fields[MAIL_CACHE_HEADERS_COUNT] = {
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen MAIL_CACHE_HEADERS1,
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen MAIL_CACHE_HEADERS2,
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen MAIL_CACHE_HEADERS3,
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen MAIL_CACHE_HEADERS4
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen};
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainenuint32_t mail_cache_uint32_to_offset(uint32_t offset)
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen{
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen unsigned char buf[4];
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen i_assert(offset < 0x40000000);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen i_assert((offset & 3) == 0);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen offset >>= 2;
e6d7d19c328e7043ad35d5a52c1617bde915a16fTimo Sirainen buf[0] = 0x80 | ((offset & 0x0fe00000) >> 21);
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen buf[1] = 0x80 | ((offset & 0x001fc000) >> 14);
153de7823e64c67678b3fc95719c41a8ec5b864dTimo Sirainen buf[2] = 0x80 | ((offset & 0x00003f80) >> 7);
153de7823e64c67678b3fc95719c41a8ec5b864dTimo Sirainen buf[3] = 0x80 | (offset & 0x0000007f);
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen return *((uint32_t *) buf);
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen}
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
e6d7d19c328e7043ad35d5a52c1617bde915a16fTimo Sirainenuint32_t mail_cache_offset_to_uint32(uint32_t offset)
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen{
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen const unsigned char *buf = (const unsigned char *) &offset;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
538c58fc95200fcc5e91abdda8b912b574a2f968Timo Sirainen if ((offset & 0x80808080) != 0x80808080)
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen return 0;
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return (((uint32_t)buf[3] & 0x7f) << 2) |
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen (((uint32_t)buf[2] & 0x7f) << 9) |
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen (((uint32_t)buf[1] & 0x7f) << 16) |
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen (((uint32_t)buf[0] & 0x7f) << 23);
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen}
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainenvoid mail_cache_set_syscall_error(struct mail_cache *cache,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen const char *function)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen i_assert(function != NULL);
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen if (ENOSPACE(errno)) {
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen cache->index->nodiskspace = TRUE;
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen return;
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_index_set_error(cache->index,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen "%s failed with index cache file %s: %m",
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen function, cache->filepath);
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenvoid mail_cache_set_corrupted(struct mail_cache *cache, const char *fmt, ...)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen{
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen va_list va;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen (void)mail_cache_reset(cache);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen if (cache->silent)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen va_start(va, fmt);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen t_push();
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen mail_index_set_error(cache->index, "Corrupted index cache file %s: %s",
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen cache->filepath, t_strdup_vprintf(fmt, va));
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen t_pop();
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen va_end(va);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainenstatic void mail_cache_file_close(struct mail_cache *cache)
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen{
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen if (cache->mmap_base != NULL) {
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen if (munmap(cache->mmap_base, cache->mmap_length) < 0)
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen mail_cache_set_syscall_error(cache, "munmap()");
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen }
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen cache->mmap_base = NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen cache->hdr = NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen cache->mmap_length = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (cache->fd != -1) {
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen if (close(cache->fd) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_cache_set_syscall_error(cache, "close()");
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen cache->fd = -1;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen }
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen}
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainenstatic int mail_cache_file_reopen(struct mail_cache *cache)
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen{
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen int fd;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen fd = open(cache->filepath, O_RDWR);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen if (fd == -1) {
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen mail_cache_set_syscall_error(cache, "open()");
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen return -1;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen }
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_cache_file_close(cache);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen cache->fd = fd;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen}
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainenstatic int mmap_verify_header(struct mail_cache *cache)
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen{
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen struct mail_cache_header *hdr;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen uint32_t used_file_size;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen /* check that the header is still ok */
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen if (cache->mmap_length < sizeof(struct mail_cache_header)) {
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen mail_cache_set_corrupted(cache, "File too small");
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen return 0;
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen }
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen cache->hdr = hdr = cache->mmap_base;
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen if (cache->hdr->indexid != cache->index->indexid) {
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen /* index id changed */
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen if (cache->hdr->indexid != 0)
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen mail_cache_set_corrupted(cache, "indexid changed");
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen return 0;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen }
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (cache->trans_ctx != NULL) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* we've updated used_file_size, do nothing */
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen return 1;
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* only check the header if we're locked */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (cache->locks == 0)
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen return 1;
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen used_file_size = nbo_to_uint32(hdr->used_file_size);
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen if (used_file_size < sizeof(struct mail_cache_header)) {
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen mail_cache_set_corrupted(cache, "used_file_size too small");
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen return 0;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen }
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen if ((used_file_size % sizeof(uint32_t)) != 0) {
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen mail_cache_set_corrupted(cache, "used_file_size not aligned");
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen return 0;
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen }
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen if (used_file_size > cache->mmap_length) {
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen mail_cache_set_corrupted(cache, "used_file_size too large");
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen return 1;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen}
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainenstatic int mmap_update_nocheck(struct mail_cache *cache,
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen size_t offset, size_t size)
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen{
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen struct stat st;
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen#if 0 // FIXME
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen /* if sequence has changed, the file has to be reopened.
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen note that if main index isn't locked, it may change again */
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen if (cache->hdr->file_seq != cache->index->hdr->cache_file_seq &&
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen cache->mmap_base != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_cache_file_reopen(cache) < 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen#endif
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (offset < cache->mmap_length &&
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen size <= cache->mmap_length - offset &&
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen !cache->mmap_refresh) {
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen /* already mapped */
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen if (size != 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return 1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* requesting the whole file - see if we need to
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen re-mmap */
7889c9f65e23c83fc31cecf304cab4ab070d6aa1Timo Sirainen if (fstat(cache->fd, &st) < 0) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen mail_cache_set_syscall_error(cache, "fstat()");
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if ((uoff_t)st.st_size == cache->mmap_length)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return 1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen cache->mmap_refresh = FALSE;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (cache->mmap_base != NULL) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (cache->locks != 0) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* in the middle of transaction - write the changes */
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen if (msync(cache->mmap_base, cache->mmap_length,
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen MS_SYNC) < 0) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen mail_cache_set_syscall_error(cache, "msync()");
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (munmap(cache->mmap_base, cache->mmap_length) < 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_cache_set_syscall_error(cache, "munmap()");
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen i_assert(cache->fd != -1);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* map the whole file */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen cache->hdr = NULL;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen cache->mmap_length = 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen cache->mmap_base = mmap_rw_file(cache->fd, &cache->mmap_length);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (cache->mmap_base == MAP_FAILED) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen cache->mmap_base = NULL;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_cache_set_syscall_error(cache, "mmap()");
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
075f90abe6b6b12dc72bca21bfce8086b4b190ecTimo Sirainen /* re-mmaped, check header */
9bc6e10d9c6d6ffb4a2ed49a3b3d2a180f2a87a3Timo Sirainen return 0;
9bc6e10d9c6d6ffb4a2ed49a3b3d2a180f2a87a3Timo Sirainen}
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainenint mail_cache_mmap_update(struct mail_cache *cache, size_t offset, size_t size)
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen int synced, ret;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen ret = mmap_update_nocheck(cache, offset, size);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (ret > 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (ret < 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen if (mmap_verify_header(cache) <= 0)
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen#if 0 // FIXME
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen /* see if cache file was rebuilt - do it only once to avoid
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen infinite looping */
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen if (cache->hdr->file_seq == cache->index->hdr->cache_file_seq ||
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen synced)
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (mail_cache_file_reopen(cache) < 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return -1;
abfcd9f73b9ad1eeef4fe6e9940383defabf68c3Timo Sirainen#endif
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainenstatic int mail_cache_open_and_verify(struct mail_cache *cache, int silent)
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen{
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen struct stat st;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen int ret;
abfcd9f73b9ad1eeef4fe6e9940383defabf68c3Timo Sirainen
abfcd9f73b9ad1eeef4fe6e9940383defabf68c3Timo Sirainen mail_cache_file_close(cache);
cd5ee8630497fdbd853ef588a858b4ef619a5e03Timo Sirainen
cd5ee8630497fdbd853ef588a858b4ef619a5e03Timo Sirainen cache->fd = open(cache->filepath, O_RDWR);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen if (cache->fd == -1) {
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen if (errno == ENOENT)
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen return 0;
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen mail_cache_set_syscall_error(cache, "open()");
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return -1;
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen }
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
9887c39c5ba429169389153ca99de49e084a73f0Timo Sirainen if (fstat(cache->fd, &st) < 0) {
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen mail_cache_set_syscall_error(cache, "fstat()");
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen return -1;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen }
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen if (st.st_size < sizeof(struct mail_cache_header))
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen cache->mmap_refresh = TRUE;
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen if (mmap_update_nocheck(cache, 0, sizeof(struct mail_cache_header)) < 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen /* verify that this really is the cache for wanted index */
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen cache->silent = silent;
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen if ((ret = mmap_verify_header(cache)) <= 0) {
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen cache->silent = FALSE;
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen return ret;
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen }
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen cache->silent = FALSE;
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen return 1;
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen}
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainenstatic int mail_cache_open_or_create_file(struct mail_cache *cache,
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen struct mail_cache_header *hdr)
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen{
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen int ret, fd;
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen cache->filepath = i_strconcat(cache->index->filepath,
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen MAIL_CACHE_FILE_PREFIX, NULL);
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen ret = mail_cache_open_and_verify(cache, FALSE);
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen if (ret != 0)
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen return ret < 0 ? -1 : 0;
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen /* maybe a rebuild.. */
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen fd = file_dotlock_open(cache->filepath, NULL, NULL,
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen MAIL_CACHE_LOCK_TIMEOUT,
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen MAIL_CACHE_LOCK_CHANGE_TIMEOUT,
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen MAIL_CACHE_LOCK_IMMEDIATE_TIMEOUT, NULL, NULL);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if (fd == -1) {
41bb0aa8e357876bc9a1916a37c9e3e78e5f8185Timo Sirainen mail_cache_set_syscall_error(cache, "file_dotlock_open()");
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen return -1;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen }
dd8de60250511cc729b67249e61dfc6b4debff11Timo Sirainen
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen /* see if someone else just created the cache file */
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen ret = mail_cache_open_and_verify(cache, TRUE);
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen if (ret != 0) {
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen (void)file_dotlock_delete(cache->filepath, NULL, fd);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return ret < 0 ? -1 : 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen
cd5ee8630497fdbd853ef588a858b4ef619a5e03Timo Sirainen /* rebuild then */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (write_full(fd, hdr, sizeof(*hdr)) < 0) {
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen mail_cache_set_syscall_error(cache, "write_full()");
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen (void)file_dotlock_delete(cache->filepath, NULL, fd);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen }
659fe5d24825b160cae512538088020d97a60239Timo Sirainen if (file_set_size(fd, MAIL_CACHE_INITIAL_SIZE) < 0) {
567e57b09a49bbb2a146b13f8617698eb56237feTimo Sirainen mail_cache_set_syscall_error(cache, "file_set_size()");
567e57b09a49bbb2a146b13f8617698eb56237feTimo Sirainen (void)file_dotlock_delete(cache->filepath, NULL, fd);
567e57b09a49bbb2a146b13f8617698eb56237feTimo Sirainen return -1;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen }
659fe5d24825b160cae512538088020d97a60239Timo Sirainen
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen mail_cache_file_close(cache);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen cache->fd = dup(fd);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
41bb0aa8e357876bc9a1916a37c9e3e78e5f8185Timo Sirainen if (file_dotlock_replace(cache->filepath, NULL, fd, FALSE) < 0) {
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen mail_cache_set_syscall_error(cache, "file_dotlock_replace()");
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen return -1;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen }
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_cache_mmap_update(cache, 0,
51920d00fa50edf7b2e9b1019288d64b7abee7f3Timo Sirainen sizeof(struct mail_cache_header)) < 0)
1d3f7c1278168d5b1cbfa9a2cc9929a0909056b4Timo Sirainen return -1;
51920d00fa50edf7b2e9b1019288d64b7abee7f3Timo Sirainen
21ec6628c567eeff025af35d8027be01044b0b1aTimo Sirainen return 0;
21ec6628c567eeff025af35d8027be01044b0b1aTimo Sirainen}
21ec6628c567eeff025af35d8027be01044b0b1aTimo Sirainen
21ec6628c567eeff025af35d8027be01044b0b1aTimo Sirainenstruct mail_cache *mail_cache_open_or_create(struct mail_index *index)
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen{
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen struct mail_cache_header hdr;
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen struct mail_cache *cache;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen memset(&hdr, 0, sizeof(hdr));
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen hdr.indexid = index->indexid;
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen hdr.file_seq = index->hdr->cache_file_seq + 1;
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen hdr.used_file_size = uint32_to_nbo(sizeof(hdr));
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen cache = i_new(struct mail_cache, 1);
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen cache->index = index;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen cache->fd = -1;
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen cache->split_header_pool = pool_alloconly_create("Headers", 512);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen if (index->mmap_disable ||
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen mail_cache_open_or_create_file(cache, &hdr) < 0) {
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen /* failed for some reason - doesn't really matter,
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen just disable caching. */
cd5ee8630497fdbd853ef588a858b4ef619a5e03Timo Sirainen mail_cache_file_close(cache);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen i_free(cache->filepath);
5a7b52012bf77132bb8f466d07e0e88c63fdba42Timo Sirainen cache->filepath = i_strdup_printf("(disabled cache for %s)",
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen index->filepath);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen cache->disabled = TRUE;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen }
9887c39c5ba429169389153ca99de49e084a73f0Timo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen return cache;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen}
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenvoid mail_cache_free(struct mail_cache *cache)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen{
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen i_assert(cache->trans_ctx == NULL);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_cache_file_close(cache);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen pool_unref(cache->split_header_pool);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen i_free(cache->filepath);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen i_free(cache);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen}
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainenvoid mail_cache_set_defaults(struct mail_cache *cache,
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen enum mail_cache_field default_cache_fields,
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen enum mail_cache_field never_cache_fields)
5a7b52012bf77132bb8f466d07e0e88c63fdba42Timo Sirainen{
5a7b52012bf77132bb8f466d07e0e88c63fdba42Timo Sirainen cache->default_cache_fields = default_cache_fields;
5a7b52012bf77132bb8f466d07e0e88c63fdba42Timo Sirainen cache->never_cache_fields = never_cache_fields;
5a7b52012bf77132bb8f466d07e0e88c63fdba42Timo Sirainen}
5a7b52012bf77132bb8f466d07e0e88c63fdba42Timo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenint mail_cache_reset(struct mail_cache *cache)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen{
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen struct mail_cache_header hdr;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen int fd;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen memset(&hdr, 0, sizeof(hdr));
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen hdr.indexid = cache->index->indexid;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen hdr.file_seq = cache->index->hdr->cache_file_seq + 1;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen hdr.used_file_size = uint32_to_nbo(sizeof(hdr));
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen fd = file_dotlock_open(cache->filepath, NULL, NULL,
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen MAIL_CACHE_LOCK_TIMEOUT,
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen MAIL_CACHE_LOCK_CHANGE_TIMEOUT,
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen MAIL_CACHE_LOCK_IMMEDIATE_TIMEOUT, NULL, NULL);
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen if (fd == -1) {
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen mail_cache_set_syscall_error(cache, "file_dotlock_open()");
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen return -1;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen }
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen if (write_full(fd, &hdr, sizeof(hdr)) < 0) {
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen mail_cache_set_syscall_error(cache, "write_full()");
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen (void)file_dotlock_delete(cache->filepath, NULL, fd);
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen return -1;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (file_set_size(fd, MAIL_CACHE_INITIAL_SIZE) < 0) {
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen mail_cache_set_syscall_error(cache, "file_set_size()");
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen (void)file_dotlock_delete(cache->filepath, NULL, fd);
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen return -1;
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen }
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen mail_cache_file_close(cache);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen cache->fd = dup(fd);
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen if (file_dotlock_replace(cache->filepath, NULL, fd, FALSE) < 0) {
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen mail_cache_set_syscall_error(cache, "file_dotlock_replace()");
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen return -1;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen }
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen cache->mmap_refresh = TRUE;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen if (mail_cache_mmap_update(cache, 0,
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen sizeof(struct mail_cache_header)) < 0)
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen return -1;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen return 0;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen}
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainenint mail_cache_lock(struct mail_cache *cache, int nonblock)
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen{
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen int ret;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen if (cache->locks != 0)
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen return 1;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen if (cache->disabled)
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen return 0;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen if (nonblock) {
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen ret = file_try_lock(cache->fd, F_WRLCK);
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen if (ret < 0)
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen mail_cache_set_syscall_error(cache, "file_try_lock()");
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen } else {
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen ret = file_wait_lock(cache->fd, F_WRLCK);
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen if (ret <= 0)
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen mail_cache_set_syscall_error(cache, "file_wait_lock()");
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen }
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen if (ret > 0) {
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen if (mail_cache_mmap_update(cache, 0, 0) < 0) {
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen (void)mail_cache_unlock(cache);
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen return -1;
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen }
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen if (cache->hdr->file_seq != cache->index->hdr->cache_file_seq) {
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen mail_cache_unlock(cache);
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen return 0;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen }
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen cache->locks++;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen }
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen return ret;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen}
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
c91de2744f8c1e61e91082ff5e214450f28a0e7cTimo Sirainenint mail_cache_unlock(struct mail_cache *cache)
c91de2744f8c1e61e91082ff5e214450f28a0e7cTimo Sirainen{
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen if (--cache->locks > 0)
c91de2744f8c1e61e91082ff5e214450f28a0e7cTimo Sirainen return 0;
c91de2744f8c1e61e91082ff5e214450f28a0e7cTimo Sirainen
c91de2744f8c1e61e91082ff5e214450f28a0e7cTimo Sirainen if (file_wait_lock(cache->fd, F_UNLCK) <= 0) {
c91de2744f8c1e61e91082ff5e214450f28a0e7cTimo Sirainen mail_cache_set_syscall_error(cache, "file_wait_lock(F_UNLCK)");
a0d34d3982507f513a9d800082481e9faeb9a943Timo Sirainen return -1;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen }
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen return 0;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen}
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainenint mail_cache_is_locked(struct mail_cache *cache)
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen{
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen return cache->locks > 0;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenint mail_cache_need_reset(struct mail_cache *cache, uint32_t *new_file_seq_r)
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen{
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen if (!cache->disabled &&
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen cache->hdr->file_seq != cache->index->hdr->cache_file_seq) {
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen if (mail_cache_lock(cache, TRUE) == 0) {
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen *new_file_seq_r = cache->hdr->file_seq;
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen return TRUE;
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen }
a0d34d3982507f513a9d800082481e9faeb9a943Timo Sirainen }
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return FALSE;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen}
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainenstruct mail_cache_view *
d143077bd518de129b8d446fb58e003903e50867Timo Sirainenmail_cache_view_open(struct mail_cache *cache, struct mail_index_view *iview)
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen{
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen struct mail_cache_view *view;
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen view = i_new(struct mail_cache_view, 1);
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen view->cache = cache;
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen view->view = iview;
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen return view;
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen}
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainenvoid mail_cache_view_close(struct mail_cache_view *view)
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen{
a0d34d3982507f513a9d800082481e9faeb9a943Timo Sirainen i_free(view);
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen}
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainenvoid mail_cache_mark_missing(struct mail_cache_view *view,
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen enum mail_cache_field fields)
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen{
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen // FIXME
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen}
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen