dovecot-2.0: Mailbox deletion: If mailbox deletion seems to have...

dovecot at dovecot.org dovecot at dovecot.org
Mon Feb 15 04:31:38 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/eae6e4a7ee55
changeset: 10723:eae6e4a7ee55
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Feb 15 04:31:35 2010 +0200
description:
Mailbox deletion: If mailbox deletion seems to have crashed, allow retrying the deletion.
We'll assume that if deletion transaction was written over 5 minutes ago,
the deletion crashed.

diffstat:

 src/lib-storage/mail-storage.c |  48 ++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 42 insertions(+), 6 deletions(-)

diffs (82 lines):

diff -r 31aca1df525b -r eae6e4a7ee55 src/lib-storage/mail-storage.c
--- a/src/lib-storage/mail-storage.c	Mon Feb 15 04:29:47 2010 +0200
+++ b/src/lib-storage/mail-storage.c	Mon Feb 15 04:31:35 2010 +0200
@@ -20,6 +20,8 @@
 #include <stdlib.h>
 #include <ctype.h>
 
+#define MAILBOX_DELETE_RETRY_SECS (60*5)
+
 struct mail_storage_module_register mail_storage_module_register = { 0 };
 struct mail_module_register mail_module_register = { 0 };
 
@@ -616,12 +618,17 @@
 	return box->v.update(box, update);
 }
 
-static int mailbox_mark_index_deleted(struct mailbox *box)
+static int mailbox_mark_index_deleted(struct mailbox *box, bool del)
 {
+	enum mail_index_transaction_flags trans_flags = 0;
 	struct mail_index_transaction *trans;
 
-	trans = mail_index_transaction_begin(box->view, 0);
-	mail_index_set_deleted(trans);
+	trans_flags = del ? 0 : MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL;
+	trans = mail_index_transaction_begin(box->view, trans_flags);
+	if (del)
+		mail_index_set_deleted(trans);
+	else
+		mail_index_set_undeleted(trans);
 	if (mail_index_transaction_commit(&trans) < 0) {
 		mail_storage_set_index_error(box);
 		return -1;
@@ -633,6 +640,21 @@
 	return mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ);
 }
 
+static bool mailbox_try_undelete(struct mailbox *box)
+{
+	time_t mtime;
+
+	if (mail_index_get_modification_time(box->index, &mtime) < 0)
+		return FALSE;
+	if (mtime + MAILBOX_DELETE_RETRY_SECS > time(NULL))
+		return FALSE;
+
+	if (mailbox_mark_index_deleted(box, FALSE) < 0)
+		return FALSE;
+	box->mailbox_deleted = FALSE;
+	return TRUE;
+}
+
 int mailbox_delete(struct mailbox *box)
 {
 	enum mail_error error;
@@ -654,9 +676,23 @@
 		(void)mail_storage_get_last_error(box->storage, &error);
 		if (error != MAIL_ERROR_NOTFOUND)
 			return -1;
-		/* \noselect mailbox */
-	} else {
-		if (mailbox_mark_index_deleted(box) < 0)
+		if (!box->mailbox_deleted) {
+			/* \noselect mailbox */
+		} else {
+			/* if deletion happened a long time ago, it means it
+			   crashed while doing it. undelete the mailbox in
+			   that case. */
+			if (!mailbox_try_undelete(box))
+				return -1;
+
+			/* retry */
+			if (mailbox_open(box) < 0)
+				return -1;
+		}
+	}
+
+	if (box->opened) {
+		if (mailbox_mark_index_deleted(box, TRUE) < 0)
 			return -1;
 	}
 	ret = box->v.delete(box);


More information about the dovecot-cvs mailing list