From: Aki Tuomi Date: Tue, 8 Mar 2022 10:03:43 +0000 (+0200) Subject: quota: Remove quota-dict X-Git-Tag: 2.4.0~4192 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4ea219f8444cf54f00fe7a2687be815c1224a6c6;p=thirdparty%2Fdovecot%2Fcore.git quota: Remove quota-dict --- diff --git a/doc/example-config/conf.d/90-quota.conf b/doc/example-config/conf.d/90-quota.conf index 3308c05950..dd09e6bb6a 100644 --- a/doc/example-config/conf.d/90-quota.conf +++ b/doc/example-config/conf.d/90-quota.conf @@ -62,22 +62,20 @@ plugin { # Multiple backends are supported: # dirsize: Find and sum all the files found from mail directory. # Extremely SLOW with Maildir. It'll eat your CPU and disk I/O. -# dict: Keep quota stored in dictionary (eg. SQL) # maildir: Maildir++ quota # fs: Read-only support for filesystem quota plugin { #quota = dirsize:User quota #quota = maildir:User quota - #quota = dict:User quota::proxy::quota #quota = fs:User quota } # Multiple quota roots are also possible, for example this gives each user # their own 100MB quota and one shared 1GB quota within the domain: plugin { - #quota = dict:user::proxy::quota - #quota2 = dict:domain:%d:proxy::quota_domain + #quota = count:user + #quota2 = count:domain:%d #quota_rule = *:storage=102400 #quota2_rule = *:storage=1048576 } diff --git a/doc/man/doveconf.1.in b/doc/man/doveconf.1.in index 060f0e0b78..388ac67346 100644 --- a/doc/man/doveconf.1.in +++ b/doc/man/doveconf.1.in @@ -198,7 +198,7 @@ This example demonstrates how to dump a whole configuration section. doveconf dict .ft P dict { - quota = pgsql:@pkgsysconfdir@/dovecot\-dict\-sql.conf.ext + quota_clone = pgsql:@pkgsysconfdir@/dovecot\-dict\-sql.conf.ext } .fi .PP @@ -206,9 +206,9 @@ Or how to dump only the quota dict: .sp .nf .ft B -doveconf dict/quota +doveconf dict/quota_clone .ft P -dict/quota = pgsql:@pkgsysconfdir@/dovecot\-dict\-sql.conf.ext +dict/quota_clone = pgsql:@pkgsysconfdir@/dovecot\-dict\-sql.conf.ext .fi .\"------------------------------------------------------------------------ @INCLUDE:reporting-bugs@ diff --git a/src/plugins/quota/Makefile.am b/src/plugins/quota/Makefile.am index 6d4aada29f..ba5fc46a87 100644 --- a/src/plugins/quota/Makefile.am +++ b/src/plugins/quota/Makefile.am @@ -35,7 +35,6 @@ quota_dist_sources = \ quota.c \ quota-count.c \ quota-fs.c \ - quota-dict.c \ quota-dirsize.c \ quota-imapc.c \ quota-maildir.c \ @@ -47,7 +46,6 @@ quota_common_objects = \ quota.lo \ quota-count.lo \ quota-fs.lo \ - quota-dict.lo \ quota-dirsize.lo \ quota-imapc.lo \ quota-maildir.lo \ diff --git a/src/plugins/quota/quota-dict.c b/src/plugins/quota/quota-dict.c deleted file mode 100644 index 02e444a345..0000000000 --- a/src/plugins/quota/quota-dict.c +++ /dev/null @@ -1,269 +0,0 @@ -/* Copyright (c) 2005-2018 Dovecot authors, see the included COPYING file */ - -#include "lib.h" -#include "ioloop.h" -#include "str.h" -#include "dict.h" -#include "mail-user.h" -#include "mail-namespace.h" -#include "quota-private.h" - - -#define DICT_QUOTA_CURRENT_PATH DICT_PATH_PRIVATE"quota/" -#define DICT_QUOTA_CURRENT_BYTES_PATH DICT_QUOTA_CURRENT_PATH"storage" -#define DICT_QUOTA_CURRENT_COUNT_PATH DICT_QUOTA_CURRENT_PATH"messages" - -struct dict_quota_root { - struct quota_root root; - struct dict *dict; - struct timeout *to_update; - bool disable_unset; -}; - -extern struct quota_backend quota_backend_dict; - -static struct quota_root *dict_quota_alloc(void) -{ - struct dict_quota_root *root; - - root = i_new(struct dict_quota_root, 1); - return &root->root; -} - -static void handle_nounset_param(struct quota_root *_root, const char *param_value ATTR_UNUSED) -{ - ((struct dict_quota_root *)_root)->disable_unset = TRUE; -} - -static int dict_quota_init(struct quota_root *_root, const char *args, - const char **error_r) -{ - struct dict_quota_root *root = (struct dict_quota_root *)_root; - struct dict_settings set; - const char *username, *p, *error; - - event_set_append_log_prefix(_root->backend.event, "quota-dict: "); - - const struct quota_param_parser dict_params[] = { - {.param_name = "no-unset", .param_handler = handle_nounset_param}, - quota_param_hidden, quota_param_ignoreunlimited, quota_param_noenforcing, quota_param_ns, - {.param_name = NULL} - }; - - p = args == NULL ? NULL : strchr(args, ':'); - if (p == NULL) { - *error_r = "URI missing from parameters"; - return -1; - } - - username = t_strdup_until(args, p); - args = p+1; - - if (quota_parse_parameters(_root, &args, error_r, dict_params, FALSE) < 0) - i_unreached(); - - if (*username == '\0') - username = _root->quota->user->username; - - e_debug(_root->backend.event, "user=%s, uri=%s, noenforcing=%d", - username, args, _root->no_enforcing ? 1 : 0); - - /* FIXME: we should use 64bit integer as datatype instead but before - it can actually be used don't bother */ - i_zero(&set); - set.base_dir = _root->quota->user->set->base_dir; - set.event_parent = _root->quota->user->event; - if (dict_init(args, &set, &root->dict, &error) < 0) { - *error_r = t_strdup_printf("dict_init(%s) failed: %s", args, error); - return -1; - } - return 0; -} - -static void dict_quota_deinit(struct quota_root *_root) -{ - struct dict_quota_root *root = (struct dict_quota_root *)_root; - - i_assert(root->to_update == NULL); - - if (root->dict != NULL) { - dict_wait(root->dict); - dict_deinit(&root->dict); - } - i_free(root); -} - -static const char *const * -dict_quota_root_get_resources(struct quota_root *root ATTR_UNUSED) -{ - static const char *resources[] = { - QUOTA_NAME_STORAGE_KILOBYTES, QUOTA_NAME_MESSAGES, NULL - }; - - return resources; -} - -static enum quota_get_result -dict_quota_count(struct dict_quota_root *root, - bool want_bytes, uint64_t *value_r, - const char **error_r) -{ - struct dict_transaction_context *dt; - struct event_reason *reason; - uint64_t bytes, count; - enum quota_get_result error_res; - const struct dict_op_settings *set; - - reason = event_reason_begin("quota:recalculate"); - int ret = quota_count(&root->root, &bytes, &count, &error_res, error_r); - event_reason_end(&reason); - if (ret < 0) - return error_res; - - set = mail_user_get_dict_op_settings(root->root.quota->user); - dt = dict_transaction_begin(root->dict, set); - /* these unsets are mainly necessary for pgsql, because its - trigger otherwise increases quota without deleting it. - but some people with other databases want to store the - quota usage among other data in the same row, which - shouldn't be deleted. */ - if (!root->disable_unset) { - dict_unset(dt, DICT_QUOTA_CURRENT_BYTES_PATH); - dict_unset(dt, DICT_QUOTA_CURRENT_COUNT_PATH); - } - dict_set(dt, DICT_QUOTA_CURRENT_BYTES_PATH, dec2str(bytes)); - dict_set(dt, DICT_QUOTA_CURRENT_COUNT_PATH, dec2str(count)); - - e_debug(root->root.backend.event, "Quota recalculated: " - "count=%"PRIu64" bytes=%"PRIu64, count, bytes); - - dict_transaction_commit_async_nocallback(&dt); - *value_r = want_bytes ? bytes : count; - return QUOTA_GET_RESULT_LIMITED; -} - -static enum quota_get_result -dict_quota_get_resource(struct quota_root *_root, - const char *name, uint64_t *value_r, - const char **error_r) -{ - struct dict_quota_root *root = (struct dict_quota_root *)_root; - bool want_bytes; - int ret; - const struct dict_op_settings *set; - - if (strcmp(name, QUOTA_NAME_STORAGE_BYTES) == 0) - want_bytes = TRUE; - else if (strcmp(name, QUOTA_NAME_MESSAGES) == 0) - want_bytes = FALSE; - else { - *error_r = QUOTA_UNKNOWN_RESOURCE_ERROR_STRING; - return QUOTA_GET_RESULT_UNKNOWN_RESOURCE; - } - - set = mail_user_get_dict_op_settings(root->root.quota->user); - const char *key, *value, *error; - key = want_bytes ? DICT_QUOTA_CURRENT_BYTES_PATH : - DICT_QUOTA_CURRENT_COUNT_PATH; - ret = dict_lookup(root->dict, set, unsafe_data_stack_pool, - key, &value, &error); - if (ret < 0) { - *error_r = t_strdup_printf( - "dict_lookup(%s) failed: %s", key, error); - *value_r = 0; - return QUOTA_GET_RESULT_INTERNAL_ERROR; - } - - intmax_t tmp; - /* recalculate quota if it's negative or if it wasn't found */ - if (ret == 0 || str_to_intmax(value, &tmp) < 0) - tmp = -1; - if (tmp >= 0) - *value_r = tmp; - else - return dict_quota_count(root, want_bytes, value_r, error_r); - return QUOTA_GET_RESULT_LIMITED; -} - -static void dict_quota_recalc_timeout(struct dict_quota_root *root) -{ - uint64_t value; - const char *error; - - timeout_remove(&root->to_update); - if (dict_quota_count(root, TRUE, &value, &error) - <= QUOTA_GET_RESULT_INTERNAL_ERROR) - e_error(root->root.backend.event, - "Recalculation failed: %s", error); -} - -static void dict_quota_update_callback(const struct dict_commit_result *result, - struct dict_quota_root *root) -{ - if (result->ret == 0) { - /* row doesn't exist, need to recalculate it */ - if (root->to_update == NULL) - root->to_update = timeout_add_short(0, dict_quota_recalc_timeout, root); - } else if (result->ret < 0) { - e_error(root->root.backend.event, - "Quota update failed: %s " - "- Quota is now desynced", result->error); - } -} - -static int -dict_quota_update(struct quota_root *_root, - struct quota_transaction_context *ctx, - const char **error_r) -{ - struct dict_quota_root *root = (struct dict_quota_root *) _root; - struct dict_transaction_context *dt; - uint64_t value; - const struct dict_op_settings *set; - - if (ctx->recalculate != QUOTA_RECALCULATE_DONT) { - if (dict_quota_count(root, TRUE, &value, error_r) - <= QUOTA_GET_RESULT_INTERNAL_ERROR) - return -1; - } else { - set = mail_user_get_dict_op_settings(root->root.quota->user); - dt = dict_transaction_begin(root->dict, set); - if (ctx->bytes_used != 0) { - dict_atomic_inc(dt, DICT_QUOTA_CURRENT_BYTES_PATH, - ctx->bytes_used); - } - if (ctx->count_used != 0) { - dict_atomic_inc(dt, DICT_QUOTA_CURRENT_COUNT_PATH, - ctx->count_used); - } - dict_transaction_no_slowness_warning(dt); - dict_transaction_commit_async(&dt, dict_quota_update_callback, - root); - } - return 0; -} - -static void dict_quota_flush(struct quota_root *_root) -{ - struct dict_quota_root *root = (struct dict_quota_root *)_root; - - dict_wait(root->dict); - if (root->to_update != NULL) { - dict_quota_recalc_timeout(root); - dict_wait(root->dict); - } -} - -struct quota_backend quota_backend_dict = { - .name = "dict", - - .v = { - .alloc = dict_quota_alloc, - .init = dict_quota_init, - .deinit = dict_quota_deinit, - .get_resources = dict_quota_root_get_resources, - .get_resource = dict_quota_get_resource, - .update = dict_quota_update, - .flush = dict_quota_flush, - } -}; diff --git a/src/plugins/quota/quota.c b/src/plugins/quota/quota.c index c972551bbf..845f59a6bb 100644 --- a/src/plugins/quota/quota.c +++ b/src/plugins/quota/quota.c @@ -38,7 +38,6 @@ struct quota_root_iter { unsigned int quota_module_id = 0; extern struct quota_backend quota_backend_count; -extern struct quota_backend quota_backend_dict; extern struct quota_backend quota_backend_dirsize; extern struct quota_backend quota_backend_fs; extern struct quota_backend quota_backend_imapc; @@ -49,7 +48,6 @@ static const struct quota_backend *quota_internal_backends[] = { "a_backend_fs, #endif "a_backend_count, - "a_backend_dict, "a_backend_dirsize, "a_backend_imapc, "a_backend_maildir