void mail_cache_sync_lost_handler(struct mail_index *index)
{
	struct mail_cache *cache = index->cache;

	if (!MAIL_CACHE_IS_UNUSABLE(cache)) {
		mail_index_flush_read_cache(cache->index, cache->filepath,
					    cache->fd, cache->locked);
	}
	file_cache_invalidate(cache->file_cache, 0, (uoff_t)-1);
}
Beispiel #2
0
static void squat_uidlist_free_from_memory(struct squat_uidlist *uidlist)
{
	size_t page_size = mmap_get_page_size();

	if (uidlist->file_cache != NULL) {
		file_cache_invalidate(uidlist->file_cache,
				      page_size, (uoff_t)-1);
	} else {
		(void)madvise(uidlist->mmap_base, uidlist->mmap_size,
			      MADV_DONTNEED);
	}
}
int mail_cache_sync_handler(struct mail_index_sync_map_ctx *sync_ctx,
			    uint32_t seq ATTR_UNUSED,
			    void *old_data, const void *new_data,
			    void **context)
{
	struct mail_index_view *view = sync_ctx->view;
	struct mail_index *index = view->index;
	struct mail_cache *cache = index->cache;
	struct mail_cache_sync_context *ctx = *context;
	const uint32_t *old_cache_offset = old_data;
	const uint32_t *new_cache_offset = new_data;
	uint32_t cache_file_seq, cur_seq, tail_seq;
	uoff_t cur_offset, tail_offset;
	int ret;

	if (new_cache_offset == NULL) {
		mail_cache_handler_deinit(sync_ctx, ctx);
		*context = NULL;
		return 1;
	}

	ctx = mail_cache_handler_init(context);
	if (cache->file_cache != NULL && !MAIL_CACHE_IS_UNUSABLE(cache)) {
		/* flush read cache only once per sync */
		if (!ctx->nfs_read_cache_flushed &&
		    (index->flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0) {
			ctx->nfs_read_cache_flushed = TRUE;
			mail_index_flush_read_cache(index,
						    cache->filepath, cache->fd,
						    cache->locked);
		}
		/* don't invalidate anything that's already been invalidated
		   within this sync. */
		if (*new_cache_offset < ctx->invalidate_highwater) {
			file_cache_invalidate(cache->file_cache,
					      *new_cache_offset,
					      ctx->invalidate_highwater -
					      *new_cache_offset);
			ctx->invalidate_highwater = *new_cache_offset;
		}
	}

	if (*old_cache_offset == 0 || *old_cache_offset == *new_cache_offset ||
	    sync_ctx->type == MAIL_INDEX_SYNC_HANDLER_VIEW)
		return 1;

	mail_transaction_log_view_get_prev_pos(view->log_view,
					       &cur_seq, &cur_offset);
	mail_transaction_log_get_mailbox_sync_pos(index->log,
						  &tail_seq, &tail_offset);
	if (LOG_IS_BEFORE(cur_seq, cur_offset, tail_seq, tail_offset)) {
		/* already been linked */
		return 1;
	}

	/* we'll need to link the old and new cache records */
	ret = mail_cache_handler_lock(ctx, cache);
	if (ret <= 0)
		return ret < 0 ? -1 : 1;

	if (!get_cache_file_seq(view, &cache_file_seq))
		return 1;

	if (cache_file_seq != cache->hdr->file_seq) {
		/* cache has been compressed, don't modify it */
		return 1;
	}

	if (mail_cache_link(cache, *old_cache_offset, *new_cache_offset) < 0)
		return -1;

	return 1;
}