dovecot-2.2: quota: Quota recalculation didn't include INBOX in ...

dovecot at dovecot.org dovecot at dovecot.org
Tue Sep 16 17:59:58 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/2baf1377f57a
changeset: 17820:2baf1377f57a
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Sep 16 20:59:48 2014 +0300
description:
quota: Quota recalculation didn't include INBOX in some configurations.
If one inbox=yes and another inbox=no namespace shared the same mail
location, and the inbox=no namespace was first, only it was used to list all
mailboxes.

diffstat:

 src/plugins/quota/quota-private.h |   1 +
 src/plugins/quota/quota.c         |  57 +++++++++++++++++++++++++++++---------
 2 files changed, 44 insertions(+), 14 deletions(-)

diffs (93 lines):

diff -r 8a969c11e1af -r 2baf1377f57a src/plugins/quota/quota-private.h
--- a/src/plugins/quota/quota-private.h	Tue Sep 16 20:29:04 2014 +0300
+++ b/src/plugins/quota/quota-private.h	Tue Sep 16 20:59:48 2014 +0300
@@ -15,6 +15,7 @@
 
 	ARRAY(struct quota_root *) roots;
 	ARRAY(struct mail_namespace *) namespaces;
+	struct mail_namespace *unwanted_ns;
 };
 
 struct quota_settings {
diff -r 8a969c11e1af -r 2baf1377f57a src/plugins/quota/quota.c
--- a/src/plugins/quota/quota.c	Tue Sep 16 20:29:04 2014 +0300
+++ b/src/plugins/quota/quota.c	Tue Sep 16 20:59:48 2014 +0300
@@ -418,28 +418,55 @@
 	return enabled ? 1 : 0;
 }
 
+static bool
+quota_is_duplicate_namespace(struct quota *quota, struct mail_namespace *ns)
+{
+	struct mail_namespace *const *namespaces;
+	unsigned int i, count;
+	const char *path, *path2;
+
+	if (!mailbox_list_get_root_path(ns->list,
+					MAILBOX_LIST_PATH_TYPE_MAILBOX, &path))
+		return TRUE;
+
+	namespaces = array_get(&quota->namespaces, &count);
+	for (i = 0; i < count; i++) {
+		if (mailbox_list_get_root_path(namespaces[i]->list,
+				MAILBOX_LIST_PATH_TYPE_MAILBOX, &path2) &&
+		    strcmp(path, path2) == 0) {
+			/* duplicate path */
+			if ((ns->flags & NAMESPACE_FLAG_INBOX_USER) == 0)
+				return TRUE;
+
+			/* this is inbox=yes namespace, but the earlier one
+			   that had the same location was inbox=no. we need to
+			   include the INBOX also in quota calculations, so we
+			   can't just ignore this namespace. but since we've
+			   already called backend's namespace_added(), we can't
+			   just remove it either. so just mark the old one as
+			   unwanted namespace.
+
+			   an alternative would be to do a bit larger change so
+			   namespaces wouldn't be added until
+			   mail_namespaces_created() hook is called */
+			i_assert(quota->unwanted_ns == NULL);
+			quota->unwanted_ns = namespaces[i];
+			return FALSE;
+		}
+	}
+	return FALSE;
+}
+
 void quota_add_user_namespace(struct quota *quota, struct mail_namespace *ns)
 {
 	struct quota_root *const *roots;
-	struct mail_namespace *const *namespaces;
 	struct quota_backend **backends;
-	const char *path, *path2;
 	unsigned int i, j, count;
 
 	/* first check if there already exists a namespace with the exact same
 	   path. we don't want to count them twice. */
-	if (mailbox_list_get_root_path(ns->list, MAILBOX_LIST_PATH_TYPE_MAILBOX,
-				       &path)) {
-		namespaces = array_get(&quota->namespaces, &count);
-		for (i = 0; i < count; i++) {
-			if (mailbox_list_get_root_path(namespaces[i]->list,
-				MAILBOX_LIST_PATH_TYPE_MAILBOX, &path2) &&
-			    strcmp(path, path2) == 0) {
-				/* duplicate */
-				return;
-			}
-		}
-	}
+	if (quota_is_duplicate_namespace(quota, ns))
+		return;
 
 	array_append(&quota->namespaces, &ns, 1);
 
@@ -507,6 +534,8 @@
 	if (mailbox_list_get_storage(&list, "", &storage) == 0 &&
 	    (storage->class_flags & MAIL_STORAGE_CLASS_FLAG_NOQUOTA) != 0)
 		return FALSE;
+	if (root->quota->unwanted_ns == ns)
+		return FALSE;
 
 	if (root->ns_prefix != NULL) {
 		if (root->ns != ns)


More information about the dovecot-cvs mailing list