changeset 20301:9cf9777c94b5

quota: Differentiate between forced and non-forced quota recalc The "count" backend doesn't need to recalc quota unless an explicit "doveadm quota recalc" command is called.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Mon, 02 May 2016 18:27:02 +0300
parents 3906d919b83f
children afaf7a683a78
files src/plugins/quota/doveadm-quota.c src/plugins/quota/quota-count.c src/plugins/quota/quota-dict.c src/plugins/quota/quota-maildir.c src/plugins/quota/quota-private.h src/plugins/quota/quota-storage.c src/plugins/quota/quota.c src/plugins/quota/quota.h
diffstat 8 files changed, 24 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/quota/doveadm-quota.c	Mon May 02 18:16:00 2016 +0300
+++ b/src/plugins/quota/doveadm-quota.c	Mon May 02 18:27:02 2016 +0300
@@ -101,7 +101,7 @@
 
 	memset(&trans, 0, sizeof(trans));
 	trans.quota = quser->quota;
-	trans.recalculate = TRUE;
+	trans.recalculate = QUOTA_RECALCULATE_FORCED;
 
 	array_foreach(&quser->quota->roots, root)
 		(void)(*root)->backend.v.update(*root, &trans);
--- a/src/plugins/quota/quota-count.c	Mon May 02 18:16:00 2016 +0300
+++ b/src/plugins/quota/quota-count.c	Mon May 02 18:27:02 2016 +0300
@@ -310,7 +310,7 @@
 	struct count_quota_root *croot = (struct count_quota_root *)root;
 
 	croot->cache_timeval.tv_sec = 0;
-	if (ctx->recalculate) {
+	if (ctx->recalculate == QUOTA_RECALCULATE_FORCED) {
 		if (quota_count_recalculate(root) < 0)
 			return -1;
 	}
--- a/src/plugins/quota/quota-dict.c	Mon May 02 18:16:00 2016 +0300
+++ b/src/plugins/quota/quota-dict.c	Mon May 02 18:27:02 2016 +0300
@@ -217,7 +217,7 @@
 	struct dict_transaction_context *dt;
 	uint64_t value;
 
-	if (ctx->recalculate) {
+	if (ctx->recalculate != QUOTA_RECALCULATE_DONT) {
 		if (dict_quota_count(root, TRUE, &value) < 0)
 			return -1;
 	} else {
--- a/src/plugins/quota/quota-maildir.c	Mon May 02 18:16:00 2016 +0300
+++ b/src/plugins/quota/quota-maildir.c	Mon May 02 18:27:02 2016 +0300
@@ -903,7 +903,7 @@
 		   we wanted to do. */
 	} else if (root->fd == -1)
 		(void)maildirsize_recalculate(root);
-	else if (ctx->recalculate) {
+	else if (ctx->recalculate != QUOTA_RECALCULATE_DONT) {
 		i_close_fd(&root->fd);
 		(void)maildirsize_recalculate(root);
 	} else if (maildirsize_update(root, ctx->count_used, ctx->bytes_used) < 0) {
--- a/src/plugins/quota/quota-private.h	Mon May 02 18:16:00 2016 +0300
+++ b/src/plugins/quota/quota-private.h	Mon May 02 18:27:02 2016 +0300
@@ -175,10 +175,10 @@
 	uint64_t bytes_over, count_over;
 
 	struct mail *tmp_mail;
+	enum quota_recalculate recalculate;
 
 	unsigned int limits_set:1;
 	unsigned int failed:1;
-	unsigned int recalculate:1;
 	unsigned int sync_transaction:1;
 	/* TRUE if all roots have auto_updating=TRUE */
 	unsigned int auto_updating:1;
--- a/src/plugins/quota/quota-storage.c	Mon May 02 18:16:00 2016 +0300
+++ b/src/plugins/quota/quota-storage.c	Mon May 02 18:27:02 2016 +0300
@@ -416,7 +416,7 @@
 			index_mailbox_vsize_hdr_expunge(ibox->vsize_update, uid, size);
 	} else {
 		/* there's no way to get the size. recalculate the quota. */
-		quota_recalculate(qbox->expunge_qt);
+		quota_recalculate(qbox->expunge_qt, QUOTA_RECALCULATE_MISSING_FREES);
 		qbox->recalculate = TRUE;
 	}
 }
--- a/src/plugins/quota/quota.c	Mon May 02 18:16:00 2016 +0300
+++ b/src/plugins/quota/quota.c	Mon May 02 18:27:02 2016 +0300
@@ -955,7 +955,7 @@
 	if (ctx->failed)
 		ret = -1;
 	else if (ctx->bytes_used != 0 || ctx->count_used != 0 ||
-		 ctx->recalculate) T_BEGIN {
+		 ctx->recalculate != QUOTA_RECALCULATE_DONT) T_BEGIN {
 		ARRAY(struct quota_root *) warn_roots;
 
 		mailbox_name = mailbox_get_vname(ctx->box);
@@ -1180,7 +1180,7 @@
 	if (ctx->auto_updating)
 		return;
 	if (mail_get_physical_size(mail, &size) < 0)
-		quota_recalculate(ctx);
+		quota_recalculate(ctx, QUOTA_RECALCULATE_MISSING_FREES);
 	else
 		quota_free_bytes(ctx, size);
 }
@@ -1192,7 +1192,8 @@
 	ctx->count_used--;
 }
 
-void quota_recalculate(struct quota_transaction_context *ctx)
+void quota_recalculate(struct quota_transaction_context *ctx,
+		       enum quota_recalculate recalculate)
 {
-	ctx->recalculate = TRUE;
+	ctx->recalculate = recalculate;
 }
--- a/src/plugins/quota/quota.h	Mon May 02 18:16:00 2016 +0300
+++ b/src/plugins/quota/quota.h	Mon May 02 18:27:02 2016 +0300
@@ -19,6 +19,17 @@
 struct quota_root_iter;
 struct quota_transaction_context;
 
+enum quota_recalculate {
+	QUOTA_RECALCULATE_DONT = 0,
+	/* We may want to recalculate quota because we weren't able to call
+	   quota_free*() correctly for all mails. Quota needs to be
+	   recalculated unless the backend does the quota tracking
+	   internally. */
+	QUOTA_RECALCULATE_MISSING_FREES,
+	/* doveadm quota recalc called - make sure the quota is correct */
+	QUOTA_RECALCULATE_FORCED
+};
+
 int quota_user_read_settings(struct mail_user *user,
 			     struct quota_settings **set_r,
 			     const char **error_r);
@@ -81,7 +92,8 @@
 void quota_free_bytes(struct quota_transaction_context *ctx,
 		      uoff_t physical_size);
 /* Mark the quota to be recalculated */
-void quota_recalculate(struct quota_transaction_context *ctx);
+void quota_recalculate(struct quota_transaction_context *ctx,
+		       enum quota_recalculate recalculate);
 
 /* Execute quota_over_scripts if needed. */
 void quota_over_flag_check_startup(struct quota *quota);