dovecot-2.0: single-dbox: Fixed broken mailbox handling.
dovecot at dovecot.org
dovecot at dovecot.org
Tue Jun 29 22:21:55 EEST 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/9d9be6aa3a55
changeset: 11658:9d9be6aa3a55
user: Timo Sirainen <tss at iki.fi>
date: Tue Jun 29 20:21:51 2010 +0100
description:
single-dbox: Fixed broken mailbox handling.
diffstat:
src/lib-storage/index/dbox-single/sdbox-storage.c | 37 ++++++++++++++----
src/lib-storage/index/dbox-single/sdbox-storage.h | 6 ++-
src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c | 20 +++++++++-
src/lib-storage/index/dbox-single/sdbox-sync.c | 18 +++++----
src/lib-storage/index/dbox-single/sdbox-sync.h | 2 +-
5 files changed, 63 insertions(+), 20 deletions(-)
diffs (233 lines):
diff -r 4e5032891954 -r 9d9be6aa3a55 src/lib-storage/index/dbox-single/sdbox-storage.c
--- a/src/lib-storage/index/dbox-single/sdbox-storage.c Tue Jun 29 19:34:16 2010 +0100
+++ b/src/lib-storage/index/dbox-single/sdbox-storage.c Tue Jun 29 20:21:51 2010 +0100
@@ -84,10 +84,13 @@
int sdbox_read_header(struct sdbox_mailbox *mbox,
struct sdbox_index_header *hdr, bool log_error)
{
+ struct mail_index_view *view;
const void *data;
size_t data_size;
+ int ret;
- mail_index_get_header_ext(mbox->box.view, mbox->hdr_ext_id,
+ view = mail_index_view_open(mbox->box.index);
+ mail_index_get_header_ext(view, mbox->hdr_ext_id,
&data, &data_size);
if (data_size < SDBOX_INDEX_HEADER_MIN_SIZE &&
(!mbox->creating || data_size != 0)) {
@@ -97,11 +100,14 @@
"dbox %s: Invalid dbox header size",
mbox->box.path);
}
- return -1;
+ ret = -1;
+ } else {
+ memset(hdr, 0, sizeof(*hdr));
+ memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr)));
+ ret = 0;
}
- memset(hdr, 0, sizeof(*hdr));
- memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr)));
- return 0;
+ mail_index_view_close(&view);
+ return ret;
}
void sdbox_update_header(struct sdbox_mailbox *mbox,
@@ -198,9 +204,15 @@
return ret;
}
-static void sdbox_set_mailbox_corrupted(struct mailbox *box ATTR_UNUSED)
+static void sdbox_set_mailbox_corrupted(struct mailbox *box)
{
- /* FIXME */
+ struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
+ struct sdbox_index_header hdr;
+
+ if (sdbox_read_header(mbox, &hdr, TRUE) < 0 || hdr.rebuild_count == 0)
+ mbox->corrupted_rebuild_count = 1;
+ else
+ mbox->corrupted_rebuild_count = hdr.rebuild_count;
}
static void sdbox_set_file_corrupted(struct dbox_file *_file)
@@ -210,6 +222,15 @@
sdbox_set_mailbox_corrupted(&file->mbox->box);
}
+static void sdbox_mailbox_close(struct mailbox *box)
+{
+ struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
+
+ if (mbox->corrupted_rebuild_count != 0)
+ (void)sdbox_sync(mbox, 0);
+ index_storage_mailbox_close(box);
+}
+
static int
sdbox_mailbox_get_guid(struct mailbox *box, uint8_t guid[MAIL_GUID_128_SIZE])
{
@@ -264,7 +285,7 @@
index_storage_allow_new_keywords,
index_storage_mailbox_enable,
dbox_mailbox_open,
- index_storage_mailbox_close,
+ sdbox_mailbox_close,
index_storage_mailbox_free,
dbox_mailbox_create,
dbox_mailbox_update,
diff -r 4e5032891954 -r 9d9be6aa3a55 src/lib-storage/index/dbox-single/sdbox-storage.h
--- a/src/lib-storage/index/dbox-single/sdbox-storage.h Tue Jun 29 19:34:16 2010 +0100
+++ b/src/lib-storage/index/dbox-single/sdbox-storage.h Tue Jun 29 20:21:51 2010 +0100
@@ -10,7 +10,8 @@
#define SDBOX_INDEX_HEADER_MIN_SIZE (sizeof(uint32_t))
struct sdbox_index_header {
- uint32_t oldv1_highest_maildir_uid;
+ /* increased every time a full mailbox rebuild is done */
+ uint32_t rebuild_count;
uint8_t mailbox_guid[MAIL_GUID_128_SIZE];
};
@@ -23,6 +24,9 @@
struct sdbox_storage *storage;
uint32_t hdr_ext_id;
+ /* if non-zero, storage should be rebuilt (except if rebuild_count
+ has changed from this value) */
+ uint32_t corrupted_rebuild_count;
unsigned int creating:1;
};
diff -r 4e5032891954 -r 9d9be6aa3a55 src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c
--- a/src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c Tue Jun 29 19:34:16 2010 +0100
+++ b/src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c Tue Jun 29 20:21:51 2010 +0100
@@ -36,12 +36,16 @@
return 0;
ret = dbox_file_get_mail_stream(file, 0, NULL);
}
+ if (ret == 0) {
+ if ((ret = dbox_file_fix(file, 0)) == 0)
+ ret = dbox_file_get_mail_stream(file, 0, NULL);
+ }
if (ret <= 0) {
if (ret < 0)
return -1;
- i_warning("dbox: Ignoring broken file: %s", file->cur_path);
+ i_warning("dbox: Skipping unfixable file: %s", file->cur_path);
return 0;
}
@@ -132,6 +136,8 @@
memset(&hdr, 0, sizeof(hdr));
if (!mail_guid_128_is_empty(hdr.mailbox_guid))
mail_generate_guid_128(hdr.mailbox_guid);
+ if (++hdr.rebuild_count == 0)
+ hdr.rebuild_count = 1;
mail_index_update_header_ext(ctx->trans, mbox->hdr_ext_id, 0,
&hdr, sizeof(hdr));
}
@@ -154,13 +160,22 @@
return ret;
}
-int sdbox_sync_index_rebuild(struct sdbox_mailbox *mbox)
+int sdbox_sync_index_rebuild(struct sdbox_mailbox *mbox, bool force)
{
struct dbox_sync_rebuild_context *ctx;
struct mail_index_view *view;
struct mail_index_transaction *trans;
+ struct sdbox_index_header hdr;
int ret;
+ if (!force && sdbox_read_header(mbox, &hdr, FALSE) == 0) {
+ if (hdr.rebuild_count != mbox->corrupted_rebuild_count &&
+ hdr.rebuild_count != 0) {
+ /* already rebuilt by someone else */
+ return 0;
+ }
+ }
+
view = mail_index_view_open(mbox->box.index);
trans = mail_index_transaction_begin(view,
MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL);
@@ -174,5 +189,6 @@
else
ret = mail_index_transaction_commit(&trans);
mail_index_view_close(&view);
+ mbox->corrupted_rebuild_count = 0;
return ret;
}
diff -r 4e5032891954 -r 9d9be6aa3a55 src/lib-storage/index/dbox-single/sdbox-sync.c
--- a/src/lib-storage/index/dbox-single/sdbox-sync.c Tue Jun 29 19:34:16 2010 +0100
+++ b/src/lib-storage/index/dbox-single/sdbox-sync.c Tue Jun 29 20:21:51 2010 +0100
@@ -104,7 +104,6 @@
const struct mail_index_header *hdr;
struct mail_index_sync_rec sync_rec;
uint32_t seq1, seq2;
- int ret = 1;
hdr = mail_index_get_header(ctx->sync_view);
if (hdr->uid_validity == 0) {
@@ -122,7 +121,7 @@
if (box->v.sync_notify != NULL)
box->v.sync_notify(box, 0, 0);
- return ret;
+ return 1;
}
static int
@@ -151,10 +150,12 @@
enum mail_index_sync_flags sync_flags;
unsigned int i;
int ret;
- bool rebuild;
+ bool rebuild, force_rebuild;
- rebuild = sdbox_refresh_header(mbox, TRUE, FALSE) < 0 ||
- (flags & SDBOX_SYNC_FLAG_FORCE_REBUILD) != 0;
+ force_rebuild = (flags & SDBOX_SYNC_FLAG_FORCE_REBUILD) != 0;
+ rebuild = force_rebuild ||
+ mbox->corrupted_rebuild_count != 0 ||
+ sdbox_refresh_header(mbox, TRUE, FALSE) < 0;
ctx = i_new(struct sdbox_sync_context, 1);
ctx->mbox = mbox;
@@ -181,8 +182,7 @@
return ret;
}
- /* now that we're locked, check again if we want to rebuild. */
- if (sdbox_refresh_header(mbox, FALSE, TRUE) < 0)
+ if (rebuild)
ret = 0;
else {
if ((ret = sdbox_sync_index(ctx)) > 0)
@@ -201,7 +201,9 @@
/* do a full resync and try again. */
i_warning("dbox %s: Rebuilding index",
ctx->mbox->box.path);
- ret = sdbox_sync_index_rebuild(mbox);
+ rebuild = FALSE;
+ ret = sdbox_sync_index_rebuild(mbox,
+ force_rebuild);
}
}
mail_index_sync_rollback(&ctx->index_sync_ctx);
diff -r 4e5032891954 -r 9d9be6aa3a55 src/lib-storage/index/dbox-single/sdbox-sync.h
--- a/src/lib-storage/index/dbox-single/sdbox-sync.h Tue Jun 29 19:34:16 2010 +0100
+++ b/src/lib-storage/index/dbox-single/sdbox-sync.h Tue Jun 29 20:21:51 2010 +0100
@@ -29,7 +29,7 @@
int sdbox_sync_finish(struct sdbox_sync_context **ctx, bool success);
int sdbox_sync(struct sdbox_mailbox *mbox, enum sdbox_sync_flags flags);
-int sdbox_sync_index_rebuild(struct sdbox_mailbox *mbox);
+int sdbox_sync_index_rebuild(struct sdbox_mailbox *mbox, bool force);
struct mailbox_sync_context *
sdbox_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags);
More information about the dovecot-cvs
mailing list