dovecot-1.1: Relative (%) limits in quota rules and warnings wor...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Feb 26 16:18:45 EET 2008
details: http://hg.dovecot.org/dovecot-1.1/rev/9e4c26471b19
changeset: 7294:9e4c26471b19
user: Timo Sirainen <tss at iki.fi>
date: Tue Feb 26 16:21:05 2008 +0200
description:
Relative (%) limits in quota rules and warnings work now if the backend
specifies or changes the limits (e.g. Maildir++ maildirsize file)
diffstat:
6 files changed, 150 insertions(+), 100 deletions(-)
src/plugins/quota/quota-dict.c | 2
src/plugins/quota/quota-dirsize.c | 2
src/plugins/quota/quota-fs.c | 37 +++++++-----
src/plugins/quota/quota-maildir.c | 86 +++++++++++++---------------
src/plugins/quota/quota-private.h | 10 +--
src/plugins/quota/quota.c | 113 +++++++++++++++++++++++++------------
diffs (truncated from 513 to 300 lines):
diff -r f78b83bf16b7 -r 9e4c26471b19 src/plugins/quota/quota-dict.c
--- a/src/plugins/quota/quota-dict.c Tue Feb 26 15:11:34 2008 +0200
+++ b/src/plugins/quota/quota-dict.c Tue Feb 26 16:21:05 2008 +0200
@@ -96,7 +96,7 @@ dict_quota_count(struct dict_quota_root
static int
dict_quota_get_resource(struct quota_root *_root, const char *name,
- uint64_t *value_r, uint64_t *limit ATTR_UNUSED)
+ uint64_t *value_r)
{
struct dict_quota_root *root = (struct dict_quota_root *)_root;
bool want_bytes;
diff -r f78b83bf16b7 -r 9e4c26471b19 src/plugins/quota/quota-dirsize.c
--- a/src/plugins/quota/quota-dirsize.c Tue Feb 26 15:11:34 2008 +0200
+++ b/src/plugins/quota/quota-dirsize.c Tue Feb 26 16:21:05 2008 +0200
@@ -180,7 +180,7 @@ get_quota_root_usage(struct quota_root *
static int
dirsize_quota_get_resource(struct quota_root *_root, const char *name,
- uint64_t *value_r, uint64_t *limit ATTR_UNUSED)
+ uint64_t *value_r)
{
int ret;
diff -r f78b83bf16b7 -r 9e4c26471b19 src/plugins/quota/quota-fs.c
--- a/src/plugins/quota/quota-fs.c Tue Feb 26 15:11:34 2008 +0200
+++ b/src/plugins/quota/quota-fs.c Tue Feb 26 16:21:05 2008 +0200
@@ -549,14 +549,14 @@ fs_quota_get_one_resource(struct fs_quot
static int
fs_quota_get_resource(struct quota_root *_root, const char *name,
- uint64_t *value_r, uint64_t *limit_r)
+ uint64_t *value_r)
{
struct fs_quota_root *root = (struct fs_quota_root *)_root;
+ uint64_t limit = 0;
bool bytes;
int ret;
*value_r = 0;
- *limit_r = 0;
if (root->mount == NULL ||
(strcasecmp(name, QUOTA_NAME_STORAGE_BYTES) != 0 &&
@@ -566,22 +566,29 @@ fs_quota_get_resource(struct quota_root
#ifdef HAVE_RQUOTA
if (strcmp(root->mount->type, "nfs") == 0) {
- int ret;
-
T_BEGIN {
- ret = do_rquota(root, bytes, value_r, limit_r);
+ ret = do_rquota(root, bytes, value_r, &limit);
} T_END;
+ } else
+#endif
+ {
+ ret = fs_quota_get_one_resource(root, FALSE, bytes,
+ value_r, &limit);
+ if (ret == 0) {
+ /* fallback to group quota */
+ ret = fs_quota_get_one_resource(root, TRUE, bytes,
+ value_r, &limit);
+ }
+ }
+ if (ret <= 0)
return ret;
- }
-#endif
-
- ret = fs_quota_get_one_resource(root, FALSE, bytes,
- value_r, limit_r);
- if (ret != 0)
- return ret;
-
- /* fallback to group quota */
- return fs_quota_get_one_resource(root, TRUE, bytes, value_r, limit_r);
+
+ /* update limit */
+ if (bytes)
+ _root->default_rule.bytes_limit = limit;
+ else
+ _root->default_rule.count_limit = limit;
+ return 1;
}
static int
diff -r f78b83bf16b7 -r 9e4c26471b19 src/plugins/quota/quota-maildir.c
--- a/src/plugins/quota/quota-maildir.c Tue Feb 26 15:11:34 2008 +0200
+++ b/src/plugins/quota/quota-maildir.c Tue Feb 26 16:21:05 2008 +0200
@@ -23,8 +23,6 @@ struct maildir_quota_root {
struct quota_root root;
const char *maildirsize_path;
- uint64_t message_bytes_limit;
- uint64_t message_count_limit;
uint64_t total_bytes;
uint64_t total_count;
@@ -208,6 +206,7 @@ maildirs_check_have_changed(struct mail_
static int maildirsize_write(struct maildir_quota_root *root, const char *path)
{
+ const struct quota_rule *rule = &root->root.default_rule;
struct dotlock *dotlock;
string_t *str;
int fd;
@@ -229,15 +228,15 @@ static int maildirsize_write(struct mail
}
str = t_str_new(128);
- if (root->message_bytes_limit != (uint64_t)-1) {
+ if (rule->bytes_limit != 0) {
str_printfa(str, "%lluS",
- (unsigned long long)root->message_bytes_limit);
- }
- if (root->message_count_limit != (uint64_t)-1) {
+ (unsigned long long)rule->bytes_limit);
+ }
+ if (rule->count_limit != 0) {
if (str_len(str) > 0)
str_append_c(str, ',');
str_printfa(str, "%lluC",
- (unsigned long long)root->message_count_limit);
+ (unsigned long long)rule->count_limit);
}
str_printfa(str, "\n%llu %llu\n",
(unsigned long long)root->total_bytes,
@@ -352,8 +351,8 @@ maildir_parse_limit(const char *str, uin
char *pos;
bool ret = TRUE;
- *bytes_r = (uint64_t)-1;
- *count_r = (uint64_t)-1;
+ *bytes_r = 0;
+ *count_r = 0;
/* 0 values mean unlimited */
for (limit = t_strsplit(str, ","); *limit != NULL; limit++) {
@@ -382,6 +381,7 @@ static int maildirsize_parse(struct mail
static int maildirsize_parse(struct maildir_quota_root *root,
int fd, const char *const *lines)
{
+ struct quota_rule *rule = &root->root.default_rule;
uint64_t message_bytes_limit, message_count_limit;
long long bytes_diff, total_bytes;
int count_diff, total_count;
@@ -394,15 +394,24 @@ static int maildirsize_parse(struct mail
(void)maildir_parse_limit(lines[0], &message_bytes_limit,
&message_count_limit);
- if (!root->master_message_limits) {
- /* we don't know the limits, use whatever the file says */
- root->message_bytes_limit = message_bytes_limit;
- root->message_count_limit = message_count_limit;
- } else if (root->message_bytes_limit != message_bytes_limit ||
- root->message_count_limit != message_count_limit) {
+ /* truncate too high limits to signed 64bit int range */
+ if (message_bytes_limit >= (1ULL << 63))
+ message_bytes_limit = (1ULL << 63) - 1;
+ if (message_count_limit >= (1ULL << 63))
+ message_count_limit = (1ULL << 63) - 1;
+
+ if (rule->bytes_limit == (int64_t)message_bytes_limit &&
+ rule->count_limit == (int64_t)message_count_limit) {
+ /* limits haven't changed */
+ } else if (root->master_message_limits) {
/* we know the limits and they've changed.
the file must be rewritten. */
return 0;
+ } else {
+ /* we're using limits from the file. */
+ rule->bytes_limit = message_bytes_limit;
+ rule->count_limit = message_count_limit;
+ quota_root_recalculate_relative_rules(&root->root);
}
if (*lines == NULL) {
@@ -425,8 +434,8 @@ static int maildirsize_parse(struct mail
return -1;
}
- if ((uint64_t)total_bytes > root->message_bytes_limit ||
- (uint64_t)total_count > root->message_count_limit) {
+ if (total_bytes > rule->bytes_limit ||
+ total_count > rule->count_limit) {
/* we're over quota. don't trust these values if the file
contains more than the initial summary line, or if the file
is older than 15 minutes. */
@@ -540,26 +549,23 @@ static int maildirsize_read(struct maild
return ret;
}
-static void maildirquota_init_limits(struct maildir_quota_root *root)
-{
+static bool maildirquota_limits_init(struct maildir_quota_root *root)
+{
+ if (root->limits_initialized)
+ return root->maildirsize_path != NULL;
root->limits_initialized = TRUE;
+ /* these limits must be checked before the maildirsize is read the
+ first time. if master limits aren't used, the default rule limits
+ will be zero initially, but they'll be updated after the file is
+ read. */
if (root->root.default_rule.bytes_limit != 0 ||
- root->root.default_rule.count_limit != 0) {
+ root->root.default_rule.count_limit != 0)
root->master_message_limits = TRUE;
- root->message_bytes_limit = root->root.default_rule.bytes_limit;
- root->message_count_limit = root->root.default_rule.count_limit;
- }
-}
-
-static bool maildirquota_limits_init(struct maildir_quota_root *root)
-{
- if (!root->limits_initialized) {
- maildirquota_init_limits(root);
- if (root->maildirsize_path == NULL) {
- i_warning("quota maildir: No maildir storages, "
- "ignoring quota.");
- }
+
+ if (root->maildirsize_path == NULL) {
+ i_warning("quota maildir: No maildir storages, "
+ "ignoring quota.");
}
return root->maildirsize_path != NULL;
}
@@ -575,8 +581,8 @@ static int maildirquota_refresh(struct m
ret = maildirsize_read(root);
} T_END;
if (ret == 0) {
- if (root->message_bytes_limit == (uint64_t)-1 &&
- root->message_count_limit == (uint64_t)-1) {
+ if (root->root.default_rule.bytes_limit == 0 &&
+ root->root.default_rule.count_limit == 0) {
/* no quota */
return 0;
}
@@ -620,8 +626,6 @@ static struct quota_root *maildir_quota_
root = i_new(struct maildir_quota_root, 1);
root->fd = -1;
- root->message_bytes_limit = (uint64_t)-1;
- root->message_count_limit = (uint64_t)-1;
return &root->root;
}
@@ -703,7 +707,7 @@ maildir_quota_root_get_resources(struct
static int
maildir_quota_get_resource(struct quota_root *_root, const char *name,
- uint64_t *value_r, uint64_t *limit_r)
+ uint64_t *value_r)
{
struct maildir_quota_root *root = (struct maildir_quota_root *)_root;
@@ -712,14 +716,8 @@ maildir_quota_get_resource(struct quota_
if (strcmp(name, QUOTA_NAME_STORAGE_BYTES) == 0) {
*value_r = root->total_bytes;
- if (!root->master_message_limits &&
- root->message_bytes_limit != (uint64_t)-1)
- *limit_r = root->message_bytes_limit;
} else if (strcmp(name, QUOTA_NAME_MESSAGES) == 0) {
*value_r = root->total_count;
- if (!root->master_message_limits &&
- root->message_count_limit != (uint64_t)-1)
- *limit_r = root->message_count_limit;
} else
return 0;
return 1;
diff -r f78b83bf16b7 -r 9e4c26471b19 src/plugins/quota/quota-private.h
--- a/src/plugins/quota/quota-private.h Tue Feb 26 15:11:34 2008 +0200
+++ b/src/plugins/quota/quota-private.h Tue Feb 26 16:21:05 2008 +0200
@@ -23,11 +23,12 @@ struct quota_rule {
char *mailbox_name;
int64_t bytes_limit, count_limit;
+ /* relative to default_rule */
+ unsigned int bytes_percent, count_percent;
};
struct quota_warning_rule {
- uint64_t bytes_limit;
- uint64_t count_limit;
+ struct quota_rule rule;
char *command;
};
@@ -45,10 +46,8 @@ struct quota_backend_vfuncs {
struct mail_storage *storage);
const char *const *(*get_resources)(struct quota_root *root);
- /* the limit is set by default, so it shouldn't normally need to
- be changed. */
int (*get_resource)(struct quota_root *root, const char *name,
- uint64_t *value_r, uint64_t *limit);
+ uint64_t *value_r);
More information about the dovecot-cvs
mailing list