Mercurial > dovecot > original-hg > dovecot-1.2
changeset 5389:00645e05ae96 HEAD
If we update the fields list in header, it's committed immediately so if the
transaction gets rollbacked, don't overwrite the already committed header.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 23 Mar 2007 05:41:42 +0200 |
parents | ce1bfc98df29 |
children | 4eeec560df01 |
files | src/lib-index/mail-cache-transaction.c |
diffstat | 1 files changed, 33 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-cache-transaction.c Fri Mar 23 05:07:08 2007 +0200 +++ b/src/lib-index/mail-cache-transaction.c Fri Mar 23 05:41:42 2007 +0200 @@ -209,6 +209,34 @@ array_append(&ctx->reservations, &res, 1); } +static void +mail_cache_transaction_partial_commit(struct mail_cache_transaction_ctx *ctx, + uint32_t offset, uint32_t size) +{ + struct mail_cache_reservation *res; + unsigned int i, count; + + if (offset + size == ctx->cache->hdr_copy.used_file_size && + offset + size == ctx->reserved_space_offset) { + i_assert(ctx->reserved_space == 0); + ctx->reserved_space_offset = 0; + } + + res = array_get_modifyable(&ctx->reservations, &count); + for (i = 0; i < count; i++) { + if (res[i].offset == offset) { + if (res[i].size == size) { + array_delete(&ctx->reservations, i, 1); + } else { + i_assert(res[i].size > size); + res[i].offset += size; + res[i].size -= size; + } + break; + } + } +} + static int mail_cache_transaction_reserve_more(struct mail_cache_transaction_ctx *ctx, size_t block_size, bool commit) @@ -676,6 +704,11 @@ &hdr_offset) < 0) ret = -1; else { + /* if we rollback the transaction, we must not overwrite this + area because it's already committed after updating the + header offset */ + mail_cache_transaction_partial_commit(ctx, offset, size); + /* after it's guaranteed to be in disk, update header offset */ offset = mail_index_uint32_to_offset(offset); if (mail_cache_write(cache, &offset, sizeof(offset),