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