From 2f705f3d22a6251791c2bc4e5bd72e76f6c336be Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Fri, 22 Feb 2013 10:01:06 +0200 Subject: [PATCH] mdbox: If m.X file has no mails, don't try to fix it infinitely in storage rebuild. --- src/lib-storage/index/dbox-common/dbox-file-fix.c | 14 ++++++++++++-- src/lib-storage/index/dbox-common/dbox-file.h | 3 ++- .../index/dbox-multi/mdbox-storage-rebuild.c | 6 ++++-- .../index/dbox-single/sdbox-sync-rebuild.c | 2 +- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/lib-storage/index/dbox-common/dbox-file-fix.c b/src/lib-storage/index/dbox-common/dbox-file-fix.c index 4a04150063..84c4a9e2c4 100644 --- a/src/lib-storage/index/dbox-common/dbox-file-fix.c +++ b/src/lib-storage/index/dbox-common/dbox-file-fix.c @@ -291,7 +291,7 @@ int dbox_file_fix(struct dbox_file *file, uoff_t start_offset) { 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 @@ int dbox_file_fix(struct dbox_file *file, uoff_t start_offset) 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 @@ int dbox_file_fix(struct dbox_file *file, uoff_t start_offset) 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 @@ int dbox_file_fix(struct dbox_file *file, uoff_t start_offset) file->cur_path); return -1; } - return 0; + return 1; } diff --git a/src/lib-storage/index/dbox-common/dbox-file.h b/src/lib-storage/index/dbox-common/dbox-file.h index bb7b81d0af..4787a84e0f 100644 --- a/src/lib-storage/index/dbox-common/dbox-file.h +++ b/src/lib-storage/index/dbox-common/dbox-file.h @@ -190,7 +190,8 @@ uoff_t dbox_file_get_plaintext_size(struct dbox_file *file); /* 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. */ diff --git a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c index cc665f9e17..b7c733f8a3 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c +++ b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c @@ -152,9 +152,11 @@ static int rebuild_file_mails(struct mdbox_storage_rebuild_context *ctx, /* 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) { diff --git a/src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c b/src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c index baaef38cf8..d66115197c 100644 --- a/src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c +++ b/src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c @@ -39,7 +39,7 @@ sdbox_sync_add_file_index(struct dbox_sync_rebuild_context *ctx, 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); } -- 2.47.3