Mercurial > dovecot > core-2.2
changeset 10678:9740c4858a57 HEAD
Mailbox deletion: Fixed race condition where a mailbox couldn't get deleted.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 09 Feb 2010 17:35:14 +0200 |
parents | 93fe3aa23bdb |
children | 3712e2dcc856 |
files | src/lib-index/mail-index-sync.c src/lib-index/mail-index.h src/lib-storage/index/cydir/cydir-sync.c src/lib-storage/index/dbox-multi/mdbox-sync.c src/lib-storage/index/dbox-single/sdbox-sync.c src/lib-storage/index/index-storage.h src/lib-storage/index/index-sync.c src/lib-storage/index/maildir/maildir-sync-index.c src/lib-storage/index/mbox/mbox-sync.c src/lib-storage/index/raw/raw-sync.c src/lib-storage/mail-storage-private.h src/lib-storage/mail-storage.c |
diffstat | 12 files changed, 39 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- 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 @@ 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 @@ 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
--- 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 @@ 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 {
--- 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 @@ 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;
--- 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 @@ { 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 @@ 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)
--- 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 @@ { 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 @@ 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)
--- 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 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 *
--- 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 @@ -6,6 +6,17 @@ #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) {
--- 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 @@ 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) {
--- 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 @@ } } - 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;
--- 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 @@ 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);
--- 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 @@ 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 {
--- 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 @@ 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 @@ return -1; } ret = box->v.delete(box); + + box->deleting = FALSE; mailbox_close(box); return ret; }