dovecot-2.2: lib-storage: Fixes to handling separation of privat...

dovecot at dovecot.org dovecot at dovecot.org
Mon Oct 29 15:19:11 EET 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/4c84efce3a94
changeset: 15275:4c84efce3a94
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Oct 29 15:18:34 2012 +0200
description:
lib-storage: Fixes to handling separation of private/shared attributes.

diffstat:

 src/lib-storage/index/index-attribute.c |  102 ++++++++++++++++++++++++++++---
 src/lib-storage/index/index-storage.c   |    6 +-
 src/lib-storage/mail-storage-private.h  |    9 +-
 src/lib-storage/mail-user.c             |    5 +
 src/lib-storage/mail-user.h             |    4 +
 5 files changed, 108 insertions(+), 18 deletions(-)

diffs (242 lines):

diff -r a87edad22199 -r 4c84efce3a94 src/lib-storage/index/index-attribute.c
--- a/src/lib-storage/index/index-attribute.c	Mon Oct 29 15:17:17 2012 +0200
+++ b/src/lib-storage/index/index-attribute.c	Mon Oct 29 15:18:34 2012 +0200
@@ -12,10 +12,74 @@
 	bool dict_disabled;
 };
 
-static int index_storage_get_dict(struct mailbox *box, struct dict **dict_r,
-				  const char **mailbox_prefix_r)
+static struct mail_namespace *
+mail_user_find_attribute_namespace(struct mail_user *user)
+{
+	struct mail_namespace *ns;
+
+	ns = mail_namespace_find_inbox(user->namespaces);
+	if (ns != NULL)
+		return ns;
+
+	for (ns = user->namespaces; ns != NULL; ns = ns->next) {
+		if (ns->type == MAIL_NAMESPACE_TYPE_PRIVATE)
+			return ns;
+	}
+	return NULL;
+}
+
+static int
+index_storage_get_user_dict(struct mail_storage *err_storage,
+			    struct mail_user *user, struct dict **dict_r)
+{
+	struct mail_namespace *ns;
+	struct mail_storage *attr_storage;
+	const char *error;
+
+	if (user->_attr_dict != NULL) {
+		*dict_r = user->_attr_dict;
+		return 0;
+	}
+	if (user->attr_dict_failed) {
+		mail_storage_set_internal_error(err_storage);
+		return -1;
+	}
+
+	ns = mail_user_find_attribute_namespace(user);
+	if (ns == NULL) {
+		/* probably never happens? */
+		mail_storage_set_error(err_storage, MAIL_ERROR_NOTPOSSIBLE,
+			"Mailbox attributes not available for this mailbox");
+		return -1;
+	}
+	attr_storage = mail_namespace_get_default_storage(ns);
+
+	if (*attr_storage->set->mail_attribute_dict == '\0') {
+		mail_storage_set_error(err_storage, MAIL_ERROR_NOTPOSSIBLE,
+				       "Mailbox attributes not enabled");
+		return -1;
+	}
+
+	if (dict_init(attr_storage->set->mail_attribute_dict,
+		      DICT_DATA_TYPE_STRING,
+		      user->username, user->set->base_dir,
+		      &user->_attr_dict, &error) < 0) {
+		mail_storage_set_critical(err_storage,
+			"mail_attribute_dict: dict_init(%s) failed: %s",
+			attr_storage->set->mail_attribute_dict, error);
+		user->attr_dict_failed = TRUE;
+		return -1;
+	}
+	*dict_r = user->_attr_dict;
+	return 0;
+}
+
+static int
+index_storage_get_dict(struct mailbox *box, enum mail_attribute_type type,
+		       struct dict **dict_r, const char **mailbox_prefix_r)
 {
 	struct mail_storage *storage = box->storage;
+	struct mail_namespace *ns;
 	struct mailbox_metadata metadata;
 	const char *error;
 
@@ -23,8 +87,24 @@
 		return -1;
 	*mailbox_prefix_r = guid_128_to_string(metadata.guid);
 
-	if (storage->_attr_dict != NULL) {
-		*dict_r = storage->_attr_dict;
+	ns = mailbox_get_namespace(box);
+	if (type == MAIL_ATTRIBUTE_TYPE_PRIVATE) {
+		/* private attributes are stored in user's own dict */
+		return index_storage_get_user_dict(storage, storage->user, dict_r);
+	} else if (ns->user == ns->owner) {
+		/* user owns the mailbox. shared attributes are stored in
+		   the same dict. */
+		return index_storage_get_user_dict(storage, storage->user, dict_r);
+	} else if (ns->owner != NULL) {
+		/* accessing shared attribute of a shared mailbox.
+		   use the owner's dict. */
+		return index_storage_get_user_dict(storage, ns->owner, dict_r);
+	}
+
+	/* accessing shared attributes of a public mailbox. no user owns it,
+	   so use the storage's dict. */
+	if (storage->_shared_attr_dict != NULL) {
+		*dict_r = storage->_shared_attr_dict;
 		return 0;
 	}
 	if (*storage->set->mail_attribute_dict == '\0') {
@@ -32,7 +112,7 @@
 				       "Mailbox attributes not enabled");
 		return -1;
 	}
-	if (storage->attr_dict_failed) {
+	if (storage->shared_attr_dict_failed) {
 		mail_storage_set_internal_error(storage);
 		return -1;
 	}
@@ -41,14 +121,14 @@
 		      DICT_DATA_TYPE_STRING,
 		      storage->user->username,
 		      storage->user->set->base_dir,
-		      &storage->_attr_dict, &error) < 0) {
+		      &storage->_shared_attr_dict, &error) < 0) {
 		mail_storage_set_critical(storage,
 			"mail_attribute_dict: dict_init(%s) failed: %s",
 			storage->set->mail_attribute_dict, error);
-		storage->attr_dict_failed = TRUE;
+		storage->shared_attr_dict_failed = TRUE;
 		return -1;
 	}
-	*dict_r = storage->_attr_dict;
+	*dict_r = storage->_shared_attr_dict;
 	return 0;
 }
 
@@ -75,7 +155,7 @@
 	struct dict *dict;
 	const char *mailbox_prefix;
 
-	if (index_storage_get_dict(box, &dict, &mailbox_prefix) < 0)
+	if (index_storage_get_dict(box, type, &dict, &mailbox_prefix) < 0)
 		return -1;
 
 	T_BEGIN {
@@ -101,7 +181,7 @@
 	const char *mailbox_prefix;
 	int ret;
 
-	if (index_storage_get_dict(box, &dict, &mailbox_prefix) < 0)
+	if (index_storage_get_dict(box, type, &dict, &mailbox_prefix) < 0)
 		return -1;
 
 	ret = dict_lookup(dict, pool_datastack_create(),
@@ -126,7 +206,7 @@
 
 	iter = i_new(struct index_storage_attribute_iter, 1);
 	iter->iter.box = box;
-	if (index_storage_get_dict(box, &dict, &mailbox_prefix) < 0) {
+	if (index_storage_get_dict(box, type, &dict, &mailbox_prefix) < 0) {
 		if (mailbox_get_last_mail_error(box) == MAIL_ERROR_NOTPOSSIBLE)
 			iter->dict_disabled = TRUE;
 	} else {
diff -r a87edad22199 -r 4c84efce3a94 src/lib-storage/index/index-storage.c
--- a/src/lib-storage/index/index-storage.c	Mon Oct 29 15:17:17 2012 +0200
+++ b/src/lib-storage/index/index-storage.c	Mon Oct 29 15:18:34 2012 +0200
@@ -807,8 +807,8 @@
 
 void index_storage_destroy(struct mail_storage *storage)
 {
-	if (storage->_attr_dict != NULL) {
-		(void)dict_wait(storage->_attr_dict);
-		dict_deinit(&storage->_attr_dict);
+	if (storage->_shared_attr_dict != NULL) {
+		(void)dict_wait(storage->_shared_attr_dict);
+		dict_deinit(&storage->_shared_attr_dict);
 	}
 }
diff -r a87edad22199 -r 4c84efce3a94 src/lib-storage/mail-storage-private.h
--- a/src/lib-storage/mail-storage-private.h	Mon Oct 29 15:17:17 2012 +0200
+++ b/src/lib-storage/mail-storage-private.h	Mon Oct 29 15:18:34 2012 +0200
@@ -108,14 +108,15 @@
 	void *callback_context;
 
 	struct mail_binary_cache binary_cache;
-	/* Filled lazily by mailbox_attribute_*() */
-	struct dict *_attr_dict;
+	/* Filled lazily by mailbox_attribute_*() when accessing shared
+	   attributes. */
+	struct dict *_shared_attr_dict;
 
 	/* Module-specific contexts. See mail_storage_module_id. */
 	ARRAY(union mail_storage_module_context *) module_contexts;
 
-	/* Failed to create attribute dict, don't try again */
-	unsigned int attr_dict_failed:1;
+	/* Failed to create shared attribute dict, don't try again */
+	unsigned int shared_attr_dict_failed:1;
 };
 
 struct mail_attachment_part {
diff -r a87edad22199 -r 4c84efce3a94 src/lib-storage/mail-user.c
--- a/src/lib-storage/mail-user.c	Mon Oct 29 15:17:17 2012 +0200
+++ b/src/lib-storage/mail-user.c	Mon Oct 29 15:18:34 2012 +0200
@@ -14,6 +14,7 @@
 #include "auth-master.h"
 #include "master-service.h"
 #include "mountpoint-list.h"
+#include "dict.h"
 #include "mail-storage-settings.h"
 #include "mail-storage-private.h"
 #include "mail-storage-service.h"
@@ -28,6 +29,10 @@
 
 static void mail_user_deinit_base(struct mail_user *user)
 {
+	if (user->_attr_dict != NULL) {
+		(void)dict_wait(user->_attr_dict);
+		dict_deinit(&user->_attr_dict);
+	}
 	mail_namespaces_deinit(&user->namespaces);
 	if (user->mountpoints != NULL)
 		mountpoint_list_deinit(&user->mountpoints);
diff -r a87edad22199 -r 4c84efce3a94 src/lib-storage/mail-user.h
--- a/src/lib-storage/mail-user.h	Mon Oct 29 15:17:17 2012 +0200
+++ b/src/lib-storage/mail-user.h	Mon Oct 29 15:18:34 2012 +0200
@@ -40,6 +40,8 @@
 
 	struct mountpoint_list *mountpoints;
 	normalizer_func_t *default_normalizer;
+	/* Filled lazily by mailbox_attribute_*() when accessing attributes. */
+	struct dict *_attr_dict;
 
 	/* Module-specific contexts. See mail_storage_module_id. */
 	ARRAY(union mail_user_module_context *) module_contexts;
@@ -64,6 +66,8 @@
 	unsigned int fuzzy_search:1;
 	/* We're running dsync */
 	unsigned int dsyncing:1;
+	/* Failed to create attribute dict, don't try again */
+	unsigned int attr_dict_failed:1;
 };
 
 struct mail_user_module_register {


More information about the dovecot-cvs mailing list