quota-storage.c revision 2ed2459dbd183bb371da4a0aecb2d2b74ae7c815
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov/* Copyright (c) 2005-2014 Dovecot authors, see the included COPYING file */
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik MODULE_CONTEXT(obj, quota_mailbox_list_module)
8bdb8c0970dc9acb5b0a54dab0bae306ca964944Jakub Hrozek struct mailbox_transaction_context *expunge_trans;
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov MODULE_CONTEXT_INIT(&mail_user_module_register);
52ae4eeba9c97c0254a2025ec3b5ffe90588b775Lukas Slebodnikstatic MODULE_CONTEXT_DEFINE_INIT(quota_storage_module,
52ae4eeba9c97c0254a2025ec3b5ffe90588b775Lukas Slebodnikstatic MODULE_CONTEXT_DEFINE_INIT(quota_mail_module, &mail_module_register);
52ae4eeba9c97c0254a2025ec3b5ffe90588b775Lukas Slebodnikstatic MODULE_CONTEXT_DEFINE_INIT(quota_mailbox_list_module,
e64696e1fab85c42aaeda65ddf49ee1b7e3f07e1Lukas Slebodnikstatic void quota_mail_expunge(struct mail *_mail)
e64696e1fab85c42aaeda65ddf49ee1b7e3f07e1Lukas Slebodnik struct mail_private *mail = (struct mail_private *)_mail;
e64696e1fab85c42aaeda65ddf49ee1b7e3f07e1Lukas Slebodnik struct quota_mailbox *qbox = QUOTA_CONTEXT(_mail->box);
e64696e1fab85c42aaeda65ddf49ee1b7e3f07e1Lukas Slebodnik union mail_module_context *qmail = QUOTA_MAIL_CONTEXT(mail);
e64696e1fab85c42aaeda65ddf49ee1b7e3f07e1Lukas Slebodnik /* We need to handle the situation where multiple transactions expunged
e64696e1fab85c42aaeda65ddf49ee1b7e3f07e1Lukas Slebodnik the mail at the same time. In here we'll just save the message's
e64696e1fab85c42aaeda65ddf49ee1b7e3f07e1Lukas Slebodnik physical size and do the quota freeing later when the message was
e64696e1fab85c42aaeda65ddf49ee1b7e3f07e1Lukas Slebodnik known to be expunged. */
e64696e1fab85c42aaeda65ddf49ee1b7e3f07e1Lukas Slebodnik if (mail_get_physical_size(_mail, &size) == 0) {
e64696e1fab85c42aaeda65ddf49ee1b7e3f07e1Lukas Slebodnik if (!array_is_created(&qbox->expunge_uids)) {
52ae4eeba9c97c0254a2025ec3b5ffe90588b775Lukas Slebodnik array_append(&qbox->expunge_uids, &_mail->uid, 1);
52ae4eeba9c97c0254a2025ec3b5ffe90588b775Lukas Slebodnik array_append(&qbox->expunge_sizes, &size, 1);
52ae4eeba9c97c0254a2025ec3b5ffe90588b775Lukas Slebodnik if ((_mail->transaction->flags & MAILBOX_TRANSACTION_FLAG_SYNC) != 0) {
52ae4eeba9c97c0254a2025ec3b5ffe90588b775Lukas Slebodnik /* we're running dsync. if this brings the quota below
52ae4eeba9c97c0254a2025ec3b5ffe90588b775Lukas Slebodnik a negative quota warning, don't execute it, because
52ae4eeba9c97c0254a2025ec3b5ffe90588b775Lukas Slebodnik it probably was already executed by the replica. */
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashovquota_get_status(struct mailbox *box, enum mailbox_status_items items,
db0982c52294ee5ea08ed242d27660783fde29cdJakub Hrozek struct quota_mailbox *qbox = QUOTA_CONTEXT(box);
a3bed9df5a47bfc84b82341f0f7e693e2b14a67aLukas Slebodnik if ((items & STATUS_CHECK_OVER_QUOTA) != 0) {
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov if ((ret = quota_test_alloc(qt, 0, &too_large)) == 0) {
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov mail_storage_set_error(box->storage, MAIL_ERROR_NOQUOTA,
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov if ((items & ~STATUS_CHECK_OVER_QUOTA) == 0) {
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov /* don't bother calling parent, it may unnecessarily
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov try to open the mailbox */
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov if (qbox->module_ctx.super.get_status(box, items, status_r) < 0)
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashovstatic struct mailbox_transaction_context *
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashovquota_mailbox_transaction_begin(struct mailbox *box,
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov struct quota_mailbox *qbox = QUOTA_CONTEXT(box);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov t = qbox->module_ctx.super.transaction_begin(box, flags);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov qt->sync_transaction = (flags & MAILBOX_TRANSACTION_FLAG_SYNC) != 0;
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov MODULE_CONTEXT_SET(t, quota_storage_module, qt);
f75ba99fc8dd64e45af2f642d9fb7660860fd28fLukas Slebodnikquota_mailbox_transaction_commit(struct mailbox_transaction_context *ctx,
e64696e1fab85c42aaeda65ddf49ee1b7e3f07e1Lukas Slebodnik struct mail_transaction_commit_changes *changes_r)
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov struct quota_mailbox *qbox = QUOTA_CONTEXT(ctx->box);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov struct quota_transaction_context *qt = QUOTA_CONTEXT(ctx);
e64696e1fab85c42aaeda65ddf49ee1b7e3f07e1Lukas Slebodnik if (qbox->module_ctx.super.transaction_commit(ctx, changes_r) < 0) {
int ret;
bool too_large;
if (ret > 0)
else if (ret == 0) {
NULL);
int ret;
bool too_large;
if (ret == 0) {
} else if (ret < 0) {
NULL);
unsigned int i, count;
if (uid == 0) {
i = count = 0;
for (i = 0; i < count; i++) {
if (i != count) {
int ret;
return ret;
unsigned int i, count;
for (i = 0; i < count; i++) {
const char *error;
int ret;
if (ret < 0) {
if (ret > 0) {
static struct quota_root *
unsigned int i, count;
for (i = 0; i < count; i++) {
return roots[i];
return NULL;
bool add;
if (add) {
const char *name;
unsigned int i, count;
for (i = 0; i < count; i++)