changeset 14914:b91e1b94af21

mdbox: If m.X file has no mails, don't try to fix it infinitely in storage rebuild.
author Timo Sirainen <tss@iki.fi>
date Fri, 22 Feb 2013 10:01:06 +0200
parents 9cb64709dd8c
children b0e68c53771e
files src/lib-storage/index/dbox-common/dbox-file-fix.c src/lib-storage/index/dbox-common/dbox-file.h src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c
diffstat 4 files changed, 19 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/dbox-common/dbox-file-fix.c	Fri Feb 22 09:43:59 2013 +0200
+++ b/src/lib-storage/index/dbox-common/dbox-file-fix.c	Fri Feb 22 10:01:06 2013 +0200
@@ -291,7 +291,7 @@
 {
 	struct ostream *output;
 	const char *dir, *p, *temp_path, *broken_path;
-	bool deleted;
+	bool deleted, have_messages;
 	int fd, ret;
 
 	i_assert(dbox_file_is_open(file));
@@ -307,6 +307,7 @@
 
 	output = o_stream_create_fd_file(fd, 0, FALSE);
 	ret = dbox_file_fix_write_stream(file, start_offset, temp_path, output);
+	have_messages = output->offset > file->file_header_size;
 	o_stream_unref(&output);
 	if (close(fd) < 0) {
 		mail_storage_set_critical(&file->storage->storage,
@@ -332,6 +333,15 @@
 		i_warning("dbox: Copy of the broken file saved to %s",
 			  broken_path);
 	}
+	if (!have_messages) {
+		/* the resulting file has no messages. just delete the file. */
+		dbox_file_close(file);
+		if (unlink(temp_path) < 0)
+			i_error("unlink(%s) failed: %m", temp_path);
+		if (unlink(file->cur_path) < 0)
+			i_error("unlink(%s) failed: %m", file->cur_path);
+		return 0;
+	}
 	if (rename(temp_path, file->cur_path) < 0) {
 		mail_storage_set_critical(&file->storage->storage,
 					  "rename(%s, %s) failed: %m",
@@ -347,5 +357,5 @@
 			file->cur_path);
 		return -1;
 	}
-	return 0;
+	return 1;
 }
--- a/src/lib-storage/index/dbox-common/dbox-file.h	Fri Feb 22 09:43:59 2013 +0200
+++ b/src/lib-storage/index/dbox-common/dbox-file.h	Fri Feb 22 10:01:06 2013 +0200
@@ -190,7 +190,8 @@
 
 /* Fix a broken dbox file by rename()ing over it with a fixed file. Everything
    before start_offset is assumed to be valid and is simply copied. The file
-   is reopened afterwards. Returns 0 if ok, -1 if I/O error. */
+   is reopened afterwards. Returns 1 if ok, 0 if the resulting file has no
+   mails and was deleted, -1 if I/O error. */
 int dbox_file_fix(struct dbox_file *file, uoff_t start_offset);
 /* Delete the given dbox file. Returns 1 if deleted, 0 if file wasn't found
    or -1 if error. */
--- a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c	Fri Feb 22 09:43:59 2013 +0200
+++ b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c	Fri Feb 22 10:01:06 2013 +0200
@@ -152,9 +152,11 @@
 				/* use existing file header if it was ok */
 				prev_offset = offset;
 			}
-			if (dbox_file_fix(file, prev_offset) < 0) {
-				ret = -1;
+			if ((ret = dbox_file_fix(file, prev_offset)) < 0)
 				break;
+			if (ret == 0) {
+				/* file was deleted */
+				return 1;
 			}
 			fixed = TRUE;
 			if (!first) {
--- a/src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c	Fri Feb 22 09:43:59 2013 +0200
+++ b/src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c	Fri Feb 22 10:01:06 2013 +0200
@@ -39,7 +39,7 @@
 		ret = dbox_file_seek(file, 0);
 	}
 	if (ret == 0) {
-		if ((ret = dbox_file_fix(file, 0)) == 0)
+		if ((ret = dbox_file_fix(file, 0)) > 0)
 			ret = dbox_file_seek(file, 0);
 	}