dovecot-2.2: lib-storage: Added support for multiple storages pe...
dovecot at dovecot.org
dovecot at dovecot.org
Sun Jun 9 00:46:17 EEST 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/d952b4091425
changeset: 16480:d952b4091425
user: Timo Sirainen <tss at iki.fi>
date: Sun Jun 09 00:46:06 2013 +0300
description:
lib-storage: Added support for multiple storages per namespace.
diffstat:
src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c | 6 ++-
src/lib-storage/mail-namespace.c | 22 ++++++---
src/lib-storage/mail-namespace.h | 4 +-
src/lib-storage/mail-storage.c | 37 ++++++++++++---
src/lib-storage/mail-storage.h | 4 +
5 files changed, 53 insertions(+), 20 deletions(-)
diffs (191 lines):
diff -r e7ea508f36ca -r d952b4091425 src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c
--- 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",
diff -r e7ea508f36ca -r d952b4091425 src/lib-storage/mail-namespace.c
--- 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;
}
diff -r e7ea508f36ca -r d952b4091425 src/lib-storage/mail-namespace.h
--- 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;
diff -r e7ea508f36ca -r d952b4091425 src/lib-storage/mail-storage.c
--- 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;
diff -r e7ea508f36ca -r d952b4091425 src/lib-storage/mail-storage.h
--- 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. */
More information about the dovecot-cvs
mailing list