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);
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;
}
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 {
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) {
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_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;
}
}
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);
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);
}
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;
}
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);
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);