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