Mercurial > dovecot > core-2.2
changeset 16480:d952b4091425
lib-storage: Added support for multiple storages per namespace.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 09 Jun 2013 00:46:06 +0300 |
parents | e7ea508f36ca |
children | 7e91b0709f06 |
files | src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c src/lib-storage/mail-namespace.c src/lib-storage/mail-namespace.h src/lib-storage/mail-storage.c src/lib-storage/mail-storage.h |
diffstat | 5 files changed, 53 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c Sun Jun 09 00:42:36 2013 +0300 +++ b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c Sun Jun 09 00:46:06 2013 +0300 @@ -541,7 +541,11 @@ box = mailbox_alloc(ns->list, vname, MAILBOX_FLAG_READONLY | MAILBOX_FLAG_IGNORE_ACLS); - i_assert(box->storage == &ctx->storage->storage.storage); + if (box->storage != &ctx->storage->storage.storage) { + /* the namespace has multiple storages. */ + mailbox_free(&box); + return 0; + } if (mailbox_open(box) < 0) { error = mailbox_get_last_mail_error(box); i_error("Couldn't open mailbox '%s': %s",
--- a/src/lib-storage/mail-namespace.c Sun Jun 09 00:42:36 2013 +0300 +++ b/src/lib-storage/mail-namespace.c Sun Jun 09 00:46:06 2013 +0300 @@ -34,9 +34,9 @@ void mail_namespace_add_storage(struct mail_namespace *ns, struct mail_storage *storage) { - /* currently we support only a single storage */ - i_assert(ns->storage == NULL); - ns->storage = storage; + if (ns->storage == NULL) + ns->storage = storage; + array_append(&ns->all_storages, &storage, 1); if (storage->v.add_list != NULL) storage->v.add_list(storage, ns->list); @@ -52,8 +52,11 @@ static void mail_namespace_free(struct mail_namespace *ns) { - if (ns->storage != NULL) - mail_storage_unref(&ns->storage); + struct mail_storage **storagep; + + array_foreach_modifiable(&ns->all_storages, storagep) + mail_storage_unref(storagep); + array_free(&ns->all_storages); if (ns->list != NULL) mailbox_list_destroy(&ns->list); @@ -150,6 +153,7 @@ ns->mail_set = mail_set; ns->prefix = i_strdup(ns_set->prefix); ns->special_use_mailboxes = namespace_has_special_use_mailboxes(ns_set); + i_array_init(&ns->all_storages, 2); if (ns->type == MAIL_NAMESPACE_TYPE_SHARED && (strchr(ns->prefix, '%') != NULL || @@ -510,9 +514,12 @@ void *context) { struct mail_namespace *ns; + struct mail_storage *const *storagep; - for (ns = namespaces; ns != NULL; ns = ns->next) - mail_storage_set_callbacks(ns->storage, callbacks, context); + for (ns = namespaces; ns != NULL; ns = ns->next) { + array_foreach(&ns->all_storages, storagep) + mail_storage_set_callbacks(*storagep, callbacks, context); + } } void mail_namespace_ref(struct mail_namespace *ns) @@ -558,7 +565,6 @@ struct mail_storage * mail_namespace_get_default_storage(struct mail_namespace *ns) { - /* currently we don't support more than one storage per namespace */ return ns->storage; }
--- a/src/lib-storage/mail-namespace.h Sun Jun 09 00:42:36 2013 +0300 +++ b/src/lib-storage/mail-namespace.h Sun Jun 09 00:46:06 2013 +0300 @@ -67,8 +67,8 @@ struct mail_user *user, *owner; struct mailbox_list *list; - /* FIXME: we should support multiple storages in one namespace */ - struct mail_storage *storage; + struct mail_storage *storage; /* default storage */ + ARRAY(struct mail_storage *) all_storages; const struct mail_namespace_settings *set, *unexpanded_set; const struct mail_storage_settings *mail_set;
--- a/src/lib-storage/mail-storage.c Sun Jun 09 00:42:36 2013 +0300 +++ b/src/lib-storage/mail-storage.c Sun Jun 09 00:46:06 2013 +0300 @@ -298,14 +298,15 @@ return NULL; } -int mail_storage_create(struct mail_namespace *ns, const char *driver, - enum mail_storage_flags flags, const char **error_r) +int mail_storage_create_full(struct mail_namespace *ns, const char *driver, + const char *data, enum mail_storage_flags flags, + struct mail_storage **storage_r, + const char **error_r) { struct mail_storage *storage_class, *storage = NULL; struct mailbox_list *list; struct mailbox_list_settings list_set; enum mailbox_list_flags list_flags = 0; - const char *data = ns->set->location; const char *p; if ((flags & MAIL_STORAGE_FLAG_KEEP_HEADER_MD5) == 0 && @@ -369,6 +370,7 @@ /* using an existing storage */ storage->refcount++; mail_namespace_add_storage(ns, storage); + *storage_r = storage; return 0; } @@ -392,10 +394,20 @@ } T_END; DLLIST_PREPEND(&ns->user->storages, storage); - mail_namespace_add_storage(ns, storage); + mail_namespace_add_storage(ns, storage); + *storage_r = storage; return 0; } +int mail_storage_create(struct mail_namespace *ns, const char *driver, + enum mail_storage_flags flags, const char **error_r) +{ + struct mail_storage *storage; + + return mail_storage_create_full(ns, driver, ns->set->location, + flags, &storage, error_r); +} + void mail_storage_unref(struct mail_storage **_storage) { struct mail_storage *storage = *_storage; @@ -639,6 +651,8 @@ struct mailbox_list *new_list = list; struct mail_storage *storage; struct mailbox *box; + enum mail_error open_error = 0; + const char *errstr = NULL; i_assert(uni_utf8_str_is_valid(vname)); @@ -654,14 +668,19 @@ vname = t_strconcat("INBOX", vname + 5, NULL); } - if (mailbox_list_get_storage(&new_list, vname, &storage) < 0) { - /* just use the default storage. FIXME: does this break? */ - storage = mail_namespace_get_default_storage(list->ns); - } + T_BEGIN { + if (mailbox_list_get_storage(&new_list, vname, &storage) < 0) { + /* do a delayed failure at mailbox_open() */ + storage = mail_namespace_get_default_storage(list->ns); + errstr = mailbox_list_get_last_error(new_list, &open_error); + errstr = t_strdup(errstr); + } - T_BEGIN { box = storage->v.mailbox_alloc(storage, new_list, vname, flags); box->set = mailbox_settings_find(storage->user, vname); + box->open_error = open_error; + if (open_error != 0) + mail_storage_set_error(storage, open_error, errstr); hook_mailbox_allocated(box); } T_END;
--- a/src/lib-storage/mail-storage.h Sun Jun 09 00:42:36 2013 +0300 +++ b/src/lib-storage/mail-storage.h Sun Jun 09 00:46:06 2013 +0300 @@ -419,6 +419,10 @@ int mail_storage_create(struct mail_namespace *ns, const char *driver, enum mail_storage_flags flags, const char **error_r) ATTR_NULL(2); +int mail_storage_create_full(struct mail_namespace *ns, const char *driver, + const char *data, enum mail_storage_flags flags, + struct mail_storage **storage_r, + const char **error_r) ATTR_NULL(2); void mail_storage_unref(struct mail_storage **storage); /* Returns the mail storage settings. */