From: Timo Sirainen Date: Mon, 2 May 2016 15:27:02 +0000 (+0300) Subject: quota: Differentiate between forced and non-forced quota recalc X-Git-Tag: 2.3.0.rc1~3535 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=39dea5f2e78f6bfc3adc0655176f596ee211938f;p=thirdparty%2Fdovecot%2Fcore.git 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. --- diff --git a/src/plugins/quota/doveadm-quota.c b/src/plugins/quota/doveadm-quota.c index cbf96d4bb8..2bdf7dc146 100644 --- a/src/plugins/quota/doveadm-quota.c +++ b/src/plugins/quota/doveadm-quota.c @@ -101,7 +101,7 @@ cmd_quota_recalc_run(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED, 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); diff --git a/src/plugins/quota/quota-count.c b/src/plugins/quota/quota-count.c index 76072eaa56..246c46dc58 100644 --- a/src/plugins/quota/quota-count.c +++ b/src/plugins/quota/quota-count.c @@ -310,7 +310,7 @@ count_quota_update(struct quota_root *root, 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; } diff --git a/src/plugins/quota/quota-dict.c b/src/plugins/quota/quota-dict.c index 987611ad62..eae8b4bc13 100644 --- a/src/plugins/quota/quota-dict.c +++ b/src/plugins/quota/quota-dict.c @@ -221,7 +221,7 @@ dict_quota_update(struct quota_root *_root, 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 { diff --git a/src/plugins/quota/quota-maildir.c b/src/plugins/quota/quota-maildir.c index df745fc0c1..7c7a23f7a5 100644 --- a/src/plugins/quota/quota-maildir.c +++ b/src/plugins/quota/quota-maildir.c @@ -903,7 +903,7 @@ maildir_quota_update(struct quota_root *_root, 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) { diff --git a/src/plugins/quota/quota-private.h b/src/plugins/quota/quota-private.h index 3341c646a7..6ac87af181 100644 --- a/src/plugins/quota/quota-private.h +++ b/src/plugins/quota/quota-private.h @@ -175,10 +175,10 @@ struct quota_transaction_context { 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; diff --git a/src/plugins/quota/quota-storage.c b/src/plugins/quota/quota-storage.c index 1b47bb8f71..14270d8df2 100644 --- a/src/plugins/quota/quota-storage.c +++ b/src/plugins/quota/quota-storage.c @@ -416,7 +416,7 @@ static void quota_mailbox_sync_notify(struct mailbox *box, uint32_t uid, 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; } } diff --git a/src/plugins/quota/quota.c b/src/plugins/quota/quota.c index c178bec2c5..468c671c51 100644 --- a/src/plugins/quota/quota.c +++ b/src/plugins/quota/quota.c @@ -956,7 +956,7 @@ int quota_transaction_commit(struct quota_transaction_context **_ctx) 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); @@ -1181,7 +1181,7 @@ void quota_free(struct quota_transaction_context *ctx, struct mail *mail) 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); } @@ -1193,7 +1193,8 @@ void quota_free_bytes(struct quota_transaction_context *ctx, 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; } diff --git a/src/plugins/quota/quota.h b/src/plugins/quota/quota.h index 04847d1f90..1088f5a9b0 100644 --- a/src/plugins/quota/quota.h +++ b/src/plugins/quota/quota.h @@ -19,6 +19,17 @@ struct quota_root; 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(struct quota_transaction_context *ctx, struct mail *mail); 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);