dovecot: maildir_storage_sync_force(): Don't wait on trying to l...

dovecot at dovecot.org dovecot at dovecot.org
Sat Dec 1 09:23:28 EET 2007


details:   http://hg.dovecot.org/dovecot/rev/724c8f12eed2
changeset: 6880:724c8f12eed2
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Dec 01 09:23:21 2007 +0200
description:
maildir_storage_sync_force(): Don't wait on trying to lock uidlist. Just try
once and if it fails, find the changed filenames and do nothing else.

diffstat:

3 files changed, 37 insertions(+), 15 deletions(-)
src/lib-storage/index/maildir/maildir-sync.c    |   31 ++++++++++++++---------
src/lib-storage/index/maildir/maildir-uidlist.c |   18 +++++++++++--
src/lib-storage/index/maildir/maildir-uidlist.h |    3 +-

diffs (138 lines):

diff -r fed2843b4ab8 -r 724c8f12eed2 src/lib-storage/index/maildir/maildir-sync.c
--- a/src/lib-storage/index/maildir/maildir-sync.c	Sat Dec 01 09:09:47 2007 +0200
+++ b/src/lib-storage/index/maildir/maildir-sync.c	Sat Dec 01 09:23:21 2007 +0200
@@ -208,12 +208,14 @@ struct maildir_sync_context {
 struct maildir_sync_context {
         struct maildir_mailbox *mbox;
 	const char *new_dir, *cur_dir;
-	bool partial;
 
 	time_t last_touch, last_notify;
 
 	struct maildir_uidlist_sync_ctx *uidlist_sync_ctx;
-        struct maildir_index_sync_context *index_sync_ctx;
+	struct maildir_index_sync_context *index_sync_ctx;
+
+	unsigned int partial:1;
+	unsigned int locked:1;
 };
 
 void maildir_sync_notify(struct maildir_sync_context *ctx)
@@ -425,7 +427,7 @@ static int maildir_scan_dir(struct maild
 	dest = t_str_new(1024);
 
 	move_new = new_dir && !mailbox_is_readonly(&ctx->mbox->ibox.box) &&
-		!ctx->mbox->ibox.keep_recent;
+		!ctx->mbox->ibox.keep_recent && ctx->locked;
 
 	errno = 0;
 	for (; (dp = readdir(dirp)) != NULL; errno = 0) {
@@ -754,18 +756,25 @@ static int maildir_sync_context(struct m
 	   problem rarely happens except under high amount of modifications.
 	*/
 
-	ctx->partial = !cur_changed;
-	sync_flags = ctx->partial ? MAILDIR_UIDLIST_SYNC_PARTIAL : 0;
+	if (!cur_changed || forced) {
+		ctx->partial = TRUE;
+		sync_flags = MAILDIR_UIDLIST_SYNC_PARTIAL;
+		if (forced)
+			sync_flags |= MAILDIR_UIDLIST_SYNC_FORCE;
+	} else {
+		ctx->partial = FALSE;
+		sync_flags = 0;
+	}
 	ret = maildir_uidlist_sync_init(ctx->mbox->uidlist, sync_flags,
 					&ctx->uidlist_sync_ctx);
 	if (ret <= 0) {
-		/* failure / timeout. if forced is TRUE, we could still go
-		   forward and check only for renamed files, but is it worth
-		   the trouble? .. */
+		/* failure / timeout */
+		i_assert(ret < 0 || !forced);
 		return ret;
 	}
-
-	if (!ctx->mbox->syncing_commit) {
+	ctx->locked = maildir_uidlist_is_locked(ctx->mbox->uidlist);
+
+	if (!ctx->mbox->syncing_commit && ctx->locked) {
 		if (maildir_sync_index_begin(ctx->mbox, ctx,
 					     &ctx->index_sync_ctx) < 0)
 			return -1;
@@ -797,7 +806,7 @@ static int maildir_sync_context(struct m
 		maildir_uidlist_sync_finish(ctx->uidlist_sync_ctx);
 	}
 
-	if (!ctx->mbox->syncing_commit) {
+	if (!ctx->mbox->syncing_commit && ctx->locked) {
 		/* NOTE: index syncing here might cause a re-sync due to
 		   files getting lost, so this function might be called
 		   re-entrantly. */
diff -r fed2843b4ab8 -r 724c8f12eed2 src/lib-storage/index/maildir/maildir-uidlist.c
--- a/src/lib-storage/index/maildir/maildir-uidlist.c	Sat Dec 01 09:09:47 2007 +0200
+++ b/src/lib-storage/index/maildir/maildir-uidlist.c	Sat Dec 01 09:23:21 2007 +0200
@@ -108,6 +108,7 @@ struct maildir_uidlist_sync_ctx {
 	unsigned int finished:1;
 	unsigned int changed:1;
 	unsigned int failed:1;
+	unsigned int locked:1;
 };
 
 struct maildir_uidlist_iter_ctx {
@@ -1067,13 +1068,19 @@ int maildir_uidlist_sync_init(struct mai
 	struct maildir_uidlist_sync_ctx *ctx;
 	int ret;
 
-	if ((ret = maildir_uidlist_lock(uidlist)) <= 0)
-		return ret;
+	if ((sync_flags & MAILDIR_UIDLIST_SYNC_FORCE) == 0) {
+		if ((ret = maildir_uidlist_lock(uidlist)) <= 0)
+			return ret;
+	} else {
+		if ((ret = maildir_uidlist_try_lock(uidlist)) < 0)
+			return -1;
+	}
 
 	*sync_ctx_r = ctx = i_new(struct maildir_uidlist_sync_ctx, 1);
 	ctx->uidlist = uidlist;
 	ctx->sync_flags = sync_flags;
 	ctx->partial = (sync_flags & MAILDIR_UIDLIST_SYNC_PARTIAL) != 0;
+	ctx->locked = ret > 0;
 	ctx->first_unwritten_pos = (unsigned int)-1;
 	ctx->first_nouid_pos = (unsigned int)-1;
 
@@ -1109,6 +1116,10 @@ maildir_uidlist_sync_next_partial(struct
 
 	if (rec == NULL) {
 		/* doesn't exist in uidlist */
+		if (!ctx->locked) {
+			/* we can't add it, so just ignore it */
+			return;
+		}
 		if (ctx->first_nouid_pos == (unsigned int)-1)
 			ctx->first_nouid_pos = array_count(&uidlist->records);
 		ctx->new_files_count++;
@@ -1371,7 +1382,8 @@ int maildir_uidlist_sync_deinit(struct m
 		t_pop();
 	}
 
-	maildir_uidlist_unlock(ctx->uidlist);
+	if (ctx->locked)
+		maildir_uidlist_unlock(ctx->uidlist);
 
 	if (ctx->files != NULL)
 		hash_destroy(&ctx->files);
diff -r fed2843b4ab8 -r 724c8f12eed2 src/lib-storage/index/maildir/maildir-uidlist.h
--- a/src/lib-storage/index/maildir/maildir-uidlist.h	Sat Dec 01 09:09:47 2007 +0200
+++ b/src/lib-storage/index/maildir/maildir-uidlist.h	Sat Dec 01 09:23:21 2007 +0200
@@ -9,7 +9,8 @@ struct maildir_uidlist_sync_ctx;
 
 enum maildir_uidlist_sync_flags {
 	MAILDIR_UIDLIST_SYNC_PARTIAL	= 0x01,
-	MAILDIR_UIDLIST_SYNC_KEEP_STATE	= 0x02
+	MAILDIR_UIDLIST_SYNC_KEEP_STATE	= 0x02,
+	MAILDIR_UIDLIST_SYNC_FORCE	= 0x04
 };
 
 enum maildir_uidlist_rec_flag {


More information about the dovecot-cvs mailing list