ARRAY(uoff_t) expunge_sizes;
unsigned int recalculate:1;
+ unsigned int sync_transaction_expunge:1;
};
struct quota_user_module quota_user_module =
}
array_append(&qbox->expunge_uids, &_mail->uid, 1);
array_append(&qbox->expunge_sizes, &size, 1);
+ if ((_mail->transaction->flags & MAILBOX_TRANSACTION_FLAG_SYNC) != 0) {
+ /* we're running dsync. if this brings the quota below
+ a negative quota warning, don't execute it, because
+ it probably was already executed by the replica. */
+ qbox->sync_transaction_expunge = TRUE;
+ } else {
+ qbox->sync_transaction_expunge = FALSE;
+ }
}
qmail->super.expunge(_mail);
t = qbox->module_ctx.super.transaction_begin(box, flags);
qt = quota_transaction_begin(box);
+ qt->sync_transaction = (flags & MAILBOX_TRANSACTION_FLAG_SYNC) != 0;
MODULE_CONTEXT_SET(t, quota_storage_module, qt);
return t;
mail_free(&qbox->expunge_qt->tmp_mail);
mailbox_transaction_rollback(&qbox->expunge_trans);
}
+ qbox->sync_transaction_expunge = FALSE;
}
static void quota_mailbox_sync_commit(struct quota_mailbox *qbox)
}
}
- if (qbox->expunge_qt == NULL)
+ if (qbox->expunge_qt == NULL) {
qbox->expunge_qt = quota_transaction_begin(box);
+ qbox->expunge_qt->sync_transaction =
+ qbox->sync_transaction_expunge;
+ }
if (i != count) {
/* we already know the size */
if (roots[i]->backend.v.update(roots[i], ctx) < 0)
ret = -1;
- else
+ else if (!ctx->sync_transaction)
array_append(&warn_roots, &roots[i], 1);
}
/* execute quota warnings after all updates. this makes it
work correctly regardless of whether backend.get_resource()
- returns updated values before backend.update() or not */
+ returns updated values before backend.update() or not.
+ warnings aren't executed when dsync bring the user over,
+ because the user probably already got the warning on the
+ other replica. */
array_foreach(&warn_roots, roots)
quota_warnings_execute(ctx, *roots);
} T_END;