[dovecot-cvs] dovecot/src/lib-index mail-cache-transaction.c, 1.36, 1.37

cras at dovecot.org cras at dovecot.org
Fri Feb 4 23:34:59 EET 2005


Update of /var/lib/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv6431

Modified Files:
	mail-cache-transaction.c 
Log Message:
cleanups / minor fixes



Index: mail-cache-transaction.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache-transaction.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- mail-cache-transaction.c	19 Dec 2004 08:31:00 -0000	1.36
+++ mail-cache-transaction.c	4 Feb 2005 21:34:57 -0000	1.37
@@ -191,16 +191,17 @@
 
 static int
 mail_cache_transaction_reserve_more(struct mail_cache_transaction_ctx *ctx,
-				    size_t size, int commit)
+				    size_t block_size, int commit)
 {
 	struct mail_cache *cache = ctx->cache;
 	struct mail_cache_header *hdr = &cache->hdr_copy;
 	struct mail_cache_hole_header hole;
 	uint32_t *buf;
+	size_t size;
 
 	i_assert(cache->locked);
 
-	if (mail_cache_unlink_hole(cache, size, &hole)) {
+	if (mail_cache_unlink_hole(cache, block_size, &hole)) {
 		/* found a large enough hole. */
 		ctx->reserved_space_offset = hole.next_offset;
 		ctx->reserved_space = hole.size;
@@ -213,49 +214,46 @@
 		return -1;
 	}
 
-	if ((uoff_t)hdr->used_file_size + size > (uint32_t)-1) {
+	if ((uint32_t)-1 - hdr->used_file_size < block_size) {
 		mail_index_set_error(cache->index, "Cache file too large: %s",
 				     cache->filepath);
 		return -1;
 	}
 
-	if (!commit) {
+	if (!commit && block_size < MAIL_CACHE_MAX_RESERVED_BLOCK_SIZE) {
 		/* allocate some more space than we need */
-		size_t new_size = (size + ctx->last_grow_size) * 2;
-		if ((uoff_t)hdr->used_file_size + new_size > (uint32_t)-1)
-			new_size = (uint32_t)-1;
-		if (new_size > MAIL_CACHE_MAX_RESERVED_BLOCK_SIZE) {
-			new_size = size > MAIL_CACHE_MAX_RESERVED_BLOCK_SIZE ?
-				size : MAIL_CACHE_MAX_RESERVED_BLOCK_SIZE;
+		size_t new_block_size = (block_size + ctx->last_grow_size) * 2;
+		if (new_block_size > MAIL_CACHE_MAX_RESERVED_BLOCK_SIZE)
+			new_block_size = MAIL_CACHE_MAX_RESERVED_BLOCK_SIZE;
+
+		if ((uint32_t)-1 - hdr->used_file_size >= new_block_size) {
+			block_size = new_block_size;
+			ctx->last_grow_size = new_block_size;
 		}
-		ctx->last_grow_size = new_size;
 	}
 
-	if (mail_cache_grow_file(ctx->cache, size) < 0)
+	if (mail_cache_grow_file(ctx->cache, block_size) < 0)
 		return -1;
 
 	if (ctx->reserved_space_offset + ctx->reserved_space ==
 	    hdr->used_file_size) {
 		/* we can simply grow it */
-		ctx->reserved_space = size - ctx->reserved_space;
+		ctx->reserved_space = block_size;
 
 		/* grow reservation. it's probably the last one in the buffer,
 		   but it's not guarateed because we might have used holes
 		   as well */
 		buf = buffer_get_modifyable_data(ctx->reservations, &size);
 		size /= sizeof(uint32_t);
-		i_assert(size >= 2);
 
 		do {
+			i_assert(size >= 2);
 			size -= 2;
-			if (buf[size] == ctx->reserved_space_offset) {
-				buf[size+1] = ctx->reserved_space;
-				break;
-			}
-		} while (size >= 2);
+		} while (buf[size] != ctx->reserved_space_offset);
+		buf[size+1] = ctx->reserved_space;
 	} else {
 		ctx->reserved_space_offset = hdr->used_file_size;
-		ctx->reserved_space = size;
+		ctx->reserved_space = block_size;
 		mail_cache_transaction_add_reservation(ctx);
 	}
 
@@ -319,13 +317,14 @@
 		mail_cache_unlock(ctx->cache);
 }
 
-static uint32_t
+static int
 mail_cache_transaction_get_space(struct mail_cache_transaction_ctx *ctx,
 				 size_t min_size, size_t max_size,
-				 size_t *available_space_r, int commit)
+				 uint32_t *offset_r, size_t *available_space_r,
+				 int commit)
 {
 	int locked = ctx->cache->locked;
-	uint32_t offset;
+	uint32_t cache_file_seq;
 	size_t size;
 	int ret;
 
@@ -333,9 +332,11 @@
 	i_assert((max_size & 3) == 0);
 
 	if (min_size > ctx->reserved_space) {
+		/* not enough preallocated space in transaction, get more */
+		cache_file_seq = ctx->cache_file_seq;
 		if (!locked) {
-			if (mail_cache_transaction_lock(ctx) <= 0)
-				return 0;
+			if ((ret = mail_cache_transaction_lock(ctx)) <= 0)
+				return ret;
 		}
 		ret = mail_cache_transaction_reserve_more(ctx, max_size,
 							  commit);
@@ -343,14 +344,19 @@
 			mail_cache_unlock(ctx->cache);
 
 		if (ret < 0)
+			return -1;
+
+		if (cache_file_seq != ctx->cache_file_seq) {
+			/* cache file reopened - need to abort */
 			return 0;
+		}
 
 		size = max_size;
 	} else {
 		size = I_MIN(max_size, ctx->reserved_space);
 	}
 
-	offset = ctx->reserved_space_offset;
+	*offset_r = ctx->reserved_space_offset;
 	ctx->reserved_space_offset += size;
 	ctx->reserved_space -= size;
 	if (available_space_r != NULL)
@@ -363,14 +369,16 @@
 		mail_cache_transaction_free_space(ctx);
 	}
 
-	return offset;
+	i_assert(size >= min_size);
+	return 1;
 }
 
-static uint32_t
+static int
 mail_cache_transaction_update_index(struct mail_cache_transaction_ctx *ctx,
 				    const struct mail_cache_record *rec,
 				    const uint32_t *seq, uint32_t *seq_idx,
-				    uint32_t seq_limit, uint32_t write_offset)
+				    uint32_t seq_limit, uint32_t write_offset,
+				    uint32_t *size_r)
 {
 	struct mail_cache *cache = ctx->cache;
 	uint32_t i, old_offset, orig_write_offset;
@@ -412,7 +420,8 @@
 	}
 
 	*seq_idx = i;
-	return write_offset - orig_write_offset;
+	*size_r = write_offset - orig_write_offset;
+	return 0;
 }
 
 static int
@@ -421,9 +430,9 @@
 	struct mail_cache *cache = ctx->cache;
 	const struct mail_cache_record *rec, *tmp_rec;
 	const uint32_t *seq;
-	uint32_t write_offset, rec_pos, cache_file_seq, seq_idx;
+	uint32_t write_offset, write_size, rec_pos, seq_idx;
 	size_t size, max_size, seq_limit, seq_count;
-	int commit;
+	int ret, commit;
 
 	if (MAIL_CACHE_IS_UNUSABLE(cache))
 		return -1;
@@ -450,19 +459,12 @@
 	for (seq_idx = 0, rec_pos = 0; rec_pos < ctx->prev_pos;) {
 		max_size = ctx->prev_pos - rec_pos;
 
-		cache_file_seq = ctx->cache_file_seq;
-		write_offset = mail_cache_transaction_get_space(ctx, rec->size,
-								max_size,
-								&max_size,
-								commit);
-		if (cache_file_seq != ctx->cache_file_seq) {
-			/* cache file reopened - need to abort */
-			return 0;
-		}
-
-		if (write_offset == 0) {
-			/* nothing to write / error */
-			return ctx->prev_pos == 0 ? 0 : -1;
+		ret = mail_cache_transaction_get_space(ctx, rec->size,
+						       max_size, &write_offset,
+						       &max_size, commit);
+		if (ret <= 0) {
+			/* nothing to write / error / cache file reopened */
+			return ret;
 		}
 
 		if (rec_pos + max_size < ctx->prev_pos) {
@@ -486,11 +488,14 @@
 			return -1;
 		}
 
-		size = mail_cache_transaction_update_index(ctx, rec, seq,
-							   &seq_idx, seq_limit,
-							   write_offset);
-		rec_pos += size;
-		rec = CONST_PTR_OFFSET(rec, size);
+		if (mail_cache_transaction_update_index(ctx, rec, seq,
+							&seq_idx, seq_limit,
+							write_offset,
+							&write_size) < 0)
+			return -1;
+
+		rec_pos += write_size;
+		rec = CONST_PTR_OFFSET(rec, write_size);
 	}
 
 	/* drop the written data from buffer */
@@ -630,8 +635,8 @@
 	mail_cache_header_fields_get(cache, buffer);
 	data = buffer_get_data(buffer, &size);
 
-	offset = mail_cache_transaction_get_space(ctx, size, size, &size, TRUE);
-	if (offset == 0)
+	if (mail_cache_transaction_get_space(ctx, size, size,
+					     &offset, &size, TRUE) <= 0)
 		ret = -1;
 	else if (pwrite_full(cache->fd, data, size, offset) < 0) {
 		mail_cache_set_syscall_error(cache, "pwrite_full()");



More information about the dovecot-cvs mailing list