dovecot: Don't set quota limits to transactions until they're ne...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Jul 16 01:23:21 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/001d25a650df
changeset: 6025:001d25a650df
user: Timo Sirainen <tss at iki.fi>
date: Mon Jul 16 00:28:24 2007 +0300
description:
Don't set quota limits to transactions until they're needed.
diffstat:
3 files changed, 62 insertions(+), 59 deletions(-)
src/plugins/quota/quota-count.c | 6 -
src/plugins/quota/quota-private.h | 2
src/plugins/quota/quota.c | 113 +++++++++++++++++++------------------
diffs (206 lines):
diff -r 6074e9e6059d -r 001d25a650df src/plugins/quota/quota-count.c
--- a/src/plugins/quota/quota-count.c Sun Jul 15 22:30:14 2007 +0300
+++ b/src/plugins/quota/quota-count.c Mon Jul 16 00:28:24 2007 +0300
@@ -77,11 +77,7 @@ int quota_count(struct quota *quota, uin
unsigned int i, count;
int ret = 0;
- i_assert(!quota->counting);
-
*bytes_r = *count_r = 0;
-
- quota->counting = TRUE;
storages = array_get("a->storages, &count);
for (i = 0; i < count; i++) {
@@ -89,7 +85,5 @@ int quota_count(struct quota *quota, uin
if (ret < 0)
break;
}
- quota->counting = FALSE;
-
return ret;
}
diff -r 6074e9e6059d -r 001d25a650df src/plugins/quota/quota-private.h
--- a/src/plugins/quota/quota-private.h Sun Jul 15 22:30:14 2007 +0300
+++ b/src/plugins/quota/quota-private.h Mon Jul 16 00:28:24 2007 +0300
@@ -16,7 +16,6 @@ struct quota {
uoff_t size, bool *too_large_r);
unsigned int debug:1;
- unsigned int counting:1;
};
struct quota_rule {
@@ -81,6 +80,7 @@ struct quota_transaction_context {
struct mail *tmp_mail;
+ unsigned int limits_set:1;
unsigned int failed:1;
unsigned int recalculate:1;
};
diff -r 6074e9e6059d -r 001d25a650df src/plugins/quota/quota.c
--- a/src/plugins/quota/quota.c Sun Jul 15 22:30:14 2007 +0300
+++ b/src/plugins/quota/quota.c Mon Jul 16 00:28:24 2007 +0300
@@ -438,83 +438,87 @@ struct quota_transaction_context *quota_
struct mailbox *box)
{
struct quota_transaction_context *ctx;
- struct quota_root *const *roots;
- const char *mailbox_name;
- unsigned int i, count;
- uint64_t current, limit, left;
- int ret;
-
- mailbox_name = mailbox_get_name(box);
-
+
ctx = i_new(struct quota_transaction_context, 1);
ctx->quota = quota;
ctx->box = box;
ctx->bytes_left = (uint64_t)-1;
ctx->count_left = (uint64_t)-1;
-
- if (quota->counting) {
- /* we got here through quota_count_storage() */
- return ctx;
- }
+ return ctx;
+}
+
+int quota_transaction_commit(struct quota_transaction_context **_ctx)
+{
+ struct quota_transaction_context *ctx = *_ctx;
+ struct quota_root *const *roots;
+ unsigned int i, count;
+ int ret = 0;
+
+ *_ctx = NULL;
+
+ if (ctx->failed)
+ ret = -1;
+ else if (ctx->bytes_used != 0 || ctx->count_used != 0 ||
+ ctx->recalculate) {
+ roots = array_get(&ctx->quota->roots, &count);
+ for (i = 0; i < count; i++) {
+ if (roots[i]->backend.v.update(roots[i], ctx) < 0)
+ ret = -1;
+ }
+ }
+
+ i_free(ctx);
+ return ret;
+}
+
+void quota_transaction_rollback(struct quota_transaction_context **_ctx)
+{
+ struct quota_transaction_context *ctx = *_ctx;
+
+ *_ctx = NULL;
+ i_free(ctx);
+}
+
+static int quota_transaction_set_limits(struct quota_transaction_context *ctx)
+{
+ struct quota_root *const *roots;
+ const char *mailbox_name;
+ unsigned int i, count;
+ uint64_t current, limit, left;
+ int ret;
+
+ ctx->limits_set = TRUE;
+ mailbox_name = mailbox_get_name(ctx->box);
/* find the lowest quota limits from all roots and use them */
- roots = array_get("a->roots, &count);
+ roots = array_get(&ctx->quota->roots, &count);
for (i = 0; i < count; i++) {
ret = quota_get_resource(roots[i], mailbox_name,
QUOTA_NAME_STORAGE_BYTES,
¤t, &limit);
if (ret > 0) {
+ current += ctx->bytes_used;
left = limit < current ? 0 : limit - current;
if (ctx->bytes_left > left)
ctx->bytes_left = left;
} else if (ret < 0) {
ctx->failed = TRUE;
- break;
+ return -1;
}
ret = quota_get_resource(roots[i], mailbox_name,
QUOTA_NAME_MESSAGES, ¤t, &limit);
if (ret > 0) {
+ current += ctx->count_used;
left = limit < current ? 0 : limit - current;
if (ctx->count_left > left)
ctx->count_left = left;
} else if (ret < 0) {
ctx->failed = TRUE;
- break;
- }
- }
- return ctx;
-}
-
-int quota_transaction_commit(struct quota_transaction_context **_ctx)
-{
- struct quota_transaction_context *ctx = *_ctx;
- struct quota_root *const *roots;
- unsigned int i, count;
- int ret = 0;
-
- *_ctx = NULL;
-
- if (ctx->failed)
- ret = -1;
- else {
- roots = array_get(&ctx->quota->roots, &count);
- for (i = 0; i < count; i++) {
- if (roots[i]->backend.v.update(roots[i], ctx) < 0)
- ret = -1;
- }
- }
-
- i_free(ctx);
- return ret;
-}
-
-void quota_transaction_rollback(struct quota_transaction_context **_ctx)
-{
- struct quota_transaction_context *ctx = *_ctx;
-
- *_ctx = NULL;
- i_free(ctx);
+ return -1;
+ }
+ }
+ return 0;
}
int quota_try_alloc(struct quota_transaction_context *ctx,
@@ -533,6 +537,13 @@ int quota_test_alloc(struct quota_transa
int quota_test_alloc(struct quota_transaction_context *ctx,
uoff_t size, bool *too_large_r)
{
+ if (ctx->failed)
+ return -1;
+
+ if (!ctx->limits_set) {
+ if (quota_transaction_set_limits(ctx) < 0)
+ return -1;
+ }
return ctx->quota->test_alloc(ctx, size, too_large_r);
}
@@ -544,8 +555,6 @@ static int quota_default_test_alloc(stru
*too_large_r = FALSE;
- if (ctx->failed)
- return -1;
if (ctx->count_left != 0 && ctx->bytes_left >= ctx->bytes_used + size)
return 1;
More information about the dovecot-cvs
mailing list