dovecot-1.2: Added maildir_very_dirty_syncs setting.

dovecot at dovecot.org dovecot at dovecot.org
Tue Mar 31 03:27:20 EEST 2009


details:   http://hg.dovecot.org/dovecot-1.2/rev/88aeadb32151
changeset: 8876:88aeadb32151
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Mar 30 20:27:14 2009 -0400
description:
Added maildir_very_dirty_syncs setting.

diffstat:

13 files changed, 150 insertions(+), 26 deletions(-)
src/lib-storage/index/maildir/maildir-keywords.c   |   18 ++++
src/lib-storage/index/maildir/maildir-keywords.h   |    4 +
src/lib-storage/index/maildir/maildir-storage.c    |    3 
src/lib-storage/index/maildir/maildir-storage.h    |    2 
src/lib-storage/index/maildir/maildir-sync-index.c |   11 ++
src/lib-storage/index/maildir/maildir-sync.c       |   51 +++++++++++--
src/lib-storage/index/maildir/maildir-uidlist.c    |    5 +
src/lib-storage/index/maildir/maildir-uidlist.h    |    1 
src/lib-storage/index/maildir/maildir-util.c       |   76 +++++++++++++++-----
src/master/mail-process.c                          |    2 
src/master/master-settings-defs.c                  |    1 
src/master/master-settings.c                       |    1 
src/master/master-settings.h                       |    1 

diffs (truncated from 419 to 300 lines):

diff -r 629004d13ec4 -r 88aeadb32151 src/lib-storage/index/maildir/maildir-keywords.c
--- a/src/lib-storage/index/maildir/maildir-keywords.c	Mon Mar 30 20:27:02 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-keywords.c	Mon Mar 30 20:27:14 2009 -0400
@@ -47,6 +47,7 @@ struct maildir_keywords_sync_ctx {
 	const ARRAY_TYPE(keywords) *keywords;
 	ARRAY_DEFINE(idx_to_chr, char);
 	unsigned int chridx_to_idx[MAILDIR_MAX_KEYWORDS];
+	bool readonly;
 };
 
 struct maildir_keywords *maildir_keywords_init(struct maildir_mailbox *mbox)
@@ -404,6 +405,17 @@ maildir_keywords_sync_init(struct maildi
 	return ctx;
 }
 
+struct maildir_keywords_sync_ctx *
+maildir_keywords_sync_init_readonly(struct maildir_keywords *mk,
+				    struct mail_index *index)
+{
+	struct maildir_keywords_sync_ctx *ctx;
+
+	ctx = maildir_keywords_sync_init(mk, index);
+	ctx->readonly = TRUE;
+	return ctx;
+}
+
 void maildir_keywords_sync_deinit(struct maildir_keywords_sync_ctx **_ctx)
 {
 	struct maildir_keywords_sync_ctx *ctx = *_ctx;
@@ -455,13 +467,17 @@ char maildir_keywords_idx_char(struct ma
 	const char *const *name_p;
 	char *chr_p;
 	unsigned int chridx;
+	int ret;
 
 	chr_p = array_idx_modifiable(&ctx->idx_to_chr, idx);
 	if (*chr_p != '\0')
 		return *chr_p;
 
 	name_p = array_idx(ctx->keywords, idx);
-	if (maildir_keywords_lookup_or_create(ctx->mk, *name_p, &chridx) <= 0)
+	ret = !ctx->readonly ?
+		maildir_keywords_lookup_or_create(ctx->mk, *name_p, &chridx) :
+		maildir_keywords_lookup(ctx->mk, *name_p, &chridx);
+	if (ret <= 0)
 		return '\0';
 
 	*chr_p = chridx + MAILDIR_KEYWORD_FIRST;
diff -r 629004d13ec4 -r 88aeadb32151 src/lib-storage/index/maildir/maildir-keywords.h
--- a/src/lib-storage/index/maildir/maildir-keywords.h	Mon Mar 30 20:27:02 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-keywords.h	Mon Mar 30 20:27:14 2009 -0400
@@ -19,6 +19,10 @@ struct maildir_keywords_sync_ctx *
 struct maildir_keywords_sync_ctx *
 maildir_keywords_sync_init(struct maildir_keywords *mk,
 			   struct mail_index *index);
+/* Don't try to add any nonexisting keywords */
+struct maildir_keywords_sync_ctx *
+maildir_keywords_sync_init_readonly(struct maildir_keywords *mk,
+				    struct mail_index *index);
 void maildir_keywords_sync_deinit(struct maildir_keywords_sync_ctx **ctx);
 
 /* Returns keyword index. */
diff -r 629004d13ec4 -r 88aeadb32151 src/lib-storage/index/maildir/maildir-storage.c
--- a/src/lib-storage/index/maildir/maildir-storage.c	Mon Mar 30 20:27:02 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-storage.c	Mon Mar 30 20:27:14 2009 -0400
@@ -442,6 +442,7 @@ maildir_open(struct maildir_storage *sto
 	index = index_storage_alloc(&storage->storage, name, flags,
 				    MAILDIR_INDEX_PREFIX);
 	mbox->ibox.index = index;
+	mbox->very_dirty_syncs = getenv("MAILDIR_VERY_DIRTY_SYNCS") != NULL;
 
 	/* for shared mailboxes get the create mode from the
 	   permissions of dovecot-shared file. */
@@ -869,6 +870,8 @@ static int maildir_storage_mailbox_close
 		timeout_remove(&mbox->keep_lock_to);
 	}
 
+	if (mbox->flags_view != NULL)
+		mail_index_view_close(&mbox->flags_view);
 	if (mbox->keywords != NULL)
 		maildir_keywords_deinit(&mbox->keywords);
 	maildir_uidlist_deinit(&mbox->uidlist);
diff -r 629004d13ec4 -r 88aeadb32151 src/lib-storage/index/maildir/maildir-storage.h
--- a/src/lib-storage/index/maildir/maildir-storage.h	Mon Mar 30 20:27:02 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-storage.h	Mon Mar 30 20:27:14 2009 -0400
@@ -82,6 +82,7 @@ struct maildir_mailbox {
 struct maildir_mailbox {
 	struct index_mailbox ibox;
 	struct maildir_storage *storage;
+	struct mail_index_view *flags_view;
 
 	const char *path;
 	struct timeout *keep_lock_to;
@@ -94,6 +95,7 @@ struct maildir_mailbox {
 	uint32_t maildir_ext_id;
 
 	unsigned int syncing_commit:1;
+	unsigned int very_dirty_syncs:1;
 };
 
 struct maildir_transaction_context {
diff -r 629004d13ec4 -r 88aeadb32151 src/lib-storage/index/maildir/maildir-sync-index.c
--- a/src/lib-storage/index/maildir/maildir-sync-index.c	Mon Mar 30 20:27:02 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-sync-index.c	Mon Mar 30 20:27:14 2009 -0400
@@ -387,6 +387,8 @@ int maildir_sync_index(struct maildir_in
 	uint32_t first_uid;
 	unsigned int changes = 0;
 	int ret = 0;
+	time_t time_before_sync;
+	struct stat st;
 	bool expunged, full_rescan = FALSE;
 
 	i_assert(!mbox->syncing_commit);
@@ -412,6 +414,7 @@ int maildir_sync_index(struct maildir_in
 	}
 	hdr_next_uid = hdr->next_uid;
 
+	time_before_sync = time(NULL);
 	mbox->syncing_commit = TRUE;
 	seq = prev_uid = 0; first_recent_uid = I_MAX(hdr->first_recent_uid, 1);
 	t_array_init(&ctx->keywords, MAILDIR_MAX_KEYWORDS);
@@ -560,8 +563,12 @@ int maildir_sync_index(struct maildir_in
 	if (mbox->ibox.box.v.sync_notify != NULL)
 		mbox->ibox.box.v.sync_notify(&mbox->ibox.box, 0, 0);
 
-	if (ctx->changed)
-		mbox->maildir_hdr.cur_mtime = time(NULL);
+	if (stat(t_strconcat(mbox->path, "/cur", NULL), &st) == 0) {
+		mbox->maildir_hdr.new_check_time =
+			I_MAX(st.st_mtime, time_before_sync);
+		mbox->maildir_hdr.cur_mtime = st.st_mtime;
+		mbox->maildir_hdr.cur_mtime_nsecs = ST_MTIME_NSEC(st);
+	}
 
 	if (uid_validity == 0) {
 		uid_validity = hdr->uid_validity != 0 ? hdr->uid_validity :
diff -r 629004d13ec4 -r 88aeadb32151 src/lib-storage/index/maildir/maildir-sync.c
--- a/src/lib-storage/index/maildir/maildir-sync.c	Mon Mar 30 20:27:02 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-sync.c	Mon Mar 30 20:27:14 2009 -0400
@@ -500,10 +500,23 @@ static int maildir_scan_dir(struct maild
 	}
 
 	if (dir_changed) {
-		if (new_dir)
-			ctx->mbox->maildir_hdr.new_mtime = now;
-		else
-			ctx->mbox->maildir_hdr.cur_mtime = now;
+		/* save the exact new times. the new mtimes should be >=
+		   "now", but just in case something weird happens and mtime
+		   doesn't update, use "now". */
+		if (stat(ctx->new_dir, &st) == 0) {
+			ctx->mbox->maildir_hdr.new_check_time =
+				I_MAX(st.st_mtime, now);
+			ctx->mbox->maildir_hdr.new_mtime = st.st_mtime;
+			ctx->mbox->maildir_hdr.new_mtime_nsecs =
+				ST_MTIME_NSEC(st);
+		}
+		if (stat(ctx->cur_dir, &st) == 0) {
+			ctx->mbox->maildir_hdr.new_check_time =
+				I_MAX(st.st_mtime, now);
+			ctx->mbox->maildir_hdr.cur_mtime = st.st_mtime;
+			ctx->mbox->maildir_hdr.cur_mtime_nsecs =
+				ST_MTIME_NSEC(st);
+		}
 	}
 
 	return ret < 0 ? -1 :
@@ -564,7 +577,7 @@ static int maildir_sync_quick_check(stru
 
 	/* try to avoid stat()ing by first checking delayed changes */
 	if (DIR_DELAYED_REFRESH(hdr, new) ||
-	    DIR_DELAYED_REFRESH(hdr, cur)) {
+	    (DIR_DELAYED_REFRESH(hdr, cur) && !mbox->very_dirty_syncs)) {
 		/* refresh index and try again */
 		if (maildir_sync_header_refresh(mbox) < 0)
 			return -1;
@@ -572,7 +585,7 @@ static int maildir_sync_quick_check(stru
 
 		if (DIR_DELAYED_REFRESH(hdr, new))
 			*new_changed_r = TRUE;
-		if (DIR_DELAYED_REFRESH(hdr, cur))
+		if (DIR_DELAYED_REFRESH(hdr, cur) && !mbox->very_dirty_syncs)
 			*cur_changed_r = TRUE;
 		if (*new_changed_r && *cur_changed_r)
 			return 0;
@@ -901,6 +914,32 @@ maildir_storage_sync_init(struct mailbox
 		}
 	}
 
+	if (mbox->very_dirty_syncs) {
+		struct mail_index_view_sync_ctx *sync_ctx;
+		bool b;
+
+		if (mbox->flags_view == NULL) {
+			mbox->flags_view =
+				mail_index_view_open(mbox->ibox.index);
+		}
+		sync_ctx = mail_index_view_sync_begin(mbox->flags_view,
+				MAIL_INDEX_VIEW_SYNC_FLAG_FIX_INCONSISTENT);
+		if (mail_index_view_sync_commit(&sync_ctx, &b) < 0) {
+			mail_storage_set_index_error(&mbox->ibox);
+			ret = -1;
+		}
+		/* make sure the map stays in private memory */
+		if (mbox->flags_view->map->refcount > 1) {
+			struct mail_index_map *map;
+
+			map = mail_index_map_clone(mbox->flags_view->map);
+			mail_index_unmap(&mbox->flags_view->map);
+			mbox->flags_view->map = map;
+		}
+		mail_index_record_map_move_to_private(mbox->flags_view->map);
+		mail_index_map_move_to_memory(mbox->flags_view->map);
+		maildir_uidlist_set_all_nonsynced(mbox->uidlist);
+	}
 	return index_mailbox_sync_init(box, flags, ret < 0);
 }
 
diff -r 629004d13ec4 -r 88aeadb32151 src/lib-storage/index/maildir/maildir-uidlist.c
--- a/src/lib-storage/index/maildir/maildir-uidlist.c	Mon Mar 30 20:27:02 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-uidlist.c	Mon Mar 30 20:27:14 2009 -0400
@@ -1338,6 +1338,11 @@ static int maildir_uidlist_sync_lock(str
 	return 1;
 }
 
+void maildir_uidlist_set_all_nonsynced(struct maildir_uidlist *uidlist)
+{
+	maildir_uidlist_mark_all(uidlist, TRUE);
+}
+
 int maildir_uidlist_sync_init(struct maildir_uidlist *uidlist,
 			      enum maildir_uidlist_sync_flags sync_flags,
 			      struct maildir_uidlist_sync_ctx **sync_ctx_r)
diff -r 629004d13ec4 -r 88aeadb32151 src/lib-storage/index/maildir/maildir-uidlist.h
--- a/src/lib-storage/index/maildir/maildir-uidlist.h	Mon Mar 30 20:27:02 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-uidlist.h	Mon Mar 30 20:27:14 2009 -0400
@@ -93,6 +93,7 @@ void maildir_uidlist_set_ext(struct mail
    maildir_uidlist_set_ext() */
 int maildir_uidlist_update(struct maildir_uidlist *uidlist);
 
+void maildir_uidlist_set_all_nonsynced(struct maildir_uidlist *uidlist);
 /* Sync uidlist with what's actually on maildir. Returns same as
    maildir_uidlist_lock(). */
 int maildir_uidlist_sync_init(struct maildir_uidlist *uidlist,
diff -r 629004d13ec4 -r 88aeadb32151 src/lib-storage/index/maildir/maildir-util.c
--- a/src/lib-storage/index/maildir/maildir-util.c	Mon Mar 30 20:27:02 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-util.c	Mon Mar 30 20:27:14 2009 -0400
@@ -1,11 +1,14 @@
 /* Copyright (c) 2004-2009 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "array.h"
 #include "ioloop.h"
 #include "str.h"
 #include "mkdir-parents.h"
 #include "maildir-storage.h"
 #include "maildir-uidlist.h"
+#include "maildir-keywords.h"
+#include "maildir-filename.h"
 #include "maildir-sync.h"
 
 #include <unistd.h>
@@ -16,35 +19,69 @@
 
 #define MAILDIR_RESYNC_RETRY_COUNT 10
 
+static const char *
+maildir_filename_guess(struct maildir_mailbox *mbox, uint32_t uid,
+		       const char *fname, bool *have_flags_r)
+
+{
+	struct mail_index_view *view = mbox->flags_view;
+	struct maildir_keywords_sync_ctx *kw_ctx;
+	enum mail_flags flags;
+	ARRAY_TYPE(keyword_indexes) keywords;
+	uint32_t seq;
+
+	if (view == NULL || !mail_index_lookup_seq(view, uid, &seq)) {
+		*have_flags_r = FALSE;
+		return fname;
+	}
+
+	t_array_init(&keywords, 32);
+	mail_index_lookup_view_flags(view, seq, &flags, &keywords);
+	if (array_count(&keywords) == 0) {
+		*have_flags_r = (flags & MAIL_FLAGS_NONRECENT) != 0;
+		fname = maildir_filename_set_flags(NULL, fname, flags, NULL);
+	} else {
+		*have_flags_r = TRUE;
+		kw_ctx = maildir_keywords_sync_init_readonly(mbox->keywords,
+							     mbox->ibox.index);
+		fname = maildir_filename_set_flags(kw_ctx, fname,
+						   flags, &keywords);
+		maildir_keywords_sync_deinit(&kw_ctx);
+	}
+	return fname;
+}
+
 static int maildir_file_do_try(struct maildir_mailbox *mbox, uint32_t uid,
 			       maildir_file_do_func *callback, void *context)


More information about the dovecot-cvs mailing list