Mercurial > dovecot > core-2.2
changeset 10843:e3672e7c0f9f HEAD
mdbox: Don't crash when trying to rebuild storage at deinit.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 06 Mar 2010 12:52:59 +0200 |
parents | a81aceb9f55b |
children | 3bfb1e9f556b |
files | src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c src/lib-storage/mail-namespace.c src/lib-storage/mail-storage.c |
diffstat | 3 files changed, 17 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c Sat Mar 06 12:30:53 2010 +0200 +++ b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c Sat Mar 06 12:52:59 2010 +0200 @@ -723,6 +723,8 @@ 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);
--- a/src/lib-storage/mail-namespace.c Sat Mar 06 12:30:53 2010 +0200 +++ b/src/lib-storage/mail-namespace.c Sat Mar 06 12:52:59 2010 +0200 @@ -340,14 +340,17 @@ 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; } }
--- a/src/lib-storage/mail-storage.c Sat Mar 06 12:30:53 2010 +0200 +++ b/src/lib-storage/mail-storage.c Sat Mar 06 12:52:59 2010 +0200 @@ -324,16 +324,20 @@ 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();