dovecot-2.1: mdbox: Check that m.X file doesn't have garbage at ...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Jan 28 23:47:00 EET 2012
details: http://hg.dovecot.org/dovecot-2.1/rev/bde005e302e0
changeset: 14027:bde005e302e0
user: Timo Sirainen <tss at iki.fi>
date: Sat Jan 28 23:46:49 2012 +0200
description:
mdbox: Check that m.X file doesn't have garbage at end of file when saving new data to it.
diffstat:
src/lib-storage/index/dbox-multi/mdbox-map.c | 28 ++++++++++++++-
src/lib-storage/index/dbox-multi/mdbox-save.c | 7 ++-
src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c | 1 -
src/lib-storage/index/dbox-multi/mdbox-sync.c | 8 ++-
src/lib-storage/index/dbox-multi/mdbox-sync.h | 3 +-
5 files changed, 37 insertions(+), 10 deletions(-)
diffs (130 lines):
diff -r ef6f3b7f6038 -r bde005e302e0 src/lib-storage/index/dbox-multi/mdbox-map.c
--- a/src/lib-storage/index/dbox-multi/mdbox-map.c Sat Jan 28 22:39:58 2012 +0200
+++ b/src/lib-storage/index/dbox-multi/mdbox-map.c Sat Jan 28 23:46:49 2012 +0200
@@ -796,10 +796,25 @@
return TRUE;
}
+static bool dbox_file_is_ok_at(struct dbox_file *file, uoff_t offset)
+{
+ bool last;
+ int ret;
+
+ if (dbox_file_seek(file, offset) == 0)
+ return FALSE;
+
+ while ((ret = dbox_file_seek_next(file, &offset, &last)) > 0);
+ if (ret == 0 && !last)
+ return FALSE;
+ return TRUE;
+}
+
static bool
mdbox_map_file_try_append(struct mdbox_map_append_context *ctx,
bool want_altpath,
- uint32_t file_id, time_t stamp, uoff_t mail_size,
+ const struct mdbox_map_mail_index_record *rec,
+ time_t stamp, uoff_t mail_size,
struct dbox_file_append_context **file_append_r,
struct ostream **output_r, bool *retry_later_r)
{
@@ -815,7 +830,7 @@
*output_r = NULL;
*retry_later_r = FALSE;
- file = mdbox_file_init(storage, file_id);
+ file = mdbox_file_init(storage, rec->file_id);
if (!dbox_try_open(file, want_altpath)) {
dbox_file_unref(&file);
return TRUE;
@@ -830,6 +845,13 @@
if (errno != ENOENT)
i_error("stat(%s) failed: %m", file->cur_path);
/* the file was unlinked between opening and locking it. */
+ } else if (st.st_size != rec->offset + rec->size &&
+ /* check if there's any garbage at the end of file.
+ note that there may be valid messages added by another
+ session before we locked it (but after we refreshed
+ map index). */
+ !dbox_file_is_ok_at(file, rec->offset + rec->size)) {
+ /* error message was already logged */
} else {
file_append = dbox_file_append_init(file);
if (dbox_file_get_append_stream(file_append, output_r) <= 0) {
@@ -1037,7 +1059,7 @@
}
mail_index_lookup_uid(map->view, seq, &uid);
- if (!mdbox_map_file_try_append(ctx, want_altpath, rec->file_id,
+ if (!mdbox_map_file_try_append(ctx, want_altpath, rec,
stamp, mail_size, file_append_r,
output_r, &retry_later)) {
/* file is too old. the rest of the files are too. */
diff -r ef6f3b7f6038 -r bde005e302e0 src/lib-storage/index/dbox-multi/mdbox-save.c
--- a/src/lib-storage/index/dbox-multi/mdbox-save.c Sat Jan 28 22:39:58 2012 +0200
+++ b/src/lib-storage/index/dbox-multi/mdbox-save.c Sat Jan 28 23:46:49 2012 +0200
@@ -301,10 +301,13 @@
return -1;
}
- /* lock the mailbox after map to avoid deadlocks. */
+ /* lock the mailbox after map to avoid deadlocks. if we've noticed
+ any corruption, deal with it later, otherwise we won't have
+ up-to-date atomic->sync_view */
if (mdbox_sync_begin(ctx->mbox, MDBOX_SYNC_FLAG_NO_PURGE |
MDBOX_SYNC_FLAG_FORCE |
- MDBOX_SYNC_FLAG_FSYNC, ctx->atomic,
+ MDBOX_SYNC_FLAG_FSYNC |
+ MDBOX_SYNC_FLAG_NO_REBUILD, ctx->atomic,
&ctx->sync_ctx) < 0) {
mdbox_transaction_save_rollback(_ctx);
return -1;
diff -r ef6f3b7f6038 -r bde005e302e0 src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c
--- a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c Sat Jan 28 22:39:58 2012 +0200
+++ b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c Sat Jan 28 23:46:49 2012 +0200
@@ -50,7 +50,6 @@
ARRAY_TYPE(seq_range) seen_file_ids;
uint32_t rebuild_count;
- uint32_t highest_seen_map_uid;
uint32_t highest_file_id;
struct mailbox_list *default_list;
diff -r ef6f3b7f6038 -r bde005e302e0 src/lib-storage/index/dbox-multi/mdbox-sync.c
--- a/src/lib-storage/index/dbox-multi/mdbox-sync.c Sat Jan 28 22:39:58 2012 +0200
+++ b/src/lib-storage/index/dbox-multi/mdbox-sync.c Sat Jan 28 23:46:49 2012 +0200
@@ -229,7 +229,7 @@
headers until syncing has locked the mailbox */
rebuild = mbox->storage->corrupted ||
(flags & MDBOX_SYNC_FLAG_FORCE_REBUILD) != 0;
- if (rebuild) {
+ if (rebuild && (flags & MDBOX_SYNC_FLAG_NO_REBUILD) == 0) {
if (mdbox_storage_rebuild_in_context(mbox->storage, atomic) < 0)
return -1;
index_mailbox_reset_uidvalidity(&mbox->box);
@@ -330,8 +330,10 @@
ret = -1;
}
- if (mail_index_reset_fscked(box->index))
- mdbox_storage_set_corrupted(mbox->storage);
+ if (box->opened) {
+ if (mail_index_reset_fscked(box->index))
+ mdbox_storage_set_corrupted(mbox->storage);
+ }
if (ret == 0 && (index_mailbox_want_full_sync(&mbox->box, flags) ||
mbox->storage->corrupted)) {
if ((flags & MAILBOX_SYNC_FLAG_FORCE_RESYNC) != 0)
diff -r ef6f3b7f6038 -r bde005e302e0 src/lib-storage/index/dbox-multi/mdbox-sync.h
--- a/src/lib-storage/index/dbox-multi/mdbox-sync.h Sat Jan 28 22:39:58 2012 +0200
+++ b/src/lib-storage/index/dbox-multi/mdbox-sync.h Sat Jan 28 23:46:49 2012 +0200
@@ -8,7 +8,8 @@
MDBOX_SYNC_FLAG_FORCE = 0x01,
MDBOX_SYNC_FLAG_FSYNC = 0x02,
MDBOX_SYNC_FLAG_FORCE_REBUILD = 0x04,
- MDBOX_SYNC_FLAG_NO_PURGE = 0x08
+ MDBOX_SYNC_FLAG_NO_PURGE = 0x08,
+ MDBOX_SYNC_FLAG_NO_REBUILD = 0x10
};
struct mdbox_sync_context {
More information about the dovecot-cvs
mailing list