From: Martti Rannanjärvi Date: Thu, 2 Nov 2017 12:02:15 +0000 (+0200) Subject: quota: Add error_result_r parameter to quota_count() X-Git-Tag: 2.3.0.rc1~480 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4f52de745cf26ee9dcbde7ca4500d442116226cf;p=thirdparty%2Fdovecot%2Fcore.git quota: Add error_result_r parameter to quota_count() --- diff --git a/src/plugins/quota/quota-count.c b/src/plugins/quota/quota-count.c index 429dee6654..46d468a2d4 100644 --- a/src/plugins/quota/quota-count.c +++ b/src/plugins/quota/quota-count.c @@ -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) diff --git a/src/plugins/quota/quota-dict.c b/src/plugins/quota/quota-dict.c index 4119ffce79..78db037fdd 100644 --- a/src/plugins/quota/quota-dict.c +++ b/src/plugins/quota/quota-dict.c @@ -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); diff --git a/src/plugins/quota/quota-private.h b/src/plugins/quota/quota-private.h index 179962184a..af2ccb65d8 100644 --- a/src/plugins/quota/quota-private.h +++ b/src/plugins/quota/quota-private.h @@ -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);