]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
quota: Add error_result_r parameter to quota_count()
authorMartti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
Thu, 2 Nov 2017 12:02:15 +0000 (14:02 +0200)
committerTimo Sirainen <tss@dovecot.fi>
Thu, 9 Nov 2017 10:52:11 +0000 (12:52 +0200)
src/plugins/quota/quota-count.c
src/plugins/quota/quota-dict.c
src/plugins/quota/quota-private.h

index 429dee6654387ffdd8e8576a2b653da43f08de5c..46d468a2d4b7bd3fe6c18278633324de41dcff18 100644 (file)
@@ -26,6 +26,7 @@ extern struct quota_backend quota_backend_count;
 static int
 quota_count_mailbox(struct quota_root *root, struct mail_namespace *ns,
                    const char *vname, uint64_t *bytes, uint64_t *count,
+                   enum quota_get_result *error_result_r,
                    const char **error_r)
 {
        struct quota_rule *rule;
@@ -57,14 +58,14 @@ quota_count_mailbox(struct quota_root *root, struct mail_namespace *ns,
                        *error_r = t_strdup_printf(
                                "Couldn't get size of mailbox %s: %s",
                                vname, errstr);
+                       *error_result_r = QUOTA_GET_RESULT_INTERNAL_ERROR;
                        ret = -1;
                } else if (error == MAIL_ERROR_INUSE) {
                        /* started on background. don't log an error. */
-                       /* FIXME: Should not log an error, will be fixed with
-                        *        upcoming enum addition. */
                        *error_r = t_strdup_printf(
-                               "%s busy with background quota calculation",
-                               vname);
+                               "Ongoing quota calculation blocked getting size of %s: %s",
+                               vname, errstr);
+                       *error_result_r = QUOTA_GET_RESULT_BACKGROUND_CALC;
                        ret = -1;
                } else {
                        /* non-temporary error, e.g. ACLs denied access. */
@@ -165,7 +166,7 @@ quota_mailbox_iter_next(struct quota_mailbox_iter *iter)
 }
 
 int quota_count(struct quota_root *root, uint64_t *bytes_r, uint64_t *count_r,
-               const char **error_r)
+               enum quota_get_result *error_result_r, const char **error_r)
 {
        struct quota_mailbox_iter *iter;
        const struct mailbox_info *info;
@@ -180,13 +181,16 @@ int quota_count(struct quota_root *root, uint64_t *bytes_r, uint64_t *count_r,
        iter = quota_mailbox_iter_begin(root);
        while ((info = quota_mailbox_iter_next(iter)) != NULL) {
                if (quota_count_mailbox(root, info->ns, info->vname,
-                                       bytes_r, count_r, &error1) < 0) {
+                                       bytes_r, count_r, error_result_r,
+                                       &error1) < 0) {
                        ret = -1;
                        break;
                }
        }
-       if (quota_mailbox_iter_deinit(&iter, &error2) < 0)
+       if (quota_mailbox_iter_deinit(&iter, &error2) < 0) {
+               *error_result_r = QUOTA_GET_RESULT_INTERNAL_ERROR;
                ret = -1;
+       }
        if (ret < 0) {
                const char *separator =
                        *error1 != '\0' && *error2 != '\0' ? " and " : "";
@@ -198,9 +202,10 @@ int quota_count(struct quota_root *root, uint64_t *bytes_r, uint64_t *count_r,
        return ret;
 }
 
-static int quota_count_cached(struct count_quota_root *root,
-                             uint64_t *bytes_r, uint64_t *count_r,
-                             const char **error_r)
+static enum quota_get_result
+quota_count_cached(struct count_quota_root *root,
+                  uint64_t *bytes_r, uint64_t *count_r,
+                  const char **error_r)
 {
        int ret;
 
@@ -209,15 +214,19 @@ static int quota_count_cached(struct count_quota_root *root,
            ioloop_timeval.tv_sec != 0) {
                *bytes_r = root->cached_bytes;
                *count_r = root->cached_count;
-               return 1;
+               return QUOTA_GET_RESULT_LIMITED;
        }
-       ret = quota_count(&root->root, bytes_r, count_r, error_r);
-       if (ret > 0) {
+
+       enum quota_get_result error_res;
+       ret = quota_count(&root->root, bytes_r, count_r, &error_res, error_r);
+       if (ret < 0) {
+               return error_res;
+       } else if (ret > 0) {
                root->cache_timeval = ioloop_timeval;
                root->cached_bytes = *bytes_r;
                root->cached_count = *count_r;
        }
-       return ret < 0 ? -1 : 0;
+       return QUOTA_GET_RESULT_LIMITED;
 }
 
 static struct quota_root *count_quota_alloc(void)
@@ -261,11 +270,13 @@ count_quota_get_resource(struct quota_root *_root,
        struct count_quota_root *root = (struct count_quota_root *)_root;
        uint64_t bytes, count;
        const char *error;
+       enum quota_get_result ret;
 
-       if (quota_count_cached(root, &bytes, &count, &error) < 0) {
+       ret = quota_count_cached(root, &bytes, &count, &error);
+       if (ret <= QUOTA_GET_RESULT_INTERNAL_ERROR) {
                *error_r = t_strdup_printf(
                        "quota-count: Failed to get %s: %s", name, error);
-               return QUOTA_GET_RESULT_INTERNAL_ERROR;
+               return ret;
        }
 
        if (strcmp(name, QUOTA_NAME_STORAGE_BYTES) == 0)
index 4119ffce79eef71c2ced57eb42b7eea8c0532c3e..78db037fdd2c5a9c7a35bd2d99019424f05247dc 100644 (file)
@@ -105,7 +105,7 @@ dict_quota_root_get_resources(struct quota_root *root ATTR_UNUSED)
        return resources;
 }
 
-static int
+static enum quota_get_result
 dict_quota_count(struct dict_quota_root *root,
                 bool want_bytes, uint64_t *value_r,
                 const char **error_r)
@@ -113,11 +113,12 @@ dict_quota_count(struct dict_quota_root *root,
        struct dict_transaction_context *dt;
        uint64_t bytes, count;
        const char *error;
+       enum quota_get_result error_res;
 
-       if (quota_count(&root->root, &bytes, &count, &error) < 0) {
+       if (quota_count(&root->root, &bytes, &count, &error_res, &error) < 0) {
                *error_r = t_strdup_printf(
                        "quota-dict count failed: %s", error);
-               return -1;
+               return error_res;
        }
 
        dt = dict_transaction_begin(root->dict);
@@ -140,7 +141,7 @@ dict_quota_count(struct dict_quota_root *root,
 
        dict_transaction_commit_async(&dt, NULL, NULL);
        *value_r = want_bytes ? bytes : count;
-       return 1;
+       return QUOTA_GET_RESULT_LIMITED;
 }
 
 static enum quota_get_result
@@ -179,8 +180,8 @@ dict_quota_get_resource(struct quota_root *_root,
                tmp = -1;
        if (tmp >= 0)
                *value_r = tmp;
-       else if (dict_quota_count(root, want_bytes, value_r, error_r) < 0)
-               return QUOTA_GET_RESULT_INTERNAL_ERROR;
+       else
+               return dict_quota_count(root, want_bytes, value_r, error_r);
        return QUOTA_GET_RESULT_LIMITED;
 }
 
@@ -190,7 +191,8 @@ static void dict_quota_recalc_timeout(struct dict_quota_root *root)
        const char *error;
 
        timeout_remove(&root->to_update);
-       if (dict_quota_count(root, TRUE, &value, &error) < 0)
+       if (dict_quota_count(root, TRUE, &value, &error)
+           <= QUOTA_GET_RESULT_INTERNAL_ERROR)
                i_error("%s", error);
 }
 
@@ -219,7 +221,8 @@ dict_quota_update(struct quota_root *_root,
        uint64_t value;
 
        if (ctx->recalculate != QUOTA_RECALCULATE_DONT) {
-               if (dict_quota_count(root, TRUE, &value, error_r) < 0)
+               if (dict_quota_count(root, TRUE, &value, error_r)
+                   <= QUOTA_GET_RESULT_INTERNAL_ERROR)
                        return -1;
        } else {
                dt = dict_transaction_begin(root->dict);
index 179962184a5fc1ba4abfdfd1a21cffe3cb82284c..af2ccb65d8ecf66be157bf68e6e46ddbf011ca0c 100644 (file)
@@ -206,7 +206,7 @@ void quota_root_recalculate_relative_rules(struct quota_root_settings *root_set,
 /* Returns 1 if values were returned successfully, 0 if we're recursing into
    the same function, -1 if error. */
 int quota_count(struct quota_root *root, uint64_t *bytes_r, uint64_t *count_r,
-               const char **error_r);
+               enum quota_get_result *error_result_r, const char **error_r);
 
 int quota_root_parse_grace(struct quota_root_settings *root_set,
                           const char *value, const char **error_r);