mail-cache-transaction.c revision c1b9c4531186c6a7cd92d2c353273a834f8ee66f
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek/* Copyright (c) 2003-2012 Dovecot authors, see the included COPYING file */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek MODULE_CONTEXT(obj, cache_mail_index_transaction_module)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek union mail_index_transaction_module_context module_ctx;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekstatic MODULE_CONTEXT_DEFINE_INIT(cache_mail_index_transaction_module,
769347ad4d35d43488eb98f980143495b0db415dStef Walterstatic int mail_cache_transaction_lock(struct mail_cache_transaction_ctx *ctx);
769347ad4d35d43488eb98f980143495b0db415dStef Walterstatic int mail_cache_link_locked(struct mail_cache *cache,
769347ad4d35d43488eb98f980143495b0db415dStef Walterstatic void mail_index_transaction_cache_reset(struct mail_index_transaction *t)
769347ad4d35d43488eb98f980143495b0db415dStef Walter struct mail_cache_transaction_ctx *ctx = CACHE_TRANS_CONTEXT(t);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek struct mail_index_transaction_vfuncs super = ctx->super;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekmail_index_transaction_cache_commit(struct mail_index_transaction *t,
3bea01f01d76e1e95a8239c0d3f67073992136a1Jan Zeleny struct mail_index_transaction_commit_result *result_r)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek struct mail_cache_transaction_ctx *ctx = CACHE_TRANS_CONTEXT(t);
c90fdc85cfb552911e29b4d284fd4c40ea1bb4e9Petr Cech struct mail_index_transaction_vfuncs super = ctx->super;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* a failed cache commit isn't important enough to fail the entire
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek index transaction, so we'll just ignore it */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekmail_index_transaction_cache_rollback(struct mail_index_transaction *t)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek struct mail_cache_transaction_ctx *ctx = CACHE_TRANS_CONTEXT(t);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov struct mail_index_transaction_vfuncs super = ctx->super;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekmail_cache_get_transaction(struct mail_cache_view *view,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ctx = !cache_mail_index_transaction_module.id.module_id_set ? NULL :
07e941c1bbdc752142bbd3b838c540bc7ecd0ed7Stef Walter ctx = i_new(struct mail_cache_transaction_ctx, 1);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov view->trans_view = mail_index_transaction_open_updated_view(t);
ccb2c1f30b04bf1f7a33f47748664dedb7ddd0e3Jakub Hrozek t->v.reset = mail_index_transaction_cache_reset;
d9577dbd92555b0755881e37724019ef9c578404Stef Walter t->v.commit = mail_index_transaction_cache_commit;
ccb2c1f30b04bf1f7a33f47748664dedb7ddd0e3Jakub Hrozek t->v.rollback = mail_index_transaction_cache_rollback;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek MODULE_CONTEXT_SET(t, cache_mail_index_transaction_module, ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekvoid mail_cache_transaction_reset(struct mail_cache_transaction_ctx *ctx)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ctx->cache_file_seq = MAIL_CACHE_IS_UNUSABLE(ctx->cache) ? 0 :
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek mail_index_ext_set_reset_id(ctx->trans, ctx->cache->ext_id,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekvoid mail_cache_transaction_rollback(struct mail_cache_transaction_ctx **_ctx)
7c9fe57ad82747a32721ca0a08c5569282f3e0c4Pavel Březina struct mail_cache_transaction_ctx *ctx = *_ctx;
7c9fe57ad82747a32721ca0a08c5569282f3e0c4Pavel Březina /* we already wrote to the cache file. we can't (or don't want
7c9fe57ad82747a32721ca0a08c5569282f3e0c4Pavel Březina to) delete that data, so just mark it as deleted space */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek MODULE_CONTEXT_UNSET(ctx->trans, cache_mail_index_transaction_module);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ctx->view->trans_seq1 = ctx->view->trans_seq2 = 0;
7c9fe57ad82747a32721ca0a08c5569282f3e0c4Pavel Březina mail_index_view_close(&ctx->view->trans_view);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekmail_cache_transaction_compress(struct mail_cache_transaction_ctx *ctx)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek MAIL_CACHE_IS_UNUSABLE(cache) ? 0 : cache->hdr->file_seq;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov if (mail_cache_compress(cache, trans) < 0) {
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekmail_cache_transaction_open_if_needed(struct mail_cache_transaction_ctx *ctx)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* see if we should try to reopen the cache file */
ac40d2f2b2b2fc35c95389f5e28febd580bd2b7aJakub Hrozek for (i = 0;; i++) {
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek if (!mail_index_map_get_ext_idx(cache->index->map,
ac40d2f2b2b2fc35c95389f5e28febd580bd2b7aJakub Hrozek /* index doesn't have a cache extension, but the cache
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek file exists (corrupted indexes fixed?). fix it. */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ext = array_idx(&cache->index->map->extensions, idx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek if (ext->reset_id == cache->hdr->file_seq || i == 2)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* index offsets don't match the cache file */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* the cache file appears to be too old.
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek reopening should help. */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* cache file sequence might be broken. it's also possible
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek that it was just compressed and we just haven't yet seen
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek the changes in index. try if refreshing index helps.
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek if not, compress the cache file. */
9e2c64c6d4f5560e27207193efea6536a566865eMichal Zidek if (i == 0) {
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* get the latest reset ID */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekstatic int mail_cache_transaction_lock(struct mail_cache_transaction_ctx *ctx)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek if ((ret = mail_cache_lock(cache, FALSE)) <= 0) {
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek if (!ctx->tried_compression && MAIL_CACHE_IS_UNUSABLE(cache)) {
for (i = 0; i < seq_count; i++) {
if (old_offset != 0) {
write_offset) < 0)
old_offset) < 0)
int ret;
return ret;
void *data;
int ret = 0;
return ret;
if (set)
unsigned int field_idx)
int ret;
T_BEGIN {
} T_END;
if (ret == 0) {
return ret;
unsigned int fixed_size;
int ret;
if (ret < 0)
sizeof(data_size32));
switch (decision) {
case MAIL_CACHE_DECISION_NO:
return FALSE;
case MAIL_CACHE_DECISION_TEMP:
return FALSE;
return FALSE;
const void *data;
int ret;
if (ret <= 0) {
if (ret == 0) {
int ret = 0;
while (offset != 0 &&
return ret;
int ret;
T_BEGIN {
} T_END;
return ret;