changeset 20622:5738729e96d2

quota: Don't get message sizes when updating mailbox that ignores quotas. Nothing is done with the size anyway.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Tue, 09 Aug 2016 18:06:25 +0300
parents bac0781b6e1f
children d961f2a542d7
files src/plugins/quota/quota-private.h src/plugins/quota/quota.c
diffstat 2 files changed, 29 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/quota/quota-private.h	Wed Aug 10 19:07:18 2016 +0300
+++ b/src/plugins/quota/quota-private.h	Tue Aug 09 18:06:25 2016 +0300
@@ -182,6 +182,8 @@
 	unsigned int sync_transaction:1;
 	/* TRUE if all roots have auto_updating=TRUE */
 	unsigned int auto_updating:1;
+	/* Quota doesn't need to be updated within this transaction. */
+	unsigned int no_quota_updates:1;
 };
 
 /* Register storage to all user's quota roots. */
--- a/src/plugins/quota/quota.c	Wed Aug 10 19:07:18 2016 +0300
+++ b/src/plugins/quota/quota.c	Tue Aug 09 18:06:25 2016 +0300
@@ -399,12 +399,15 @@
 static int quota_root_get_rule_limits(struct quota_root *root,
 				      const char *mailbox_name,
 				      uint64_t *bytes_limit_r,
-				      uint64_t *count_limit_r)
+				      uint64_t *count_limit_r,
+				      bool *ignored_r)
 {
 	struct quota_rule *rule;
 	int64_t bytes_limit, count_limit;
 	bool enabled;
 
+	*ignored_r = FALSE;
+
 	if (!root->set->force_default_rule) {
 		if (root->backend.v.init_limits != NULL) {
 			if (root->backend.v.init_limits(root) < 0)
@@ -429,6 +432,7 @@
 		} else {
 			bytes_limit = 0;
 			count_limit = 0;
+			*ignored_r = TRUE;
 		}
 	}
 
@@ -671,7 +675,7 @@
 		       const char *name, uint64_t *value_r, uint64_t *limit_r)
 {
 	uint64_t bytes_limit, count_limit;
-	bool kilobytes = FALSE;
+	bool ignored, kilobytes = FALSE;
 	int ret;
 
 	*value_r = *limit_r = 0;
@@ -688,7 +692,8 @@
 		return ret;
 
 	if (quota_root_get_rule_limits(root, mailbox_name,
-				       &bytes_limit, &count_limit) < 0)
+				       &bytes_limit, &count_limit,
+				       &ignored) < 0)
 		return -1;
 
 	if (strcmp(name, QUOTA_NAME_STORAGE_BYTES) == 0)
@@ -784,13 +789,14 @@
 	const char *mailbox_name;
 	unsigned int i, count;
 	uint64_t bytes_limit, count_limit, current, limit, diff;
-	bool use_grace;
+	bool use_grace, ignored;
 	int ret;
 
 	ctx->limits_set = TRUE;
 	mailbox_name = mailbox_get_vname(ctx->box);
 	/* use quota_grace only for LDA/LMTP */
 	use_grace = (ctx->box->flags & MAILBOX_FLAG_POST_SESSION) != 0;
+	ctx->no_quota_updates = TRUE;
 
 	/* find the lowest quota limits from all roots and use them */
 	roots = array_get(&ctx->quota->roots, &count);
@@ -799,11 +805,13 @@
 			continue;
 
 		if (quota_root_get_rule_limits(roots[i], mailbox_name,
-					       &bytes_limit,
-					       &count_limit) < 0) {
+					       &bytes_limit, &count_limit,
+					       &ignored) < 0) {
 			ctx->failed = TRUE;
 			return -1;
 		}
+		if (!ignored)
+			ctx->no_quota_updates = FALSE;
 
 		if (bytes_limit > 0) {
 			ret = quota_get_resource(roots[i], mailbox_name,
@@ -1093,6 +1101,14 @@
 	uoff_t size;
 	int ret;
 
+	if (!ctx->limits_set) {
+		if (quota_transaction_set_limits(ctx) < 0)
+			return -1;
+	}
+
+	if (ctx->no_quota_updates)
+		return 1;
+
 	if (mail_get_physical_size(mail, &size) < 0) {
 		i_error("quota: Failed to get mail size (box=%s, uid=%u): %s",
 			mail->box->vname, mail->uid,
@@ -1123,6 +1139,8 @@
 		if (quota_transaction_set_limits(ctx) < 0)
 			return -1;
 	}
+	if (ctx->no_quota_updates)
+		return 1;
 	/* this is a virtual function mainly for trash plugin and similar,
 	   which may automatically delete mails to stay under quota. */
 	return ctx->quota->set->test_alloc(ctx, size, too_large_r);
@@ -1133,6 +1151,7 @@
 {
 	struct quota_root *const *roots;
 	unsigned int i, count;
+	bool ignore;
 	int ret;
 
 	*too_large_r = FALSE;
@@ -1150,7 +1169,8 @@
 
 		ret = quota_root_get_rule_limits(roots[i],
 						 mailbox_get_vname(ctx->box),
-						 &bytes_limit, &count_limit);
+						 &bytes_limit, &count_limit,
+						 &ignore);
 		if (ret < 0)
 			return -1;