dovecot-2.0: maildir: Cleaned up save/copy code.

dovecot at dovecot.org dovecot at dovecot.org
Fri Jul 10 03:14:48 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/489727453d1c
changeset: 9602:489727453d1c
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Jul 09 20:14:42 2009 -0400
description:
maildir: Cleaned up save/copy code.

diffstat:

6 files changed, 178 insertions(+), 204 deletions(-)
src/lib-storage/index/maildir/maildir-copy.c       |   25 -
src/lib-storage/index/maildir/maildir-save.c       |  302 +++++++++-----------
src/lib-storage/index/maildir/maildir-storage.h    |    9 
src/lib-storage/index/maildir/maildir-sync-index.c |   31 +-
src/lib-storage/index/maildir/maildir-sync.c       |   11 
src/lib-storage/index/maildir/maildir-sync.h       |    4 

diffs (truncated from 719 to 300 lines):

diff -r 069679de3005 -r 489727453d1c src/lib-storage/index/maildir/maildir-copy.c
--- a/src/lib-storage/index/maildir/maildir-copy.c	Thu Jul 09 20:13:31 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-copy.c	Thu Jul 09 20:14:42 2009 -0400
@@ -125,17 +125,13 @@ static int do_hardlink(struct maildir_ma
 }
 
 static int
-maildir_copy_hardlink(struct maildir_transaction_context *t, struct mail *mail,
-		      enum mail_flags flags, struct mail_keywords *keywords,
-		      struct mail *dest_mail)
+maildir_copy_hardlink(struct mail_save_context *ctx, struct mail *mail)
 {
 	struct maildir_mailbox *dest_mbox =
-		(struct maildir_mailbox *)t->ictx.ibox;
+		(struct maildir_mailbox *)ctx->transaction->box;
 	struct maildir_mailbox *src_mbox;
 	struct hardlink_ctx do_ctx;
 	const char *path, *filename = NULL;
-
-	i_assert((t->ictx.flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
 
 	if (strcmp(mail->box->storage->name, MAILDIR_STORAGE_NAME) == 0)
 		src_mbox = (struct maildir_mailbox *)mail->box;
@@ -146,14 +142,6 @@ maildir_copy_hardlink(struct maildir_tra
 		/* Can't hard link files from the source storage */
 		return 0;
 	}
-
-	if (t->save_ctx == NULL)
-		t->save_ctx = maildir_save_transaction_init(t);
-
-	/* don't allow caller to specify recent flag */
-	flags &= ~MAIL_RECENT;
-	if (dest_mbox->ibox.keep_recent)
-		flags |= MAIL_RECENT;
 
 	memset(&do_ctx, 0, sizeof(do_ctx));
 	do_ctx.dest_path = str_new(default_pool, 512);
@@ -209,8 +197,7 @@ maildir_copy_hardlink(struct maildir_tra
 	}
 
 	/* hardlinked to tmp/, treat as normal copied mail */
-	maildir_save_add(t->save_ctx, do_ctx.dest_fname, flags, keywords,
-			 dest_mail);
+	maildir_save_add(ctx, do_ctx.dest_fname);
 	return 1;
 }
 
@@ -228,12 +215,12 @@ int maildir_copy(struct mail_save_contex
 	struct maildir_mailbox *mbox = (struct maildir_mailbox *)t->ictx.ibox;
 	int ret;
 
+	i_assert((t->ictx.flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
+
 	if (mbox->storage->set->maildir_copy_with_hardlinks &&
 	    maildir_compatible_file_modes(&mbox->ibox.box, mail->box)) {
 		T_BEGIN {
-			ret = maildir_copy_hardlink(t, mail, ctx->flags,
-						    ctx->keywords,
-						    ctx->dest_mail);
+			ret = maildir_copy_hardlink(ctx, mail);
 		} T_END;
 
 		if (ret != 0) {
diff -r 069679de3005 -r 489727453d1c src/lib-storage/index/maildir/maildir-save.c
--- a/src/lib-storage/index/maildir/maildir-save.c	Thu Jul 09 20:13:31 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-save.c	Thu Jul 09 20:14:42 2009 -0400
@@ -24,6 +24,8 @@
 #include <utime.h>
 #include <sys/stat.h>
 
+#define MAILDIR_FILENAME_FLAG_MOVED 0x10000000
+
 struct maildir_filename {
 	struct maildir_filename *next;
 	const char *basename;
@@ -56,27 +58,24 @@ struct maildir_save_context {
 	int fd;
 	uint32_t first_seq, seq;
 
-	unsigned int want_mails:1;
 	unsigned int have_keywords:1;
 	unsigned int locked:1;
 	unsigned int failed:1;
-	unsigned int moving:1;
-	unsigned int finished:1;
+	unsigned int last_save_finished:1;
 };
 
 static int maildir_file_move(struct maildir_save_context *ctx,
-			     const char *tmpname, const char *destname,
+			     struct maildir_filename *mf, const char *destname,
 			     bool newdir)
 {
 	struct mail_storage *storage = &ctx->mbox->storage->storage;
 	const char *tmp_path, *new_path;
-	int ret;
 
 	/* if we have flags, we'll move it to cur/ directly, because files in
 	   new/ directory can't have flags. alternative would be to write it
 	   in new/ and set the flags dirty in index file, but in that case
 	   external MUAs would see wrong flags. */
-	tmp_path = t_strconcat(ctx->tmpdir, "/", tmpname, NULL);
+	tmp_path = t_strconcat(ctx->tmpdir, "/", mf->basename, NULL);
 	new_path = newdir ?
 		t_strconcat(ctx->newdir, "/", destname, NULL) :
 		t_strconcat(ctx->curdir, "/", destname, NULL);
@@ -91,20 +90,18 @@ static int maildir_file_move(struct mail
 	   almost required with OSX's HFS+ filesystem, since it implements
 	   hard links in a pretty ugly way, which makes the performance crawl
 	   when a lot of hard links are used. */
-	if (rename(tmp_path, new_path) == 0)
-		ret = 0;
-	else {
-		ret = -1;
-		if (ENOSPACE(errno)) {
-			mail_storage_set_error(storage,
-				MAIL_ERROR_NOSPACE, MAIL_ERRSTR_NO_SPACE);
-		} else {
-			mail_storage_set_critical(storage,
-				"rename(%s, %s) failed: %m",
-				tmp_path, new_path);
-		}
-	}
-	return ret;
+	if (rename(tmp_path, new_path) == 0) {
+		mf->flags |= MAILDIR_FILENAME_FLAG_MOVED;
+		return 0;
+	} else if (ENOSPACE(errno)) {
+		mail_storage_set_error(storage, MAIL_ERROR_NOSPACE,
+				       MAIL_ERRSTR_NO_SPACE);
+		return -1;
+	} else {
+		mail_storage_set_critical(storage, "rename(%s, %s) failed: %m",
+					  tmp_path, new_path);
+		return -1;
+	}
 }
 
 struct maildir_save_context *
@@ -130,27 +127,32 @@ maildir_save_transaction_init(struct mai
 	ctx->keywords_buffer = buffer_create_const_data(pool, NULL, 0);
 	array_create_from_buffer(&ctx->keywords_array, ctx->keywords_buffer,
 				 sizeof(unsigned int));
-	ctx->finished = TRUE;
+	ctx->last_save_finished = TRUE;
 	return ctx;
 }
 
-uint32_t maildir_save_add(struct maildir_save_context *ctx,
-			  const char *base_fname, enum mail_flags flags,
-			  struct mail_keywords *keywords,
-			  struct mail *dest_mail)
-{
+uint32_t maildir_save_add(struct mail_save_context *_ctx,
+			  const char *base_fname)
+{
+	struct maildir_save_context *ctx = (struct maildir_save_context *)_ctx;
 	struct maildir_filename *mf;
 	struct istream *input;
+	unsigned int keyword_count;
+
+	/* don't allow caller to specify recent flag */
+	_ctx->flags &= ~MAIL_RECENT;
+	if (ctx->mbox->ibox.keep_recent)
+		_ctx->flags |= MAIL_RECENT;
 
 	/* now, we want to be able to rollback the whole append session,
 	   so we'll just store the name of this temp file and move it later
 	   into new/ or cur/. */
 	/* @UNSAFE */
+	keyword_count = _ctx->keywords == NULL ? 0 : _ctx->keywords->count;
 	mf = p_malloc(ctx->pool, sizeof(*mf) +
-		      sizeof(unsigned int) * (keywords == NULL ? 0 :
-					      keywords->count));
+		      sizeof(unsigned int) * keyword_count);
 	mf->basename = p_strdup(ctx->pool, base_fname);
-	mf->flags = flags;
+	mf->flags = _ctx->flags;
 	mf->size = (uoff_t)-1;
 	mf->vsize = (uoff_t)-1;
 
@@ -160,22 +162,21 @@ uint32_t maildir_save_add(struct maildir
 	ctx->files_tail = &mf->next;
 	ctx->files_count++;
 
-	if (keywords != NULL) {
-		i_assert(sizeof(keywords->idx[0]) == sizeof(unsigned int));
-
+	if (_ctx->keywords != NULL) {
 		/* @UNSAFE */
-		mf->keywords_count = keywords->count;
-		memcpy(mf + 1, keywords->idx,
-		       sizeof(unsigned int) * keywords->count);
+		mf->keywords_count = keyword_count;
+		memcpy(mf + 1, _ctx->keywords->idx,
+		       sizeof(unsigned int) * keyword_count);
 		ctx->have_keywords = TRUE;
 	}
 
 	/* insert into index */
 	mail_index_append(ctx->trans, 0, &ctx->seq);
-	mail_index_update_flags(ctx->trans, ctx->seq, MODIFY_REPLACE, flags);
-	if (keywords != NULL) {
+	mail_index_update_flags(ctx->trans, ctx->seq,
+				MODIFY_REPLACE, _ctx->flags);
+	if (_ctx->keywords != NULL) {
 		mail_index_update_keywords(ctx->trans, ctx->seq,
-					   MODIFY_REPLACE, keywords);
+					   MODIFY_REPLACE, _ctx->keywords);
 	}
 
 	if (ctx->first_seq == 0) {
@@ -183,22 +184,23 @@ uint32_t maildir_save_add(struct maildir
 		i_assert(ctx->files->next == NULL);
 	}
 
-	if (dest_mail == NULL) {
+	if (_ctx->dest_mail == NULL) {
 		if (ctx->mail == NULL)
-			ctx->mail = mail_alloc(ctx->ctx.transaction, 0, NULL);
-		dest_mail = ctx->mail;
-	}
-	mail_set_seq(dest_mail, ctx->seq);
+			ctx->mail = mail_alloc(_ctx->transaction, 0, NULL);
+		_ctx->dest_mail = ctx->mail;
+	}
+	mail_set_seq(_ctx->dest_mail, ctx->seq);
 
 	if (ctx->input == NULL) {
 		/* FIXME: copying with hardlinking. we could copy the
 		   cached data directly */
 		ctx->cur_dest_mail = NULL;
 	} else {
-		input = index_mail_cache_parse_init(dest_mail, ctx->input);
+		input = index_mail_cache_parse_init(_ctx->dest_mail,
+						    ctx->input);
 		i_stream_unref(&ctx->input);
 		ctx->input = input;
-		ctx->cur_dest_mail = dest_mail;
+		ctx->cur_dest_mail = _ctx->dest_mail;
 	}
 	return ctx->seq;
 }
@@ -247,7 +249,7 @@ static const char *maildir_mf_get_path(s
 {
 	const char *fname;
 
-	if (!ctx->moving && (mf->flags & MAILDIR_SAVE_FLAG_HARDLINK) == 0) {
+	if ((mf->flags & MAILDIR_FILENAME_FLAG_MOVED) == 0) {
 		/* file is still in tmp/ */
 		return t_strdup_printf("%s/%s", ctx->tmpdir, mf->basename);
 	}
@@ -367,13 +369,7 @@ maildir_save_alloc(struct mailbox_transa
 
 int maildir_save_begin(struct mail_save_context *_ctx, struct istream *input)
 {
-	struct maildir_transaction_context *t =
-		(struct maildir_transaction_context *)_ctx->transaction;
 	struct maildir_save_context *ctx = (struct maildir_save_context *)_ctx;
-
-	_ctx->flags &= ~MAIL_RECENT;
-	if (ctx->mbox->ibox.keep_recent)
-		_ctx->flags |= MAIL_RECENT;
 
 	T_BEGIN {
 		/* create a new file in tmp/ directory */
@@ -387,14 +383,14 @@ int maildir_save_begin(struct mail_save_
 				ctx->input = i_stream_create_crlf(input);
 			else
 				ctx->input = i_stream_create_lf(input);
-			maildir_save_add(t->save_ctx, fname, _ctx->flags,
-					 _ctx->keywords, _ctx->dest_mail);
+			maildir_save_add(_ctx, fname);
 		}
 	} T_END;
 
 	if (!ctx->failed) {
 		_ctx->output = o_stream_create_fd_file(ctx->fd, 0, FALSE);
 		o_stream_cork(_ctx->output);
+		ctx->last_save_finished = FALSE;
 	}
 	return ctx->failed ? -1 : 0;
 }
@@ -428,37 +424,12 @@ int maildir_save_continue(struct mail_sa
 	return 0;
 }
 
-static int maildir_save_finish_real(struct mail_save_context *_ctx)
-{
-	struct maildir_save_context *ctx = (struct maildir_save_context *)_ctx;
+static int maildir_save_finish_received_date(struct maildir_save_context *ctx,
+					     const char *path)
+{
 	struct mail_storage *storage = &ctx->mbox->storage->storage;
 	struct utimbuf buf;
 	struct stat st;
-	const char *path;
-	int output_errno;
-


More information about the dovecot-cvs mailing list