dovecot-2.0: maildir: Code cleanups.

dovecot at dovecot.org dovecot at dovecot.org
Tue Jun 30 05:04:30 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/bb260536bdb5
changeset: 9552:bb260536bdb5
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Jun 29 21:52:42 2009 -0400
description:
maildir: Code cleanups.

diffstat:

1 file changed, 97 insertions(+), 75 deletions(-)
src/lib-storage/index/maildir/maildir-save.c |  172 ++++++++++++++------------

diffs (224 lines):

diff -r 49a1e47cb037 -r bb260536bdb5 src/lib-storage/index/maildir/maildir-save.c
--- a/src/lib-storage/index/maildir/maildir-save.c	Mon Jun 29 12:37:10 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-save.c	Mon Jun 29 21:52:42 2009 -0400
@@ -616,7 +616,7 @@ static int maildir_transaction_fsync_dir
 }
 
 static int
-maildir_transaction_save_commit_pre_sync(struct maildir_save_context *ctx)
+maildir_save_sync_index(struct maildir_save_context *ctx)
 {
 	struct maildir_transaction_context *t =
 		(struct maildir_transaction_context *)ctx->ctx.transaction;
@@ -671,56 +671,31 @@ maildir_transaction_save_commit_pre_sync
 	return 0;
 }
 
-int maildir_transaction_save_commit_pre(struct maildir_save_context *ctx)
+static void
+maildir_save_rollback_index_changes(struct maildir_save_context *ctx)
 {
 	struct maildir_transaction_context *t =
 		(struct maildir_transaction_context *)ctx->ctx.transaction;
+	uint32_t seq;
+
+	for (seq = ctx->seq; seq >= ctx->first_seq; seq--)
+		mail_index_expunge(ctx->trans, seq);
+
+	mail_cache_transaction_rollback(&t->ictx.cache_trans);
+	t->ictx.cache_trans = mail_cache_get_transaction(t->ictx.cache_view,
+							 t->ictx.trans);
+}
+
+static int
+maildir_save_move_files_to_newcur(struct maildir_save_context *ctx,
+				  struct maildir_filename **last_mf_r)
+{
 	struct maildir_filename *mf;
-	uint32_t seq;
-	enum maildir_uidlist_rec_flag flags;
-	enum maildir_uidlist_sync_flags sync_flags;
 	bool newdir, new_changed, cur_changed;
-	int ret;
-
-	i_assert(ctx->ctx.output == NULL);
-	i_assert(ctx->finished);
-
-	sync_flags = MAILDIR_UIDLIST_SYNC_PARTIAL |
-		MAILDIR_UIDLIST_SYNC_NOREFRESH;
-
-	/* if we want to assign UIDs or keywords, we require uidlist lock */
-	if ((t->ictx.flags & MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS) == 0 &&
-	    !ctx->have_keywords) {
-		/* assign the UIDs if we happen to get a lock */
-		sync_flags |= MAILDIR_UIDLIST_SYNC_TRYLOCK;
-	}
-	ret = maildir_uidlist_sync_init(ctx->mbox->uidlist, sync_flags,
-					&ctx->uidlist_sync_ctx);
-	if (ret <= 0 &&
-	    (ret < 0 || (sync_flags & MAILDIR_UIDLIST_SYNC_TRYLOCK) == 0)) {
-		maildir_transaction_save_rollback(ctx);
-		return -1;
-	}
-
-	ctx->locked = maildir_uidlist_is_locked(ctx->mbox->uidlist);
-	if (ctx->locked) {
-		if (maildir_transaction_save_commit_pre_sync(ctx) < 0) {
-			maildir_transaction_save_rollback(ctx);
-			return -1;
-		}
-	} else {
-		/* since we couldn't lock uidlist, we'll have to drop the
-		   appends to index. */
-		for (seq = ctx->seq; seq >= ctx->first_seq; seq--)
-			mail_index_expunge(ctx->trans, seq);
-
-		mail_cache_transaction_rollback(&t->ictx.cache_trans);
-		t->ictx.cache_trans =
-			mail_cache_get_transaction(t->ictx.cache_view,
-						   t->ictx.trans);
-	}
-
-	/* move them into new/ and/or cur/ */
+	int ret = 0;
+
+	*last_mf_r = NULL;
+
 	ret = 0;
 	ctx->moving = TRUE;
 	new_changed = cur_changed = FALSE;
@@ -747,33 +722,81 @@ int maildir_transaction_save_commit_pre(
 			}
 		} T_END;
 		if (ret < 0)
-			break;
-	}
-
-	if (ret == 0) {
-		ret = maildir_transaction_fsync_dirs(ctx, new_changed,
-						     cur_changed);
-	}
-	if (ret == 0 && ctx->uidlist_sync_ctx != NULL) {
-		/* everything was moved successfully. update our internal
-		   state. */
-		for (mf = ctx->files; mf != NULL; mf = mf->next) T_BEGIN {
-			const char *dest;
-			newdir = maildir_get_updated_filename(ctx, mf, &dest);
-
-			flags = MAILDIR_UIDLIST_REC_FLAG_RECENT;
-			if (newdir)
-				flags |= MAILDIR_UIDLIST_REC_FLAG_NEW_DIR;
-			ret = maildir_uidlist_sync_next(ctx->uidlist_sync_ctx,
-							dest, flags);
-			i_assert(ret > 0);
-		} T_END;
-	}
-
-	if (ctx->uidlist_sync_ctx != NULL) {
+			return -1;
+		*last_mf_r = mf;
+	}
+
+	return maildir_transaction_fsync_dirs(ctx, new_changed, cur_changed);
+}
+
+static void maildir_save_sync_uidlist(struct maildir_save_context *ctx)
+{
+	struct maildir_filename *mf;
+	enum maildir_uidlist_rec_flag flags;
+	bool newdir;
+	int ret;
+
+	for (mf = ctx->files; mf != NULL; mf = mf->next) T_BEGIN {
+		const char *dest;
+
+		newdir = maildir_get_updated_filename(ctx, mf, &dest);
+		flags = MAILDIR_UIDLIST_REC_FLAG_RECENT;
+		if (newdir)
+			flags |= MAILDIR_UIDLIST_REC_FLAG_NEW_DIR;
+		ret = maildir_uidlist_sync_next(ctx->uidlist_sync_ctx,
+						dest, flags);
+		i_assert(ret > 0);
+	} T_END;
+}
+
+int maildir_transaction_save_commit_pre(struct maildir_save_context *ctx)
+{
+	struct maildir_transaction_context *t =
+		(struct maildir_transaction_context *)ctx->ctx.transaction;
+	struct maildir_filename *last_mf;
+	enum maildir_uidlist_sync_flags sync_flags;
+	int ret;
+
+	i_assert(ctx->ctx.output == NULL);
+	i_assert(ctx->finished);
+
+	sync_flags = MAILDIR_UIDLIST_SYNC_PARTIAL |
+		MAILDIR_UIDLIST_SYNC_NOREFRESH;
+
+	/* if we want to assign UIDs or keywords, we require uidlist lock */
+	if ((t->ictx.flags & MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS) == 0 &&
+	    !ctx->have_keywords) {
+		/* assign the UIDs if we happen to get a lock */
+		sync_flags |= MAILDIR_UIDLIST_SYNC_TRYLOCK;
+	}
+	ret = maildir_uidlist_sync_init(ctx->mbox->uidlist, sync_flags,
+					&ctx->uidlist_sync_ctx);
+	if (ret > 0) {
+		ctx->locked = TRUE;
+		if (maildir_save_sync_index(ctx) < 0) {
+			maildir_transaction_save_rollback(ctx);
+			return -1;
+		}
+	} else if (ret == 0 &&
+		   (sync_flags & MAILDIR_UIDLIST_SYNC_TRYLOCK) != 0) {
+		ctx->locked = FALSE;
+		i_assert(ctx->uidlist_sync_ctx == NULL);
+		/* since we couldn't lock uidlist, we'll have to drop the
+		   appends to index. */
+		maildir_save_rollback_index_changes(ctx);
+	} else {
+		maildir_transaction_save_rollback(ctx);
+		return -1;
+	}
+
+	ret = maildir_save_move_files_to_newcur(ctx, &last_mf);
+	if (ctx->locked) {
 		/* update dovecot-uidlist file. */
+		if (ret == 0)
+			maildir_save_sync_uidlist(ctx);
+
 		if (maildir_uidlist_sync_deinit(&ctx->uidlist_sync_ctx,
-						ret >= 0) < 0)
+						ret == 0) < 0)
 			ret = -1;
 	}
 
@@ -790,8 +813,7 @@ int maildir_transaction_save_commit_pre(
 	if (ctx->locked) {
 		/* It doesn't matter if index syncing fails */
 		ctx->keywords_sync_ctx = NULL;
-		(void)maildir_sync_index_finish(&ctx->sync_ctx,
-						ret < 0, FALSE);
+		(void)maildir_sync_index_finish(&ctx->sync_ctx, ret < 0, FALSE);
 	}
 
 	if (ret < 0) {
@@ -802,7 +824,7 @@ int maildir_transaction_save_commit_pre(
 		/* unlink the files we just moved in an attempt to rollback
 		   the transaction. uidlist is still locked, so at least other
 		   Dovecot instances haven't yet seen the files. */
-		maildir_transaction_unlink_copied_files(ctx, mf);
+		maildir_transaction_unlink_copied_files(ctx, last_mf);
 
 		if (ctx->keywords_sync_ctx != NULL)
 			maildir_keywords_sync_deinit(&ctx->keywords_sync_ctx);
@@ -810,7 +832,7 @@ int maildir_transaction_save_commit_pre(
 		maildir_transaction_save_rollback(ctx);
 		return -1;
 	}
-	return ret;
+	return 0;
 }
 
 void maildir_transaction_save_commit_post(struct maildir_save_context *ctx)


More information about the dovecot-cvs mailing list