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