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