]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
quota: Differentiate between forced and non-forced quota recalc
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 2 May 2016 15:27:02 +0000 (18:27 +0300)
committerGitLab <gitlab@git.dovecot.net>
Mon, 6 Jun 2016 11:28:38 +0000 (14:28 +0300)
The "count" backend doesn't need to recalc quota unless an explicit "doveadm
quota recalc" command is called.

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

index cbf96d4bb8c645b676c66fc73ba41e31ddd4942c..2bdf7dc1465dda7ee5f96b657127c5b7ff4258c4 100644 (file)
@@ -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);
index 76072eaa56630d5d451a7947d5c75129cdab2cf6..246c46dc589e95b477afc2098c21b6916336f479 100644 (file)
@@ -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;
        }
index 987611ad62b88b5711d31b45b0bcd6e93db90754..eae8b4bc138c5048958318ab06bf1b5a9f88db00 100644 (file)
@@ -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 {
index df745fc0c103f5b27dd9b1fd31e14b6ff2138445..7c7a23f7a582008021dececd13389e6315c11b94 100644 (file)
@@ -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) {
index 3341c646a75163462173eb310dc6fce15c86c6a6..6ac87af181bd53fde903b6e0e9f1cb32e6d8bbd3 100644 (file)
@@ -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;
index 1b47bb8f71756d197487fe130374ff3954970d21..14270d8df28c2b72142a8f320896fe4b3b44f223 100644 (file)
@@ -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;
        }
 }
index c178bec2c56568c86fd36ff8ef76a1e1c9009142..468c671c51761b0a494c9ab6255e8bd15563eea6 100644 (file)
@@ -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;
 }
index 04847d1f90de6882a32eca96a0504d06e5ab2bb5..1088f5a9b057f44ca61a0de89ee6f5f1c21a6e3b 100644 (file)
@@ -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);