]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
mdbox: If m.X file has no mails, don't try to fix it infinitely in storage rebuild.
authorTimo Sirainen <tss@iki.fi>
Fri, 22 Feb 2013 08:01:06 +0000 (10:01 +0200)
committerTimo Sirainen <tss@iki.fi>
Fri, 22 Feb 2013 08:01:06 +0000 (10:01 +0200)
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

index 4a04150063ed0ae7a8eb2c92a3a2c860eec9e952..84c4a9e2c4d9716709c55824cf114ddf6bbf3d73 100644 (file)
@@ -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;
 }
index bb7b81d0af105362fce2b6f2a2b5dce826491734..4787a84e0f124c7ccdaf9775f767ef4cf96b4102 100644 (file)
@@ -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. */
index cc665f9e17f2bc9819cb80969ccd5906f8c1f1d2..b7c733f8a3934e8868793c08dd714f7174b257cf 100644 (file)
@@ -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) {
index baaef38cf8130c0f07746449abc89006c902ae98..d66115197c6dbd5c58b6dec268a66328fceb1f55 100644 (file)
@@ -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);
        }