changeset 8956:ec6428000c5b HEAD

dbox: More error handling fixes.
author Timo Sirainen <tss@iki.fi>
date Wed, 11 Mar 2009 19:10:01 -0400
parents 4d4e1cbb61a0
children a93c247f80dc
files src/lib-storage/index/dbox/dbox-file.h src/lib-storage/index/dbox/dbox-map.c src/lib-storage/index/dbox/dbox-sync-file.c
diffstat 3 files changed, 42 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/dbox/dbox-file.h	Wed Mar 11 18:42:13 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-file.h	Wed Mar 11 19:10:01 2009 -0400
@@ -93,6 +93,8 @@
 
 	uoff_t cur_offset;
 	uoff_t cur_physical_size;
+	/* first appended message's offset (while appending) */
+	uoff_t first_append_offset;
 
 	char *fname;
 	char *current_path;
--- a/src/lib-storage/index/dbox/dbox-map.c	Wed Mar 11 18:42:13 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-map.c	Wed Mar 11 19:10:01 2009 -0400
@@ -217,8 +217,8 @@
 		mail_index_lookup_ext(map->view, seq, map->map_ext_id,
 				      &data, &expunged);
 		if (data == NULL) {
-			// FIXME
-			break;
+			dbox_map_set_corrupted(map, "missing map extension");
+			return -1;
 		}
 		rec = data;
 		if (rec->file_id != file_id)
@@ -228,8 +228,8 @@
 		mail_index_lookup_ext(map->view, seq, map->ref_ext_id,
 				      &data, &expunged);
 		if (data == NULL) {
-			// FIXME
-			break;
+			dbox_map_set_corrupted(map, "missing ref extension");
+			return -1;
 		}
 		ref16_p = data;
 		msg.refcount = *ref16_p;
@@ -287,31 +287,31 @@
 	struct seq_range_iter iter;
 	unsigned int i;
 	uint32_t map_uid, seq;
-	int ret = 0;
+	int ret;
 
 	trans = mail_index_transaction_begin(map->view,
 					MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL);
 	seq_range_array_iter_init(&iter, map_uids); i = 0;
 	while (seq_range_array_iter_nth(&iter, i++, &map_uid)) {
 		if ((ret = dbox_map_get_seq(map, map_uid, &seq)) <= 0) {
-			if (ret < 0)
-				break;
-		} else {
-			mail_index_atomic_inc_ext(trans, seq,
-						  map->ref_ext_id, diff);
-		}
-	}
-	if (ret < 0) {
-		mail_index_transaction_rollback(&trans);
-		return -1;
-	} else {
-		if (mail_index_transaction_commit(&trans) < 0) {
-			mail_storage_set_internal_error(&map->storage->storage);
-			mail_index_reset_error(map->index);
+			if (ret == 0) {
+				dbox_map_set_corrupted(map,
+					"refcount update lost map_uid=%u",
+					map_uid);
+			}
+			mail_index_transaction_rollback(&trans);
 			return -1;
 		}
-		return 0;
+
+		mail_index_atomic_inc_ext(trans, seq, map->ref_ext_id, diff);
 	}
+
+	if (mail_index_transaction_commit(&trans) < 0) {
+		mail_storage_set_internal_error(&map->storage->storage);
+		mail_index_reset_error(map->index);
+		return -1;
+	}
+	return 0;
 }
 
 int dbox_map_remove_file_id(struct dbox_map *map, uint32_t file_id)
@@ -334,8 +334,11 @@
 	for (seq = 1; seq <= hdr->messages_count; seq++) {
 		mail_index_lookup_ext(map->view, seq, map->map_ext_id,
 				      &data, &expunged);
-		if (data == NULL)
-			break;
+		if (data == NULL) {
+			dbox_map_set_corrupted(map, "missing map extension");
+			mail_index_transaction_rollback(&trans);
+			return -1;
+		}
 
 		rec = data;
 		if (rec->file_id == file_id)
@@ -383,7 +386,6 @@
 	struct tm tm;
 	time_t stamp;
 
-
 	if (days == 0)
 		return 0;
 
@@ -627,7 +629,9 @@
 		append->size = (uint32_t)-1;
 	}
 	if (!existing) {
+		i_assert(file->first_append_offset == 0);
 		i_assert(file->output != NULL);
+		file->first_append_offset = file->output->offset;
 		array_append(&ctx->files, &file, 1);
 	}
 	*file_r = file;
@@ -714,7 +718,6 @@
 	}
 
 	if (ret < 0) {
-		/* FIXME: we have to rollback the changes we made */
 		mail_index_sync_rollback(&ctx->sync_ctx);
 		return -1;
 	}
@@ -868,6 +871,7 @@
 
 	files = array_get_modifiable(&ctx->files, &count);
 	for (i = 0; i < count; i++) {
+		files[i]->first_append_offset = 0;
 		dbox_file_unlock(files[i]);
 		dbox_file_unref(&files[i]);
 	}
@@ -895,8 +899,14 @@
 			(void)o_stream_flush(file->output);
 		}
 
-		if (file->file_id != 0) {
-			/* FIXME: truncate? */
+		if (file->file_id != 0 &&
+		    file->first_append_offset > file->file_header_size) {
+			if (ftruncate(file->fd, file->first_append_offset) < 0) {
+				mail_storage_set_critical(storage,
+					"ftruncate(%s, %"PRIuUOFF_T") failed: %m",
+					file->current_path,
+					file->first_append_offset);
+			}
 		} else {
 			if (unlink(file->current_path) < 0) {
 				mail_storage_set_critical(storage,
@@ -904,6 +914,8 @@
 					file->current_path);
 			}
 		}
+		file->first_append_offset = 0;
+		dbox_file_unlock(files[i]);
 		dbox_file_unref(&file);
 	}
 	array_free(&ctx->appends);
--- a/src/lib-storage/index/dbox/dbox-sync-file.c	Wed Mar 11 18:42:13 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-sync-file.c	Wed Mar 11 19:10:01 2009 -0400
@@ -188,6 +188,7 @@
 			i_stream_unref(&input);
 			if (ret != (off_t)msg_size) {
 				// FIXME
+				i_error("FIXME");
 				ret = -1;
 				break;
 			}
@@ -213,13 +214,7 @@
 	}
 	array_free(&msgs_arr); msgs = NULL;
 
-	if (ret == 0) {
-		// FIXME: ..?
-		i_error("dbox corrupted");
-		dbox_map_append_rollback(&append_ctx);
-		ret = -1;
-	} else if (ret < 0) {
-		i_error("dbox error");
+	if (ret <= 0) {
 		dbox_map_append_rollback(&append_ctx);
 		ret = -1;
 	} else if (array_count(&copied_map_uids) == 0) {
@@ -230,7 +225,6 @@
 		/* assign new file_id + offset to moved messages */
 		if (dbox_map_append_move(append_ctx, &copied_map_uids,
 					 &expunged_map_uids) < 0) {
-			// FIXME
 			dbox_map_append_rollback(&append_ctx);
 			ret = -1;
 		} else {