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),