changeset 21567:8004757eeee0

lib-storage: Make sure mailbox undeletion won't go to infinite loop
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Wed, 15 Feb 2017 18:05:14 +0200
parents 7dfa73aba5f6
children 5accb4ee4d95
files src/lib-storage/mail-storage-private.h src/lib-storage/mail-storage.c
diffstat 2 files changed, 9 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/mail-storage-private.h	Wed Feb 15 23:32:52 2017 +0200
+++ b/src/lib-storage/mail-storage-private.h	Wed Feb 15 18:05:14 2017 +0200
@@ -395,6 +395,8 @@
 	unsigned int creating:1;
 	/* Mailbox is being deleted */
 	unsigned int deleting:1;
+	/* Mailbox is being undeleted */
+	unsigned int mailbox_undeleting:1;
 	/* Don't use MAIL_INDEX_SYNC_FLAG_DELETING_INDEX for sync flag */
 	unsigned int delete_sync_check:1;
 	/* Delete mailbox only if it's empty */
--- a/src/lib-storage/mail-storage.c	Wed Feb 15 23:32:52 2017 +0200
+++ b/src/lib-storage/mail-storage.c	Wed Feb 15 18:05:14 2017 +0200
@@ -1136,6 +1136,8 @@
 {
 	time_t mtime;
 
+	i_assert(!box->mailbox_undeleting);
+
 	if ((box->flags & MAILBOX_FLAG_READONLY) != 0) {
 		/* most importantly we don't do this because we want to avoid
 		   a loop: mdbox storage rebuild -> mailbox_open() ->
@@ -1148,7 +1150,10 @@
 	if (mtime + MAILBOX_DELETE_RETRY_SECS > time(NULL))
 		return FALSE;
 
-	if (mailbox_mark_index_deleted(box, FALSE) < 0)
+	box->mailbox_undeleting = TRUE;
+	int ret = mailbox_mark_index_deleted(box, FALSE);
+	box->mailbox_undeleting = FALSE;
+	if (ret < 0)
 		return FALSE;
 	box->mailbox_deleted = FALSE;
 	return TRUE;
@@ -1165,7 +1170,7 @@
 	}
 
 	if (mailbox_open_full(box, NULL) < 0) {
-		if (!box->mailbox_deleted)
+		if (!box->mailbox_deleted || box->mailbox_undeleting)
 			return -1;
 
 		/* mailbox has been marked as deleted. if this deletion