mail-cache-compress.c revision a817fdcc43aedf423e2134091d5f83f91d64bcc9
06509499ae5b6676db799057108433170a23ed28fuankg/* Copyright (C) 2003-2004 Timo Sirainen */
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg#include "lib.h"
06509499ae5b6676db799057108433170a23ed28fuankg#include "buffer.h"
06509499ae5b6676db799057108433170a23ed28fuankg#include "ostream.h"
06509499ae5b6676db799057108433170a23ed28fuankg#include "file-dotlock.h"
06509499ae5b6676db799057108433170a23ed28fuankg#include "file-cache.h"
06509499ae5b6676db799057108433170a23ed28fuankg#include "file-set-size.h"
06509499ae5b6676db799057108433170a23ed28fuankg#include "mail-cache-private.h"
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg#include <sys/stat.h>
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankgstruct mail_cache_copy_context {
06509499ae5b6676db799057108433170a23ed28fuankg int new_msg;
06509499ae5b6676db799057108433170a23ed28fuankg buffer_t *buffer, *field_seen;
06509499ae5b6676db799057108433170a23ed28fuankg uint8_t field_seen_value;
06509499ae5b6676db799057108433170a23ed28fuankg};
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankgstatic void mail_cache_merge_bitmask(struct mail_cache *cache, buffer_t *buffer,
06509499ae5b6676db799057108433170a23ed28fuankg uint32_t field, const void *data,
06509499ae5b6676db799057108433170a23ed28fuankg size_t data_size)
06509499ae5b6676db799057108433170a23ed28fuankg{
06509499ae5b6676db799057108433170a23ed28fuankg void *buf_data;
06509499ae5b6676db799057108433170a23ed28fuankg uint32_t buf_field;
06509499ae5b6676db799057108433170a23ed28fuankg unsigned int i, buf_data_size;
06509499ae5b6676db799057108433170a23ed28fuankg size_t pos, buf_size;
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg buf_data = buffer_get_modifyable_data(buffer, &buf_size);
06509499ae5b6676db799057108433170a23ed28fuankg for (pos = sizeof(struct mail_cache_record); pos < buf_size; ) {
06509499ae5b6676db799057108433170a23ed28fuankg buf_field = *((uint32_t *)PTR_OFFSET(buf_data, pos));
06509499ae5b6676db799057108433170a23ed28fuankg pos += sizeof(uint32_t);
06509499ae5b6676db799057108433170a23ed28fuankg i_assert(buf_field < cache->fields_count);
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg buf_data_size = cache->fields[buf_field].field.field_size;
06509499ae5b6676db799057108433170a23ed28fuankg if (buf_data_size == (unsigned int)-1) {
06509499ae5b6676db799057108433170a23ed28fuankg buf_data_size =
06509499ae5b6676db799057108433170a23ed28fuankg *((uint32_t *)PTR_OFFSET(buf_data, pos));
06509499ae5b6676db799057108433170a23ed28fuankg pos += sizeof(uint32_t);
06509499ae5b6676db799057108433170a23ed28fuankg }
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg if (buf_field == field) {
06509499ae5b6676db799057108433170a23ed28fuankg /* @UNSAFE: found it, do the merging */
06509499ae5b6676db799057108433170a23ed28fuankg unsigned char *dest = PTR_OFFSET(buf_data, pos);
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg i_assert(buf_data_size == data_size);
06509499ae5b6676db799057108433170a23ed28fuankg i_assert(pos + buf_data_size <= buf_size);
06509499ae5b6676db799057108433170a23ed28fuankg for (i = 0; i < buf_data_size; i++)
06509499ae5b6676db799057108433170a23ed28fuankg dest[i] |= ((const unsigned char*)data)[i];
06509499ae5b6676db799057108433170a23ed28fuankg break;
06509499ae5b6676db799057108433170a23ed28fuankg }
06509499ae5b6676db799057108433170a23ed28fuankg pos += (buf_data_size + 3) & ~3;
06509499ae5b6676db799057108433170a23ed28fuankg i_assert(pos <= buf_size);
06509499ae5b6676db799057108433170a23ed28fuankg }
06509499ae5b6676db799057108433170a23ed28fuankg}
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankgstatic int
06509499ae5b6676db799057108433170a23ed28fuankgmail_cache_compress_callback(struct mail_cache_view *view, uint32_t field,
06509499ae5b6676db799057108433170a23ed28fuankg const void *data, size_t data_size, void *context)
06509499ae5b6676db799057108433170a23ed28fuankg{
06509499ae5b6676db799057108433170a23ed28fuankg struct mail_cache_copy_context *ctx = context;
06509499ae5b6676db799057108433170a23ed28fuankg struct mail_cache_field *cache_field;
06509499ae5b6676db799057108433170a23ed28fuankg enum mail_cache_decision_type dec;
06509499ae5b6676db799057108433170a23ed28fuankg uint8_t *field_seen;
06509499ae5b6676db799057108433170a23ed28fuankg uint32_t size32;
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg cache_field = &view->cache->fields[field].field;
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg field_seen = buffer_get_space_unsafe(ctx->field_seen, field, 1);
06509499ae5b6676db799057108433170a23ed28fuankg if (*field_seen == ctx->field_seen_value) {
06509499ae5b6676db799057108433170a23ed28fuankg /* duplicate */
06509499ae5b6676db799057108433170a23ed28fuankg if (cache_field->type == MAIL_CACHE_FIELD_BITMASK) {
06509499ae5b6676db799057108433170a23ed28fuankg mail_cache_merge_bitmask(view->cache, ctx->buffer,
06509499ae5b6676db799057108433170a23ed28fuankg field, data, data_size);
06509499ae5b6676db799057108433170a23ed28fuankg }
06509499ae5b6676db799057108433170a23ed28fuankg return 1;
06509499ae5b6676db799057108433170a23ed28fuankg }
06509499ae5b6676db799057108433170a23ed28fuankg *field_seen = ctx->field_seen_value;
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg dec = cache_field->decision & ~MAIL_CACHE_DECISION_FORCED;
06509499ae5b6676db799057108433170a23ed28fuankg if (ctx->new_msg) {
06509499ae5b6676db799057108433170a23ed28fuankg if (dec == MAIL_CACHE_DECISION_NO)
06509499ae5b6676db799057108433170a23ed28fuankg return 1;
06509499ae5b6676db799057108433170a23ed28fuankg } else {
06509499ae5b6676db799057108433170a23ed28fuankg if (dec != MAIL_CACHE_DECISION_YES)
06509499ae5b6676db799057108433170a23ed28fuankg return 1;
06509499ae5b6676db799057108433170a23ed28fuankg }
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg buffer_append(ctx->buffer, &field, sizeof(field));
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg if (cache_field->field_size == (unsigned int)-1) {
06509499ae5b6676db799057108433170a23ed28fuankg size32 = (uint32_t)data_size;
06509499ae5b6676db799057108433170a23ed28fuankg buffer_append(ctx->buffer, &size32, sizeof(size32));
06509499ae5b6676db799057108433170a23ed28fuankg }
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg buffer_append(ctx->buffer, data, data_size);
06509499ae5b6676db799057108433170a23ed28fuankg if ((data_size & 3) != 0)
06509499ae5b6676db799057108433170a23ed28fuankg buffer_append_zero(ctx->buffer, 4 - (data_size & 3));
06509499ae5b6676db799057108433170a23ed28fuankg return 1;
06509499ae5b6676db799057108433170a23ed28fuankg}
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankgstatic uint32_t
06509499ae5b6676db799057108433170a23ed28fuankgget_next_file_seq(struct mail_cache *cache, struct mail_index_view *view)
06509499ae5b6676db799057108433170a23ed28fuankg{
06509499ae5b6676db799057108433170a23ed28fuankg const struct mail_index_ext *ext;
06509499ae5b6676db799057108433170a23ed28fuankg uint32_t file_seq;
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg ext = mail_index_view_get_ext(view, cache->ext_id);
06509499ae5b6676db799057108433170a23ed28fuankg file_seq = ext != NULL ? ext->reset_id + 1 : (uint32_t)ioloop_time;
06509499ae5b6676db799057108433170a23ed28fuankg return file_seq != 0 ? file_seq : 1;
06509499ae5b6676db799057108433170a23ed28fuankg}
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankgstatic int
06509499ae5b6676db799057108433170a23ed28fuankgmail_cache_copy(struct mail_cache *cache, struct mail_index_view *view, int fd)
06509499ae5b6676db799057108433170a23ed28fuankg{
06509499ae5b6676db799057108433170a23ed28fuankg struct mail_cache_copy_context ctx;
06509499ae5b6676db799057108433170a23ed28fuankg struct mail_cache_view *cache_view;
06509499ae5b6676db799057108433170a23ed28fuankg struct mail_index_transaction *t;
06509499ae5b6676db799057108433170a23ed28fuankg const struct mail_index_header *idx_hdr;
06509499ae5b6676db799057108433170a23ed28fuankg struct mail_cache_header hdr;
06509499ae5b6676db799057108433170a23ed28fuankg struct mail_cache_record cache_rec;
06509499ae5b6676db799057108433170a23ed28fuankg struct ostream *output;
06509499ae5b6676db799057108433170a23ed28fuankg buffer_t *buffer;
06509499ae5b6676db799057108433170a23ed28fuankg uint32_t i, message_count, seq, first_new_seq, old_offset;
06509499ae5b6676db799057108433170a23ed28fuankg uoff_t offset;
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg /* get sequence of first message which doesn't need its temp fields
06509499ae5b6676db799057108433170a23ed28fuankg removed. */
06509499ae5b6676db799057108433170a23ed28fuankg idx_hdr = mail_index_get_header(view);
06509499ae5b6676db799057108433170a23ed28fuankg if (idx_hdr->day_first_uid[7] == 0) {
06509499ae5b6676db799057108433170a23ed28fuankg first_new_seq = 1;
06509499ae5b6676db799057108433170a23ed28fuankg message_count = mail_index_view_get_messages_count(view);
06509499ae5b6676db799057108433170a23ed28fuankg } else {
06509499ae5b6676db799057108433170a23ed28fuankg if (mail_index_lookup_uid_range(view, idx_hdr->day_first_uid[7],
06509499ae5b6676db799057108433170a23ed28fuankg (uint32_t)-1, &first_new_seq,
06509499ae5b6676db799057108433170a23ed28fuankg &message_count) < 0)
06509499ae5b6676db799057108433170a23ed28fuankg return -1;
06509499ae5b6676db799057108433170a23ed28fuankg if (first_new_seq == 0)
06509499ae5b6676db799057108433170a23ed28fuankg first_new_seq = message_count+1;
06509499ae5b6676db799057108433170a23ed28fuankg }
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg cache_view = mail_cache_view_open(cache, view);
06509499ae5b6676db799057108433170a23ed28fuankg t = mail_index_transaction_begin(view, FALSE, TRUE);
06509499ae5b6676db799057108433170a23ed28fuankg output = o_stream_create_file(fd, default_pool, 0, FALSE);
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg memset(&hdr, 0, sizeof(hdr));
06509499ae5b6676db799057108433170a23ed28fuankg hdr.version = MAIL_CACHE_VERSION;
06509499ae5b6676db799057108433170a23ed28fuankg hdr.indexid = idx_hdr->indexid;
06509499ae5b6676db799057108433170a23ed28fuankg hdr.file_seq = get_next_file_seq(cache, view);
06509499ae5b6676db799057108433170a23ed28fuankg o_stream_send(output, &hdr, sizeof(hdr));
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg memset(&ctx, 0, sizeof(ctx));
06509499ae5b6676db799057108433170a23ed28fuankg ctx.buffer = buffer_create_dynamic(default_pool, 4096);
06509499ae5b6676db799057108433170a23ed28fuankg ctx.field_seen = buffer_create_dynamic(default_pool, 64);
06509499ae5b6676db799057108433170a23ed28fuankg ctx.field_seen_value = 0;
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg mail_index_ext_reset(t, cache->ext_id, hdr.file_seq);
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg for (seq = 1; seq <= message_count; seq++) {
06509499ae5b6676db799057108433170a23ed28fuankg ctx.new_msg = seq >= first_new_seq;
06509499ae5b6676db799057108433170a23ed28fuankg buffer_set_used_size(ctx.buffer, 0);
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg if (++ctx.field_seen_value == 0) {
06509499ae5b6676db799057108433170a23ed28fuankg memset(buffer_get_modifyable_data(ctx.field_seen, NULL),
06509499ae5b6676db799057108433170a23ed28fuankg 0, buffer_get_size(ctx.field_seen));
06509499ae5b6676db799057108433170a23ed28fuankg ctx.field_seen_value++;
06509499ae5b6676db799057108433170a23ed28fuankg }
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg memset(&cache_rec, 0, sizeof(cache_rec));
06509499ae5b6676db799057108433170a23ed28fuankg buffer_append(ctx.buffer, &cache_rec, sizeof(cache_rec));
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg (void)mail_cache_foreach(cache_view, seq,
06509499ae5b6676db799057108433170a23ed28fuankg mail_cache_compress_callback, &ctx);
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg cache_rec.size = buffer_get_used_size(ctx.buffer);
06509499ae5b6676db799057108433170a23ed28fuankg if (cache_rec.size == sizeof(cache_rec))
06509499ae5b6676db799057108433170a23ed28fuankg continue;
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg mail_index_update_ext(t, seq, cache->ext_id, &output->offset,
06509499ae5b6676db799057108433170a23ed28fuankg &old_offset);
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg buffer_write(ctx.buffer, 0, &cache_rec, sizeof(cache_rec));
06509499ae5b6676db799057108433170a23ed28fuankg o_stream_send(output, ctx.buffer->data, cache_rec.size);
06509499ae5b6676db799057108433170a23ed28fuankg }
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg if (cache->fields_count != 0) {
06509499ae5b6676db799057108433170a23ed28fuankg hdr.field_header_offset =
06509499ae5b6676db799057108433170a23ed28fuankg mail_index_uint32_to_offset(output->offset);
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg /* we wrote everything using our internal field ids. so we want
06509499ae5b6676db799057108433170a23ed28fuankg mail_cache_header_fields_get() to use them and ignore any
06509499ae5b6676db799057108433170a23ed28fuankg existing id mappings in the old cache file. */
06509499ae5b6676db799057108433170a23ed28fuankg cache->file_fields_count = 0;
06509499ae5b6676db799057108433170a23ed28fuankg for (i = 0; i < cache->fields_count; i++)
06509499ae5b6676db799057108433170a23ed28fuankg cache->field_file_map[i] = (uint32_t)-1;
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg t_push();
06509499ae5b6676db799057108433170a23ed28fuankg buffer = buffer_create_dynamic(pool_datastack_create(), 256);
06509499ae5b6676db799057108433170a23ed28fuankg mail_cache_header_fields_get(cache, buffer);
06509499ae5b6676db799057108433170a23ed28fuankg o_stream_send(output, buffer_get_data(buffer, NULL),
06509499ae5b6676db799057108433170a23ed28fuankg buffer_get_used_size(buffer));
06509499ae5b6676db799057108433170a23ed28fuankg t_pop();
06509499ae5b6676db799057108433170a23ed28fuankg }
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg hdr.used_file_size = output->offset;
06509499ae5b6676db799057108433170a23ed28fuankg buffer_free(ctx.buffer);
06509499ae5b6676db799057108433170a23ed28fuankg buffer_free(ctx.field_seen);
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg o_stream_seek(output, 0);
06509499ae5b6676db799057108433170a23ed28fuankg o_stream_send(output, &hdr, sizeof(hdr));
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg mail_cache_view_close(cache_view);
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg if (o_stream_flush(output) < 0) {
06509499ae5b6676db799057108433170a23ed28fuankg errno = output->stream_errno;
06509499ae5b6676db799057108433170a23ed28fuankg mail_cache_set_syscall_error(cache, "o_stream_flush()");
06509499ae5b6676db799057108433170a23ed28fuankg (void)mail_index_transaction_rollback(t);
06509499ae5b6676db799057108433170a23ed28fuankg o_stream_unref(output);
06509499ae5b6676db799057108433170a23ed28fuankg return -1;
06509499ae5b6676db799057108433170a23ed28fuankg }
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg if (hdr.used_file_size < MAIL_CACHE_INITIAL_SIZE) {
06509499ae5b6676db799057108433170a23ed28fuankg /* grow the file some more. doesn't matter if it fails */
06509499ae5b6676db799057108433170a23ed28fuankg (void)file_set_size(fd, MAIL_CACHE_INITIAL_SIZE);
06509499ae5b6676db799057108433170a23ed28fuankg }
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg o_stream_unref(output);
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg if (fdatasync(fd) < 0) {
06509499ae5b6676db799057108433170a23ed28fuankg mail_cache_set_syscall_error(cache, "fdatasync()");
06509499ae5b6676db799057108433170a23ed28fuankg (void)mail_index_transaction_rollback(t);
06509499ae5b6676db799057108433170a23ed28fuankg return -1;
06509499ae5b6676db799057108433170a23ed28fuankg }
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg return mail_index_transaction_commit(t, &seq, &offset);
06509499ae5b6676db799057108433170a23ed28fuankg}
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankgstatic int mail_cache_compress_locked(struct mail_cache *cache,
06509499ae5b6676db799057108433170a23ed28fuankg struct mail_index_view *view)
06509499ae5b6676db799057108433170a23ed28fuankg{
06509499ae5b6676db799057108433170a23ed28fuankg struct dotlock *dotlock;
06509499ae5b6676db799057108433170a23ed28fuankg mode_t old_mask;
06509499ae5b6676db799057108433170a23ed28fuankg int fd;
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg /* get the latest info on fields */
06509499ae5b6676db799057108433170a23ed28fuankg if (mail_cache_header_fields_read(cache) < 0)
06509499ae5b6676db799057108433170a23ed28fuankg return -1;
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg#ifdef DEBUG
06509499ae5b6676db799057108433170a23ed28fuankg i_warning("Compressing cache file %s", cache->filepath);
06509499ae5b6676db799057108433170a23ed28fuankg#endif
06509499ae5b6676db799057108433170a23ed28fuankg
06509499ae5b6676db799057108433170a23ed28fuankg old_mask = umask(cache->index->mode ^ 0666);
06509499ae5b6676db799057108433170a23ed28fuankg fd = file_dotlock_open(&cache->dotlock_settings, cache->filepath,
0, &dotlock);
umask(old_mask);
if (fd == -1) {
mail_cache_set_syscall_error(cache, "file_dotlock_open()");
return -1;
}
if (cache->index->gid != (gid_t)-1 &&
fchown(fd, (uid_t)-1, cache->index->gid) < 0) {
mail_cache_set_syscall_error(cache, "fchown()");
file_dotlock_delete(&dotlock);
return -1;
}
// FIXME: check that cache file wasn't just recreated
if (mail_cache_copy(cache, view, fd) < 0) {
(void)file_dotlock_delete(&dotlock);
return -1;
}
if (file_dotlock_replace(&dotlock,
DOTLOCK_REPLACE_FLAG_DONT_CLOSE_FD) < 0) {
mail_cache_set_syscall_error(cache,
"file_dotlock_replace()");
(void)close(fd);
return -1;
}
mail_cache_file_close(cache);
cache->fd = fd;
if (cache->file_cache != NULL)
file_cache_set_fd(cache->file_cache, cache->fd);
if (mail_cache_map(cache, 0, 0) < 0)
return -1;
if (mail_cache_header_fields_read(cache) < 0)
return -1;
cache->need_compress = FALSE;
return 0;
}
int mail_cache_compress(struct mail_cache *cache, struct mail_index_view *view)
{
int ret;
if (MAIL_INDEX_IS_IN_MEMORY(cache->index))
return 0;
if (cache->index->lock_method == MAIL_INDEX_LOCK_DOTLOCK) {
/* we're using dotlocking, cache file creation itself creates
the dotlock file we need. */
return mail_cache_compress_locked(cache, view);
}
switch (mail_cache_lock(cache)) {
case -1:
return -1;
case 0:
/* couldn't lock, either it's broken or doesn't exist.
just start creating it. */
return mail_cache_compress_locked(cache, view);
default:
/* locking succeeded. */
ret = mail_cache_compress_locked(cache, view);
if (mail_cache_unlock(cache) < 0)
ret = -1;
return ret;
}
}
int mail_cache_need_compress(struct mail_cache *cache)
{
return cache->need_compress;
}