]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
quota: Added quota_vsizes=yes setting to count quotas using virtual sizes instead...
authorTimo Sirainen <tss@iki.fi>
Mon, 21 Sep 2015 13:24:30 +0000 (16:24 +0300)
committerTimo Sirainen <tss@iki.fi>
Mon, 21 Sep 2015 13:24:30 +0000 (16:24 +0300)
This doesn't work with all the quota backends.

src/plugins/quota/quota-count.c
src/plugins/quota/quota-private.h
src/plugins/quota/quota-storage.c
src/plugins/quota/quota.c

index 074aba7d6e05c90c9e9cf7ecd009f59e5b411c9e..5946df4b1c57f0af6ffafc5361b0a371ddd5c641 100644 (file)
@@ -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);
index f0a08d7626d3a85b9f5d3ff333e1d89e52494f99..5f3e1100ab46697d2eae393fecfa5d2a49a4bb3d 100644 (file)
@@ -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 {
index 3fa28d47e35573eec4f76ba3165bf02efba6bf5f..a0946a4b00e50f9c078ad6f243de59855607fc47 100644 (file)
@@ -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;
index c3a278f1c757774b2d6a4bcf4f76b65bab8aa410..f4da6bb47417309e57eb24d0db5aec409c4c1a2c 100644 (file)
@@ -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(&quota_set->root_sets, pool, 4);
        if (i_strocpy(root_name, "quota", sizeof(root_name)) < 0)