dovecot-2.2: lmtp: Removed code that attempts to deduplicate mai...

dovecot at dovecot.org dovecot at dovecot.org
Thu Jul 3 17:29:55 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/51274bf2a47d
changeset: 17588:51274bf2a47d
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Jul 03 20:28:16 2014 +0300
description:
lmtp: Removed code that attempts to deduplicate mail files by copying them between user mailboxes.
This sometimes started failing if the mail that was being used for copying
was deleted by the user. There's no good way for lmtp code to fix that
situation.

If deduplication is needed, it could be implemented in a more generic way
inside mailbox_copy() where after initial copy it would store the
destination struct mail to src_mail->last_copy_dest_mail. If another mail is
copied, the last_copy_dest_mail could be attempted to be used for the
copying and if that doesn't work it would fallback to regular copying. This
should probably be attempted only for lda/lmtp processes as it would just
cause extra overhead for others.

diffstat:

 src/lmtp/client.h   |   3 --
 src/lmtp/commands.c |  69 ++++++++++------------------------------------------
 2 files changed, 14 insertions(+), 58 deletions(-)

diffs (171 lines):

diff -r 4c4db2d76137 -r 51274bf2a47d src/lmtp/client.h
--- a/src/lmtp/client.h	Thu Jul 03 19:34:57 2014 +0300
+++ b/src/lmtp/client.h	Thu Jul 03 20:28:16 2014 +0300
@@ -29,9 +29,6 @@
 
 	struct mail *raw_mail;
 
-	struct mail_user *dest_user;
-	struct mail *first_saved_mail;
-
 	unsigned int mail_body_7bit:1;
 	unsigned int mail_body_8bitmime:1;
 };
diff -r 4c4db2d76137 -r 51274bf2a47d src/lmtp/commands.c
--- a/src/lmtp/commands.c	Thu Jul 03 19:34:57 2014 +0300
+++ b/src/lmtp/commands.c	Thu Jul 03 20:28:16 2014 +0300
@@ -614,7 +614,7 @@
 
 static int
 client_deliver(struct client *client, const struct mail_recipient *rcpt,
-	       struct mail *src_mail, struct mail_deliver_session *session)
+	       struct mail_deliver_session *session)
 {
 	struct mail_deliver_context dctx;
 	struct mail_storage *storage;
@@ -622,6 +622,7 @@
 	const struct mail_storage_settings *mail_set;
 	struct lda_settings *lda_set;
 	struct mail_namespace *ns;
+	struct mail_user *dest_user;
 	struct setting_parser_context *set_parser;
 	void **sets;
 	const char *line, *error, *username;
@@ -649,7 +650,7 @@
 
 	i_set_failure_prefix("lmtp(%s, %s): ", my_pid, username);
 	if (mail_storage_service_next(storage_service, rcpt->service_user,
-				      &client->state.dest_user) < 0) {
+				      &dest_user) < 0) {
 		client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL,
 				 rcpt->address);
 		return -1;
@@ -657,18 +658,18 @@
 	sets = mail_storage_service_user_get_set(rcpt->service_user);
 	lda_set = sets[1];
 	settings_var_expand(&lda_setting_parser_info, lda_set, client->pool,
-		mail_user_var_expand_table(client->state.dest_user));
+		mail_user_var_expand_table(dest_user));
 
 	memset(&dctx, 0, sizeof(dctx));
 	dctx.session = session;
 	dctx.pool = session->pool;
 	dctx.set = lda_set;
 	dctx.session_id = client->state.session_id;
-	dctx.src_mail = src_mail;
+	dctx.src_mail = client->state.raw_mail;
 	dctx.src_envelope_sender = client->state.mail_from;
-	dctx.dest_user = client->state.dest_user;
+	dctx.dest_user = dest_user;
 	if (*dctx.set->lda_original_recipient_header != '\0') {
-		dctx.dest_addr = mail_deliver_get_address(src_mail,
+		dctx.dest_addr = mail_deliver_get_address(dctx.src_mail,
 				dctx.set->lda_original_recipient_header);
 	}
 	if (dctx.dest_addr == NULL)
@@ -678,19 +679,12 @@
 	    !client->lmtp_set->lmtp_save_to_detail_mailbox)
 		dctx.dest_mailbox_name = "INBOX";
 	else {
-		ns = mail_namespace_find_inbox(dctx.dest_user->namespaces);
+		ns = mail_namespace_find_inbox(dest_user->namespaces);
 		dctx.dest_mailbox_name =
 			t_strconcat(ns->prefix, rcpt->detail, NULL);
 	}
 
-	dctx.save_dest_mail = array_count(&client->state.rcpt_to) > 1 &&
-		client->state.first_saved_mail == NULL;
-
 	if (mail_deliver(&dctx, &storage) == 0) {
-		if (dctx.dest_mail != NULL) {
-			i_assert(client->state.first_saved_mail == NULL);
-			client->state.first_saved_mail = dctx.dest_mail;
-		}
 		client_send_line(client, "250 2.0.0 <%s> %s Saved",
 				 rcpt->address, client->state.session_id);
 		ret = 0;
@@ -717,10 +711,11 @@
 				 rcpt->address);
 		ret = -1;
 	}
+	mail_user_unref(&dest_user);
 	return ret;
 }
 
-static bool client_deliver_next(struct client *client, struct mail *src_mail,
+static bool client_deliver_next(struct client *client,
 				struct mail_deliver_session *session)
 {
 	const struct mail_recipient *rcpts;
@@ -730,15 +725,13 @@
 	rcpts = array_get(&client->state.rcpt_to, &count);
 	while (client->state.rcpt_idx < count) {
 		ret = client_deliver(client, &rcpts[client->state.rcpt_idx],
-				     src_mail, session);
+				     session);
 		i_set_failure_prefix("lmtp(%s): ", my_pid);
 
 		client->state.rcpt_idx++;
 		if (ret == 0)
 			return TRUE;
 		/* failed. try the next one. */
-		if (client->state.dest_user != NULL)
-			mail_user_unref(&client->state.dest_user);
 	}
 	return FALSE;
 }
@@ -815,51 +808,17 @@
 client_input_data_write_local(struct client *client, struct istream *input)
 {
 	struct mail_deliver_session *session;
-	struct mail *src_mail;
-	uid_t old_uid, first_uid = (uid_t)-1;
+	uid_t old_uid;
 
 	if (client_open_raw_mail(client, input) < 0)
 		return;
 
 	session = mail_deliver_session_init();
 	old_uid = geteuid();
-	src_mail = client->state.raw_mail;
-	while (client_deliver_next(client, src_mail, session)) {
-		if (client->state.first_saved_mail == NULL ||
-		    client->state.first_saved_mail == src_mail)
-			mail_user_unref(&client->state.dest_user);
-		else {
-			/* use the first saved message to save it elsewhere too.
-			   this might allow hard linking the files. */
-			client->state.dest_user = NULL;
-			src_mail = client->state.first_saved_mail;
-			first_uid = geteuid();
-			i_assert(first_uid != 0);
-		}
-	}
+	while (client_deliver_next(client, session))
+		;
 	mail_deliver_session_deinit(&session);
 
-	if (client->state.first_saved_mail != NULL) {
-		struct mail *mail = client->state.first_saved_mail;
-		struct mailbox_transaction_context *trans = mail->transaction;
-		struct mailbox *box = trans->box;
-		struct mail_user *user = box->storage->user;
-
-		/* just in case these functions are going to write anything,
-		   change uid back to user's own one */
-		if (first_uid != old_uid) {
-			if (seteuid(0) < 0)
-				i_fatal("seteuid(0) failed: %m");
-			if (seteuid(first_uid) < 0)
-				i_fatal("seteuid() failed: %m");
-		}
-
-		mail_free(&mail);
-		mailbox_transaction_rollback(&trans);
-		mailbox_free(&box);
-		mail_user_unref(&user);
-	}
-
 	if (old_uid == 0) {
 		/* switch back to running as root, since that's what we're
 		   practically doing anyway. it's also important in case we


More information about the dovecot-cvs mailing list