]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
quota: Move namespaces list to quota_root
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 19 Aug 2024 09:29:56 +0000 (12:29 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Fri, 17 Jan 2025 08:40:00 +0000 (10:40 +0200)
It makes more sense in there.

src/plugins/quota/quota-count.c
src/plugins/quota/quota-maildir.c
src/plugins/quota/quota-private.h
src/plugins/quota/quota.c

index 7aa1fb31f7509ccd750db0a2fa8fc4a804a0ac18..507d19cbf38ce13b42c98f96da6443e5a38d0eea 100644 (file)
@@ -125,7 +125,7 @@ quota_mailbox_iter_next(struct quota_mailbox_iter *iter)
        unsigned int count;
 
        if (iter->iter == NULL) {
-               namespaces = array_get(&iter->root->quota->namespaces, &count);
+               namespaces = array_get(&iter->root->namespaces, &count);
                do {
                        if (iter->ns_idx >= count)
                                return NULL;
index 75d79070cffae3d7c907add260000cb3729e2f81..db00d817309ddc0ecb6d55e80bd17e2806972053 100644 (file)
@@ -376,7 +376,7 @@ static int maildirsize_recalculate(struct maildir_quota_root *root,
        maildirsize_recalculate_init(root);
 
        /* count mails from all namespaces */
-       namespaces = array_get(&root->root.quota->namespaces, &count);
+       namespaces = array_get(&root->root.namespaces, &count);
        for (i = 0; i < count; i++) {
                if (!quota_root_is_namespace_visible(&root->root, namespaces[i]))
                        continue;
index 34b1f8ce12544c68b36c285e418c699b099bfb1b..98ca47df2fc50903ee6355a3014871a2939b7505 100644 (file)
@@ -16,8 +16,6 @@ struct quota {
        struct event *event;
 
        ARRAY(struct quota_root *) roots;
-       ARRAY(struct mail_namespace *) namespaces;
-       struct mail_namespace *unwanted_ns;
 
        enum quota_alloc_result (*test_alloc)(
                struct quota_transaction_context *ctx, uoff_t size,
@@ -115,6 +113,9 @@ struct quota_root {
           ns=NULL, so when checking if quota root applies only to a specific
           namespace use the ns_prefix!=NULL check. */
        const char *ns_prefix;
+       /* All namespaces using this quota root */
+       ARRAY(struct mail_namespace *) namespaces;
+       struct mail_namespace *unwanted_ns;
 
        /* initially the same as set->default_rule.*_limit, but some backends
           may change these by reading the limits elsewhere (e.g. imapc,
index 1337b2b08fba62a173a31404119ebb409e638a97..0ca5ea51a1a96466245ade483267815f07cab244 100644 (file)
@@ -353,6 +353,7 @@ quota_root_init(struct quota_root_legacy_settings *root_set, struct quota *quota
        root->backend = *root_set->backend;
        root->bytes_limit = root_set->default_rule.bytes_limit;
        root->count_limit = root_set->default_rule.count_limit;
+       p_array_init(&root->namespaces, root->pool, 4);
 
        array_create(&root->quota_module_contexts, root->pool,
                     sizeof(void *), 10);
@@ -397,7 +398,6 @@ int quota_init(struct quota_legacy_settings *quota_set, struct mail_user *user,
        i_array_init(&quota->roots, 8);
 
        root_sets = array_get(&quota_set->root_sets, &count);
-       i_array_init(&quota->namespaces, count);
        for (i = 0; i < count; i++) {
                ret = quota_root_init(root_sets[i], quota, &root, &error);
                if (ret < 0) {
@@ -433,7 +433,6 @@ void quota_deinit(struct quota **_quota)
        *_quota = NULL;
 
        array_free(&quota->roots);
-       array_free(&quota->namespaces);
        event_unref(&quota->event);
        i_free(quota);
 }
@@ -484,7 +483,7 @@ quota_root_get_rule_limits(struct quota_root *root, struct mailbox *box,
 }
 
 static bool
-quota_is_duplicate_namespace(struct quota *quota, struct mail_namespace *ns)
+quota_is_duplicate_namespace(struct quota_root *root, struct mail_namespace *ns)
 {
        struct mail_namespace *const *namespaces;
        unsigned int i, count;
@@ -494,7 +493,7 @@ quota_is_duplicate_namespace(struct quota *quota, struct mail_namespace *ns)
                                        MAILBOX_LIST_PATH_TYPE_MAILBOX, &path))
                path = NULL;
 
-       namespaces = array_get(&quota->namespaces, &count);
+       namespaces = array_get(&root->namespaces, &count);
        for (i = 0; i < count; i++) {
                /* Count namespace aliases only once. Don't rely only on
                   non-empty alias_for, because the alias might have been
@@ -524,8 +523,8 @@ quota_is_duplicate_namespace(struct quota *quota, struct mail_namespace *ns)
                           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];
+                       i_assert(root->unwanted_ns == NULL);
+                       root->unwanted_ns = namespaces[i];
                        return FALSE;
                }
        }
@@ -534,38 +533,25 @@ quota_is_duplicate_namespace(struct quota *quota, struct mail_namespace *ns)
 
 void quota_add_user_namespace(struct quota *quota, struct mail_namespace *ns)
 {
-       struct quota_root *const *roots;
-       struct quota_backend **backends;
-       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 (quota_is_duplicate_namespace(quota, ns))
-               return;
+       struct quota_root *root;
 
-       array_push_back(&quota->namespaces, &ns);
+       array_foreach_elem(&quota->roots, root) {
+               /* first check if there already exists a namespace with the
+                  exact same path. we don't want to count them twice. */
+               if (quota_is_duplicate_namespace(root, ns))
+                       continue;
 
-       roots = array_get(&quota->roots, &count);
-       /* @UNSAFE: get different backends into one array */
-       backends = t_new(struct quota_backend *, count + 1);
-       for (i = 0; i < count; i++) {
-               for (j = 0; backends[j] != NULL; j++) {
-                       if (backends[j]->name == roots[i]->backend.name)
-                               break;
-               }
-               if (backends[j] == NULL)
-                       backends[j] = &roots[i]->backend;
-       }
+               array_push_back(&root->namespaces, &ns);
 
-       for (i = 0; backends[i] != NULL; i++) {
-               if (backends[i]->v.namespace_added != NULL)
-                       backends[i]->v.namespace_added(quota, ns);
+               if (root->backend.v.namespace_added != NULL)
+                       root->backend.v.namespace_added(quota, ns);
        }
 }
 
 void quota_remove_user_namespace(struct mail_namespace *ns)
 {
        struct quota *quota;
+       struct quota_root *root;
        struct mail_namespace *const *namespaces;
        unsigned int i, count;
 
@@ -577,11 +563,13 @@ void quota_remove_user_namespace(struct mail_namespace *ns)
                return;
        }
 
-       namespaces = array_get(&quota->namespaces, &count);
-       for (i = 0; i < count; i++) {
-               if (namespaces[i] == ns) {
-                       array_delete(&quota->namespaces, i, 1);
-                       break;
+       array_foreach_elem(&quota->roots, root) {
+               namespaces = array_get(&root->namespaces, &count);
+               for (i = 0; i < count; i++) {
+                       if (namespaces[i] == ns) {
+                               array_delete(&root->namespaces, i, 1);
+                               break;
+                       }
                }
        }
 }
@@ -620,7 +608,7 @@ bool quota_root_is_namespace_visible(struct quota_root *root,
        if (mailbox_list_get_storage(&list, &vname, 0, &storage) == 0 &&
            (storage->class_flags & MAIL_STORAGE_CLASS_FLAG_NOQUOTA) != 0)
                return FALSE;
-       if (root->quota->unwanted_ns == ns)
+       if (root->unwanted_ns == ns)
                return FALSE;
 
        if (root->ns_prefix != NULL) {