dovecot-2.0: Mailbox deletion: Fixed race condition where a mail...

dovecot at dovecot.org dovecot at dovecot.org
Tue Feb 9 17:35:20 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/9740c4858a57
changeset: 10678:9740c4858a57
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Feb 09 17:35:14 2010 +0200
description:
Mailbox deletion: Fixed race condition where a mailbox couldn't get deleted.

diffstat:

12 files changed, 39 insertions(+), 25 deletions(-)
src/lib-index/mail-index-sync.c                    |   12 +++++++-----
src/lib-index/mail-index.h                         |    4 +++-
src/lib-storage/index/cydir/cydir-sync.c           |    5 ++---
src/lib-storage/index/dbox-multi/mdbox-sync.c      |    5 ++---
src/lib-storage/index/dbox-single/sdbox-sync.c     |    5 ++---
src/lib-storage/index/index-storage.h              |    1 +
src/lib-storage/index/index-sync.c                 |   11 +++++++++++
src/lib-storage/index/maildir/maildir-sync-index.c |    7 +++----
src/lib-storage/index/mbox/mbox-sync.c             |    4 +---
src/lib-storage/index/raw/raw-sync.c               |    5 ++---
src/lib-storage/mail-storage-private.h             |    2 ++
src/lib-storage/mail-storage.c                     |    3 +++

diffs (220 lines):

diff -r 93fe3aa23bdb -r 9740c4858a57 src/lib-index/mail-index-sync.c
--- a/src/lib-index/mail-index-sync.c	Tue Feb 09 04:52:29 2010 +0200
+++ b/src/lib-index/mail-index-sync.c	Tue Feb 09 17:35:14 2010 +0200
@@ -774,11 +774,13 @@ int mail_index_sync_commit(struct mail_i
         struct mail_index_sync_ctx *ctx = *_ctx;
 	struct mail_index *index = ctx->index;
 	uint32_t next_uid;
-	bool want_rotate, index_undeleted;
+	bool want_rotate, index_undeleted, delete_index;
 	int ret = 0;
 
 	index_undeleted = ctx->ext_trans->index_undeleted;
-	if (index->index_delete_requested && !index_undeleted) {
+	delete_index = index->index_delete_requested && !index_undeleted &&
+		(ctx->flags & MAIL_INDEX_SYNC_FLAG_DELETING_INDEX) != 0;
+	if (delete_index) {
 		/* finish this sync by marking the index deleted */
 		mail_index_set_deleted(ctx->ext_trans);
 	}
@@ -806,12 +808,12 @@ int mail_index_sync_commit(struct mail_i
 		return -1;
 	}
 
-	if (index_undeleted) {
+	if (delete_index)
+		index->index_deleted = TRUE;
+	else if (index_undeleted) {
 		index->index_deleted = FALSE;
 		index->index_delete_requested = FALSE;
 	}
-	if (index->index_delete_requested)
-		index->index_deleted = TRUE;
 
 	/* refresh the mapping with newly committed external transactions
 	   and the synced expunges. sync using file handler here so that the
diff -r 93fe3aa23bdb -r 9740c4858a57 src/lib-index/mail-index.h
--- a/src/lib-index/mail-index.h	Tue Feb 09 04:52:29 2010 +0200
+++ b/src/lib-index/mail-index.h	Tue Feb 09 17:35:14 2010 +0200
@@ -143,7 +143,9 @@ enum mail_index_sync_flags {
 	   return 0 in mail_index_sync_begin() */
 	MAIL_INDEX_SYNC_FLAG_REQUIRE_CHANGES	= 0x08,
 	/* Create the transaction with FSYNC flag */
-	MAIL_INDEX_SYNC_FLAG_FSYNC		= 0x10
+	MAIL_INDEX_SYNC_FLAG_FSYNC		= 0x10,
+	/* If we see "delete index" request transaction, finish it */
+	MAIL_INDEX_SYNC_FLAG_DELETING_INDEX	= 0x20
 };
 
 enum mail_index_view_sync_flags {
diff -r 93fe3aa23bdb -r 9740c4858a57 src/lib-storage/index/cydir/cydir-sync.c
--- a/src/lib-storage/index/cydir/cydir-sync.c	Tue Feb 09 04:52:29 2010 +0200
+++ b/src/lib-storage/index/cydir/cydir-sync.c	Tue Feb 09 17:35:14 2010 +0200
@@ -116,9 +116,8 @@ int cydir_sync_begin(struct cydir_mailbo
 	ctx = i_new(struct cydir_sync_context, 1);
 	ctx->mbox = mbox;
 
-	sync_flags = MAIL_INDEX_SYNC_FLAG_FLUSH_DIRTY;
-	if ((mbox->box.flags & MAILBOX_FLAG_KEEP_RECENT) == 0)
-		sync_flags |= MAIL_INDEX_SYNC_FLAG_DROP_RECENT;
+	sync_flags = index_storage_get_sync_flags(&mbox->box) |
+		MAIL_INDEX_SYNC_FLAG_FLUSH_DIRTY;
 	if (!force)
 		sync_flags |= MAIL_INDEX_SYNC_FLAG_REQUIRE_CHANGES;
 
diff -r 93fe3aa23bdb -r 9740c4858a57 src/lib-storage/index/dbox-multi/mdbox-sync.c
--- a/src/lib-storage/index/dbox-multi/mdbox-sync.c	Tue Feb 09 04:52:29 2010 +0200
+++ b/src/lib-storage/index/dbox-multi/mdbox-sync.c	Tue Feb 09 17:35:14 2010 +0200
@@ -185,7 +185,7 @@ int mdbox_sync_begin(struct mdbox_mailbo
 {
 	struct mail_storage *storage = mbox->box.storage;
 	struct mdbox_sync_context *ctx;
-	enum mail_index_sync_flags sync_flags = 0;
+	enum mail_index_sync_flags sync_flags;
 	unsigned int i;
 	int ret;
 	bool rebuild, storage_rebuilt = FALSE;
@@ -203,8 +203,7 @@ int mdbox_sync_begin(struct mdbox_mailbo
 	ctx->mbox = mbox;
 	ctx->flags = flags;
 
-	if ((mbox->box.flags & MAILBOX_FLAG_KEEP_RECENT) == 0)
-		sync_flags |= MAIL_INDEX_SYNC_FLAG_DROP_RECENT;
+	sync_flags = index_storage_get_sync_flags(&mbox->box);
 	if (!rebuild && (flags & MDBOX_SYNC_FLAG_FORCE) == 0)
 		sync_flags |= MAIL_INDEX_SYNC_FLAG_REQUIRE_CHANGES;
 	if ((flags & MDBOX_SYNC_FLAG_FSYNC) != 0)
diff -r 93fe3aa23bdb -r 9740c4858a57 src/lib-storage/index/dbox-single/sdbox-sync.c
--- a/src/lib-storage/index/dbox-single/sdbox-sync.c	Tue Feb 09 04:52:29 2010 +0200
+++ b/src/lib-storage/index/dbox-single/sdbox-sync.c	Tue Feb 09 17:35:14 2010 +0200
@@ -166,7 +166,7 @@ int sdbox_sync_begin(struct sdbox_mailbo
 {
 	struct mail_storage *storage = mbox->box.storage;
 	struct sdbox_sync_context *ctx;
-	enum mail_index_sync_flags sync_flags = 0;
+	enum mail_index_sync_flags sync_flags;
 	unsigned int i;
 	int ret;
 	bool rebuild;
@@ -178,8 +178,7 @@ int sdbox_sync_begin(struct sdbox_mailbo
 	ctx->mbox = mbox;
 	ctx->flags = flags;
 
-	if ((mbox->box.flags & MAILBOX_FLAG_KEEP_RECENT) == 0)
-		sync_flags |= MAIL_INDEX_SYNC_FLAG_DROP_RECENT;
+	sync_flags = index_storage_get_sync_flags(&mbox->box);
 	if (!rebuild && (flags & SDBOX_SYNC_FLAG_FORCE) == 0)
 		sync_flags |= MAIL_INDEX_SYNC_FLAG_REQUIRE_CHANGES;
 	if ((flags & SDBOX_SYNC_FLAG_FSYNC) != 0)
diff -r 93fe3aa23bdb -r 9740c4858a57 src/lib-storage/index/index-storage.h
--- a/src/lib-storage/index/index-storage.h	Tue Feb 09 04:52:29 2010 +0200
+++ b/src/lib-storage/index/index-storage.h	Tue Feb 09 17:35:14 2010 +0200
@@ -104,6 +104,7 @@ void index_mailbox_check_add(struct mail
 void index_mailbox_check_add(struct mailbox *box, const char *path);
 void index_mailbox_check_remove_all(struct mailbox *box);
 
+enum mail_index_sync_flags index_storage_get_sync_flags(struct mailbox *box);
 bool index_mailbox_want_full_sync(struct mailbox *box,
 				  enum mailbox_sync_flags flags);
 struct mailbox_sync_context *
diff -r 93fe3aa23bdb -r 9740c4858a57 src/lib-storage/index/index-sync.c
--- a/src/lib-storage/index/index-sync.c	Tue Feb 09 04:52:29 2010 +0200
+++ b/src/lib-storage/index/index-sync.c	Tue Feb 09 17:35:14 2010 +0200
@@ -5,6 +5,17 @@
 #include "ioloop.h"
 #include "array.h"
 #include "index-sync-private.h"
+
+enum mail_index_sync_flags index_storage_get_sync_flags(struct mailbox *box)
+{
+	enum mail_index_sync_flags sync_flags = 0;
+
+	if ((box->flags & MAILBOX_FLAG_KEEP_RECENT) == 0)
+		sync_flags |= MAIL_INDEX_SYNC_FLAG_DROP_RECENT;
+	if (box->deleting)
+		sync_flags |= MAIL_INDEX_SYNC_FLAG_DELETING_INDEX;
+	return sync_flags;
+}
 
 bool index_mailbox_want_full_sync(struct mailbox *box,
 				  enum mailbox_sync_flags flags)
diff -r 93fe3aa23bdb -r 9740c4858a57 src/lib-storage/index/maildir/maildir-sync-index.c
--- a/src/lib-storage/index/maildir/maildir-sync-index.c	Tue Feb 09 04:52:29 2010 +0200
+++ b/src/lib-storage/index/maildir/maildir-sync-index.c	Tue Feb 09 17:35:14 2010 +0200
@@ -219,11 +219,10 @@ int maildir_sync_index_begin(struct mail
 	struct mail_index_transaction *trans;
 	enum mail_index_sync_flags sync_flags;
 
-	sync_flags = 0;
+	sync_flags = index_storage_get_sync_flags(&mbox->box);
 	/* don't drop recent messages if we're saving messages */
-	if ((_box->flags & MAILBOX_FLAG_KEEP_RECENT) == 0 &&
-	    maildir_sync_ctx != NULL)
-		sync_flags |= MAIL_INDEX_SYNC_FLAG_DROP_RECENT;
+	if (maildir_sync_ctx == NULL)
+		sync_flags &= ~MAIL_INDEX_SYNC_FLAG_DROP_RECENT;
 
 	if (mail_index_sync_begin(_box->index, &sync_ctx, &view,
 				  &trans, sync_flags) < 0) {
diff -r 93fe3aa23bdb -r 9740c4858a57 src/lib-storage/index/mbox/mbox-sync.c
--- a/src/lib-storage/index/mbox/mbox-sync.c	Tue Feb 09 04:52:29 2010 +0200
+++ b/src/lib-storage/index/mbox/mbox-sync.c	Tue Feb 09 17:35:14 2010 +0200
@@ -1792,9 +1792,7 @@ again:
 		}
 	}
 
-	sync_flags = 0;
-	if ((mbox->box.flags & MAILBOX_FLAG_KEEP_RECENT) == 0)
-		sync_flags |= MAIL_INDEX_SYNC_FLAG_DROP_RECENT;
+	sync_flags = index_storage_get_sync_flags(&mbox->box);
 	if ((flags & MBOX_SYNC_REWRITE) != 0)
 		sync_flags |= MAIL_INDEX_SYNC_FLAG_FLUSH_DIRTY;
 
diff -r 93fe3aa23bdb -r 9740c4858a57 src/lib-storage/index/raw/raw-sync.c
--- a/src/lib-storage/index/raw/raw-sync.c	Tue Feb 09 04:52:29 2010 +0200
+++ b/src/lib-storage/index/raw/raw-sync.c	Tue Feb 09 17:35:14 2010 +0200
@@ -16,10 +16,9 @@ static int raw_sync(struct raw_mailbox *
 
 	i_assert(!mbox->synced);
 
-	sync_flags = MAIL_INDEX_SYNC_FLAG_FLUSH_DIRTY |
+	sync_flags = index_storage_get_sync_flags(&mbox->box) |
+		MAIL_INDEX_SYNC_FLAG_FLUSH_DIRTY |
 		MAIL_INDEX_SYNC_FLAG_REQUIRE_CHANGES;
-	if ((mbox->box.flags & MAILBOX_FLAG_KEEP_RECENT) == 0)
-		sync_flags |= MAIL_INDEX_SYNC_FLAG_DROP_RECENT;
 
 	ret = mail_index_sync_begin(mbox->box.index, &index_sync_ctx,
 				    &sync_view, &trans, sync_flags);
diff -r 93fe3aa23bdb -r 9740c4858a57 src/lib-storage/mail-storage-private.h
--- a/src/lib-storage/mail-storage-private.h	Tue Feb 09 04:52:29 2010 +0200
+++ b/src/lib-storage/mail-storage-private.h	Tue Feb 09 17:35:14 2010 +0200
@@ -256,6 +256,8 @@ struct mailbox {
 	unsigned int mailbox_deleted:1;
 	/* we've discovered there aren't enough permissions to modify mailbox */
 	unsigned int backend_readonly:1;
+	/* Mailbox is being deleted */
+	unsigned int deleting:1;
 };
 
 struct mail_vfuncs {
diff -r 93fe3aa23bdb -r 9740c4858a57 src/lib-storage/mail-storage.c
--- a/src/lib-storage/mail-storage.c	Tue Feb 09 04:52:29 2010 +0200
+++ b/src/lib-storage/mail-storage.c	Tue Feb 09 17:35:14 2010 +0200
@@ -615,6 +615,7 @@ int mailbox_delete(struct mailbox *box)
 		return -1;
 	}
 
+	box->deleting = TRUE;
 	if (mailbox_open(box) < 0) {
 		(void)mail_storage_get_last_error(box->storage, &error);
 		if (error != MAIL_ERROR_NOTFOUND)
@@ -625,6 +626,8 @@ int mailbox_delete(struct mailbox *box)
 			return -1;
 	}
 	ret = box->v.delete(box);
+
+	box->deleting = FALSE;
 	mailbox_close(box);
 	return ret;
 }


More information about the dovecot-cvs mailing list