mail-cache.c revision 2131ef7a3390f15ea6a958256ea54908f1096350
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina/* Copyright (c) 2003-2007 Dovecot authors, see the included COPYING file */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinavoid mail_cache_set_syscall_error(struct mail_cache *cache,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina "%s failed with index cache file %s: %m",
2a25713afc6beefb11a799903a43f695c5d7a4f9Adam Tkacvoid mail_cache_set_corrupted(struct mail_cache *cache, const char *fmt, ...)
769347ad4d35d43488eb98f980143495b0db415dStef Walter /* mark the cache as unusable */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina mail_index_set_error(cache->index, "Corrupted index cache file %s: %s",
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinavoid mail_cache_file_close(struct mail_cache *cache)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (munmap(cache->mmap_base, cache->mmap_length) < 0)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina mail_cache_set_syscall_error(cache, "munmap()");
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina mail_cache_set_syscall_error(cache, "close()");
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinastatic void mail_cache_init_file_cache(struct mail_cache *cache)
8bccd95e275fae760a991da394235e4e70e57bbdMichal Zidek nfs_flush_attr_cache_fd(cache->filepath, cache->fd);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina nfs_flush_read_cache(cache->filepath, cache->fd,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina file_cache_set_fd(cache->file_cache, cache->fd);
7c9fe57ad82747a32721ca0a08c5569282f3e0c4Pavel Březina file_cache_set_size(cache->file_cache, st.st_size);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov mail_cache_set_syscall_error(cache, "fstat()");
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashovstatic bool mail_cache_need_reopen(struct mail_cache *cache)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* we're waiting for compression */
2a25713afc6beefb11a799903a43f695c5d7a4f9Adam Tkac /* disabled */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* see if the file has changed */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (nfs_safe_stat(cache->filepath, &st) < 0) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov mail_cache_set_syscall_error(cache, "stat()");
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* if the old file has been deleted, the new file may have
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina the same inode as the old one, but we'll catch this by
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina flushing attribute cache and seeing if it fails with
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (!nfs_flush_attr_cache_fd(cache->filepath, cache->fd))
52e3ee5c5ff2c5a4341041826a803ad42d2b2de7Pavel Březinaint mail_cache_reopen(struct mail_cache *cache)
52e3ee5c5ff2c5a4341041826a803ad42d2b2de7Pavel Březina /* reopening does no good */
a5f300adf19ec9c3087c62bd93a5175db799687aPavel Březina mail_cache_set_syscall_error(cache, "open()");
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov if (mail_cache_header_fields_read(cache) < 0)
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ext = mail_index_view_get_ext(view, cache->ext_id);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (ext == NULL || cache->hdr->file_seq != ext->reset_id) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* still different - maybe a race condition or maybe the
6f8ae17869f4f8a1496e3f171ae6b5c11af1845cPavel Březina file_seq really is corrupted. either way, this shouldn't
6f8ae17869f4f8a1496e3f171ae6b5c11af1845cPavel Březina happen often so we'll just mark cache to be compressed
7c9fe57ad82747a32721ca0a08c5569282f3e0c4Pavel Březina later which fixes this. */
6f8ae17869f4f8a1496e3f171ae6b5c11af1845cPavel Březina cache->need_compress_file_seq = cache->hdr->file_seq;
ac40d2f2b2b2fc35c95389f5e28febd580bd2b7aJakub Hrozekstatic bool mail_cache_verify_header(struct mail_cache *cache)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina const struct mail_cache_header *hdr = cache->data;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* check that the header is still ok */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (cache->mmap_length < sizeof(struct mail_cache_header)) {
cb75b275d15beedd1fdecc1f8ced657fba282218Lukas Slebodnik mail_cache_set_corrupted(cache, "File too small");
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* version changed - upgrade silently */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (hdr->compat_sizeof_uoff_t != sizeof(uoff_t)) {
458f5245dd5130d12666cce6faf8ef1ec7f80169Pavel Reichl /* architecture change - handle silently(?) */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* index id changed - handle silently */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina mail_cache_set_corrupted(cache, "file_seq is 0");
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* only check the header if we're locked */
677a31351c80453d9ce006481364399a96312052René Genz if (hdr->used_file_size < sizeof(struct mail_cache_header)) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina mail_cache_set_corrupted(cache, "used_file_size too small");
cb75b275d15beedd1fdecc1f8ced657fba282218Lukas Slebodnik if ((hdr->used_file_size % sizeof(uint32_t)) != 0) {
3f9e2c24dbc14b2eafbe4f5a5ee16fe9af3c3f75Jakub Hrozek mail_cache_set_corrupted(cache, "used_file_size not aligned");
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina mail_cache_set_corrupted(cache, "used_file_size too large");
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinaint mail_cache_map(struct mail_cache *cache, size_t offset, size_t size)
if (ret < 0) {
if (offset == 0) {
int ret;
if (ret > 0)
if (ret < 0) {
return ret;
return cache;
return cache;
return cache;
int ret;
if (ret < 0) {
if (ret <= 0)
return ret;
int i, ret;
(require_same_reset_id || i == 0)) {
if (ret <= 0)
ret = 0;
if (ret > 0) {
sizeof(struct mail_cache_header));
return ret;
unsigned int cont_percentage;
int ret = 0;
return ret;
struct mail_cache_view *
return view;