From: Timo Sirainen Date: Mon, 21 Sep 2015 13:24:30 +0000 (+0300) Subject: quota: Added quota_vsizes=yes setting to count quotas using virtual sizes instead... X-Git-Tag: 2.2.19.rc1~27 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=93f1642397e46497894e6695749e5c52fda61774;p=thirdparty%2Fdovecot%2Fcore.git quota: Added quota_vsizes=yes setting to count quotas using virtual sizes instead of physical sizes. This doesn't work with all the quota backends. --- diff --git a/src/plugins/quota/quota-count.c b/src/plugins/quota/quota-count.c index 074aba7d6e..5946df4b1c 100644 --- a/src/plugins/quota/quota-count.c +++ b/src/plugins/quota/quota-count.c @@ -25,12 +25,14 @@ quota_count_mailbox(struct quota_root *root, struct mail_namespace *ns, } box = mailbox_alloc(ns->list, vname, MAILBOX_FLAG_READONLY); - if (mailbox_get_metadata(box, MAILBOX_METADATA_PHYSICAL_SIZE, + if (mailbox_get_metadata(box, root->quota->set->vsizes ? + MAILBOX_METADATA_VIRTUAL_SIZE : + MAILBOX_METADATA_PHYSICAL_SIZE, &metadata) < 0 || mailbox_get_status(box, STATUS_MESSAGES, &status) < 0) { errstr = mailbox_get_last_error(box, &error); if (error == MAIL_ERROR_TEMP) { - i_error("quota: Couldn't get physical size of mailbox %s: %s", + i_error("quota: Couldn't get size of mailbox %s: %s", vname, errstr); ret = -1; } else { @@ -39,7 +41,8 @@ quota_count_mailbox(struct quota_root *root, struct mail_namespace *ns, } } else { ret = 1; - *bytes_r = metadata.physical_size; + *bytes_r = root->quota->set->vsizes ? + metadata.virtual_size : metadata.physical_size; *count_r = status.messages; } mailbox_free(&box); diff --git a/src/plugins/quota/quota-private.h b/src/plugins/quota/quota-private.h index f0a08d7626..5f3e1100ab 100644 --- a/src/plugins/quota/quota-private.h +++ b/src/plugins/quota/quota-private.h @@ -28,6 +28,7 @@ struct quota_settings { const char *quota_exceeded_msg; unsigned int debug:1; unsigned int initialized:1; + unsigned int vsizes:1; }; struct quota_rule { diff --git a/src/plugins/quota/quota-storage.c b/src/plugins/quota/quota-storage.c index 3fa28d47e3..a0946a4b00 100644 --- a/src/plugins/quota/quota-storage.c +++ b/src/plugins/quota/quota-storage.c @@ -48,14 +48,20 @@ static void quota_mail_expunge(struct mail *_mail) { struct mail_private *mail = (struct mail_private *)_mail; struct quota_mailbox *qbox = QUOTA_CONTEXT(_mail->box); + struct quota_user *quser = QUOTA_USER_CONTEXT(_mail->box->storage->user); union mail_module_context *qmail = QUOTA_MAIL_CONTEXT(mail); uoff_t size; + int ret; /* We need to handle the situation where multiple transactions expunged the mail at the same time. In here we'll just save the message's physical size and do the quota freeing later when the message was known to be expunged. */ - if (mail_get_physical_size(_mail, &size) == 0) { + if (quser->quota->set->vsizes) + ret = mail_get_virtual_size(_mail, &size); + else + ret = mail_get_physical_size(_mail, &size); + if (ret == 0) { if (!array_is_created(&qbox->expunge_uids)) { i_array_init(&qbox->expunge_uids, 64); i_array_init(&qbox->expunge_sizes, 64); @@ -310,6 +316,7 @@ static void quota_mailbox_sync_notify(struct mailbox *box, uint32_t uid, enum mailbox_sync_type sync_type) { struct quota_mailbox *qbox = QUOTA_CONTEXT(box); + struct quota_user *quser = QUOTA_USER_CONTEXT(box->storage->user); const uint32_t *uids; const uoff_t *sizep; unsigned int i, count; @@ -369,10 +376,16 @@ static void quota_mailbox_sync_notify(struct mailbox *box, uint32_t uid, mail_alloc(qbox->expunge_trans, MAIL_FETCH_PHYSICAL_SIZE, NULL); } - if (mail_set_uid(qbox->expunge_qt->tmp_mail, uid) && - mail_get_physical_size(qbox->expunge_qt->tmp_mail, &size) == 0) + if (!mail_set_uid(qbox->expunge_qt->tmp_mail, uid)) + ; + else if (!quser->quota->set->vsizes) { + if (mail_get_physical_size(qbox->expunge_qt->tmp_mail, &size) == 0) { + quota_free_bytes(qbox->expunge_qt, size); + return; + } + } else if (mail_get_virtual_size(qbox->expunge_qt->tmp_mail, &size) == 0) { quota_free_bytes(qbox->expunge_qt, size); - else { + } else { /* there's no way to get the size. recalculate the quota. */ quota_recalculate(qbox->expunge_qt); qbox->recalculate = TRUE; diff --git a/src/plugins/quota/quota.c b/src/plugins/quota/quota.c index c3a278f1c7..f4da6bb474 100644 --- a/src/plugins/quota/quota.c +++ b/src/plugins/quota/quota.c @@ -229,6 +229,7 @@ int quota_user_read_settings(struct mail_user *user, mail_user_plugin_getenv(user, "quota_exceeded_message"); if (quota_set->quota_exceeded_msg == NULL) quota_set->quota_exceeded_msg = DEFAULT_QUOTA_EXCEEDED_MSG; + quota_set->vsizes = mail_user_plugin_getenv(user, "quota_vsizes") != NULL; p_array_init("a_set->root_sets, pool, 4); if (i_strocpy(root_name, "quota", sizeof(root_name)) < 0)