dovecot-2.1: maildir: When logging "scanning took n secs" warnin...

dovecot at dovecot.org dovecot at dovecot.org
Mon Sep 5 11:48:20 EEST 2011


details:   http://hg.dovecot.org/dovecot-2.1/rev/ae7a7282af83
changeset: 13400:ae7a7282af83
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Sep 05 11:48:11 2011 +0300
description:
maildir: When logging "scanning took n secs" warning, log also why scan was done.
This could help debugging why cur/ directory is sometimes scanned with
maildir_very_dirty_syncs=yes (if the previous commit didn't fully solve it).

diffstat:

 src/lib-storage/index/maildir/maildir-sync.c |  74 ++++++++++++++++++++-------
 1 files changed, 54 insertions(+), 20 deletions(-)

diffs (193 lines):

diff -r ed8ed96cc828 -r ae7a7282af83 src/lib-storage/index/maildir/maildir-sync.c
--- a/src/lib-storage/index/maildir/maildir-sync.c	Mon Sep 05 11:45:45 2011 +0300
+++ b/src/lib-storage/index/maildir/maildir-sync.c	Mon Sep 05 11:48:11 2011 +0300
@@ -206,6 +206,17 @@
 
 #define DUPE_LINKS_DELETE_SECS 30
 
+enum maildir_scan_why {
+	WHY_FORCED	= 0x01,
+	WHY_FIRSTSYNC	= 0x02,
+	WHY_NEWCHANGED	= 0x04,
+	WHY_CURCHANGED	= 0x08,
+	WHY_DROPRECENT	= 0x10,
+	WHY_FINDRECENT	= 0x20,
+	WHY_DELAYEDNEW	= 0x40,
+	WHY_DELAYEDCUR	= 0x80
+};
+
 struct maildir_sync_context {
         struct maildir_mailbox *mbox;
 	const char *new_dir, *cur_dir;
@@ -355,7 +366,8 @@
 }
 
 static int
-maildir_scan_dir(struct maildir_sync_context *ctx, bool new_dir, bool final)
+maildir_scan_dir(struct maildir_sync_context *ctx, bool new_dir, bool final,
+		 enum maildir_scan_why why)
 {
 	struct mail_storage *storage = &ctx->mbox->storage->storage;
 	const char *path;
@@ -531,8 +543,8 @@
 	time_diff = time(NULL) - start_time;
 	if (time_diff >= MAILDIR_SYNC_TIME_WARN_SECS) {
 		i_warning("Maildir: Scanning %s took %u seconds "
-			  "(%u readdir()s, %u rename()s to cur/)",
-			  path, time_diff, readdir_count, move_count);
+			  "(%u readdir()s, %u rename()s to cur/, why=0x%x)",
+			  path, time_diff, readdir_count, move_count, why);
 	}
 
 	return ret < 0 ? -1 :
@@ -566,7 +578,8 @@
 
 static int maildir_sync_quick_check(struct maildir_mailbox *mbox, bool undirty,
 				    const char *new_dir, const char *cur_dir,
-				    bool *new_changed_r, bool *cur_changed_r)
+				    bool *new_changed_r, bool *cur_changed_r,
+				    enum maildir_scan_why *why_r)
 {
 #define DIR_DELAYED_REFRESH(hdr, name) \
 	((hdr)->name ## _check_time <= \
@@ -586,6 +599,7 @@
 		maildir_sync_get_header(mbox);
 		if (mbox->maildir_hdr.new_mtime == 0) {
 			/* first sync */
+			*why_r |= WHY_FIRSTSYNC;
 			*new_changed_r = *cur_changed_r = TRUE;
 			return 0;
 		}
@@ -602,11 +616,15 @@
 			return -1;
 		refreshed = TRUE;
 
-		if (DIR_DELAYED_REFRESH(hdr, new))
+		if (DIR_DELAYED_REFRESH(hdr, new)) {
+			*why_r |= WHY_DELAYEDNEW;
 			*new_changed_r = TRUE;
+		}
 		if (DIR_DELAYED_REFRESH(hdr, cur) &&
-		    !mbox->storage->set->maildir_very_dirty_syncs)
+		    !mbox->storage->set->maildir_very_dirty_syncs) {
+			*why_r |= WHY_DELAYEDCUR;
 			*cur_changed_r = TRUE;
+		}
 		if (*new_changed_r && *cur_changed_r)
 			return 0;
 	}
@@ -623,10 +641,16 @@
 	}
 
 	for (;;) {
-		if (check_new)
+		if (check_new) {
 			*new_changed_r = DIR_MTIME_CHANGED(new_st, hdr, new);
-		if (check_cur)
+			if (*new_changed_r)
+				*why_r |= WHY_NEWCHANGED;
+		}
+		if (check_cur) {
 			*cur_changed_r = DIR_MTIME_CHANGED(cur_st, hdr, cur);
+			if (*cur_changed_r)
+				*why_r |= WHY_CURCHANGED;
+		}
 
 		if ((!*new_changed_r && !*cur_changed_r) || refreshed)
 			break;
@@ -679,27 +703,32 @@
 }
 
 static int maildir_sync_get_changes(struct maildir_sync_context *ctx,
-				    bool *new_changed_r, bool *cur_changed_r)
+				    bool *new_changed_r, bool *cur_changed_r,
+				    enum maildir_scan_why *why_r)
 {
 	struct maildir_mailbox *mbox = ctx->mbox;
 	enum mail_index_sync_flags flags = 0;
 	bool undirty = (ctx->flags & MAILBOX_SYNC_FLAG_FULL_READ) != 0;
 
 	if (maildir_sync_quick_check(mbox, undirty, ctx->new_dir, ctx->cur_dir,
-				     new_changed_r, cur_changed_r) < 0)
+				     new_changed_r, cur_changed_r, why_r) < 0)
 		return -1;
 
 	/* if there are files in new/, we'll need to move them. we'll check
 	   this by seeing if we have any recent messages */
 	if ((mbox->box.flags & MAILBOX_FLAG_DROP_RECENT) != 0) {
-		if (!*new_changed_r)
-			*new_changed_r = have_recent_messages(ctx, FALSE);
+		if (!*new_changed_r && have_recent_messages(ctx, FALSE)) {
+			*new_changed_r = TRUE;
+			*why_r |= WHY_DROPRECENT;
+		}
 	} else if (*new_changed_r) {
 		/* if recent messages have been externally deleted from new/,
 		   we need to get them out of index. this requires that
 		   we make sure they weren't just moved to cur/. */
-		if (!*cur_changed_r)
-			*cur_changed_r = have_recent_messages(ctx, TRUE);
+		if (!*cur_changed_r && have_recent_messages(ctx, TRUE)) {
+			*cur_changed_r = TRUE;
+			*why_r |= WHY_FINDRECENT;
+		}
 	}
 
 	if (*new_changed_r || *cur_changed_r)
@@ -723,14 +752,17 @@
 	enum maildir_uidlist_rec_flag flags;
 	bool new_changed, cur_changed, lock_failure;
 	const char *fname;
+	enum maildir_scan_why why = 0;
 	int ret;
 
 	*lost_files_r = FALSE;
 
-	if (forced)
+	if (forced) {
 		new_changed = cur_changed = TRUE;
-	else {
-		ret = maildir_sync_get_changes(ctx, &new_changed, &cur_changed);
+		why = WHY_FORCED;
+	} else {
+		ret = maildir_sync_get_changes(ctx, &new_changed, &cur_changed,
+					       &why);
 		if (ret <= 0)
 			return ret;
 	}
@@ -840,7 +872,7 @@
 		unsigned int count = 0;
 		bool final = FALSE;
 
-		while ((ret = maildir_scan_dir(ctx, TRUE, final)) > 0) {
+		while ((ret = maildir_scan_dir(ctx, TRUE, final, why)) > 0) {
 			/* rename()d at least some files, which might have
 			   caused some other files to be missed. check again
 			   (see MAILDIR_RENAME_RESCAN_COUNT). */
@@ -851,7 +883,7 @@
 			return -1;
 
 		if (cur_changed) {
-			if (maildir_scan_dir(ctx, FALSE, TRUE) < 0)
+			if (maildir_scan_dir(ctx, FALSE, TRUE, why) < 0)
 				return -1;
 		}
 
@@ -1020,6 +1052,7 @@
 int maildir_sync_is_synced(struct maildir_mailbox *mbox)
 {
 	bool new_changed, cur_changed;
+	enum maildir_scan_why why;
 	int ret;
 
 	T_BEGIN {
@@ -1030,7 +1063,8 @@
 		cur_dir = t_strconcat(box_path, "/cur", NULL);
 
 		ret = maildir_sync_quick_check(mbox, FALSE, new_dir, cur_dir,
-					       &new_changed, &cur_changed);
+					       &new_changed, &cur_changed,
+					       &why);
 	} T_END;
 	return ret < 0 ? -1 : (!new_changed && !cur_changed);
 }


More information about the dovecot-cvs mailing list