From: Timo Sirainen Date: Sat, 6 Mar 2010 10:52:59 +0000 (+0200) Subject: mdbox: Don't crash when trying to rebuild storage at deinit. X-Git-Tag: 2.0.beta4~125 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cd89cbcf9ef73a0855ffcbe799b4fc2442b28cbb;p=thirdparty%2Fdovecot%2Fcore.git mdbox: Don't crash when trying to rebuild storage at deinit. --HG-- branch : HEAD --- diff --git a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c index 20721ac990..ee8488344a 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c +++ b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c @@ -723,6 +723,8 @@ static void rebuild_update_refcounts(struct mdbox_storage_rebuild_context *ctx) static int rebuild_finish(struct mdbox_storage_rebuild_context *ctx) { + i_assert(ctx->default_list != NULL); + if (rebuild_handle_zero_refs(ctx) < 0) return -1; rebuild_update_refcounts(ctx); diff --git a/src/lib-storage/mail-namespace.c b/src/lib-storage/mail-namespace.c index e5509b9bc4..381b58b120 100644 --- a/src/lib-storage/mail-namespace.c +++ b/src/lib-storage/mail-namespace.c @@ -340,14 +340,17 @@ struct mail_namespace *mail_namespaces_init_empty(struct mail_user *user) void mail_namespaces_deinit(struct mail_namespace **_namespaces) { - struct mail_namespace *ns, *namespaces = *_namespaces; + struct mail_namespace *ns, *next; - *_namespaces = NULL; - while (namespaces != NULL) { - ns = namespaces; - namespaces = namespaces->next; + /* update *_namespaces as needed, instead of immediately setting it + to NULL. for example mdbox_storage.destroy() wants to go through + user's namespaces. */ + while (*_namespaces != NULL) { + ns = *_namespaces; + next = ns->next; mail_namespace_free(ns); + *_namespaces = next; } } diff --git a/src/lib-storage/mail-storage.c b/src/lib-storage/mail-storage.c index 73bfc52206..7d99b9e5cc 100644 --- a/src/lib-storage/mail-storage.c +++ b/src/lib-storage/mail-storage.c @@ -324,16 +324,20 @@ void mail_storage_unref(struct mail_storage **_storage) i_assert(storage->refcount > 0); - *_storage = NULL; - - if (--storage->refcount > 0) + /* set *_storage=NULL only after calling destroy() callback. + for example mdbox wants to access ns->storage */ + if (--storage->refcount > 0) { + *_storage = NULL; return; + } DLLIST_REMOVE(&storage->user->storages, storage); if (storage->v.destroy != NULL) storage->v.destroy(storage); i_free(storage->error_string); + + *_storage = NULL; pool_unref(&storage->pool); mail_index_alloc_cache_destroy_unrefed();