]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added "ignore" option to quota rules which causes the mailbox to be ignored
authorTimo Sirainen <tss@iki.fi>
Sat, 3 May 2008 23:39:58 +0000 (02:39 +0300)
committerTimo Sirainen <tss@iki.fi>
Sat, 3 May 2008 23:39:58 +0000 (02:39 +0300)
when counting quota.

--HG--
branch : HEAD

src/plugins/quota/quota-count.c
src/plugins/quota/quota-dict.c
src/plugins/quota/quota-maildir.c
src/plugins/quota/quota-private.h
src/plugins/quota/quota.c

index 78e39ab83ce7547d58d365c984c1aaeaf29a4d8e..7d4af66f756ed49f54db8ed023bea4be91a7e643 100644 (file)
@@ -6,9 +6,11 @@
 #include "mail-storage.h"
 #include "quota-private.h"
 
-static int quota_count_mailbox(struct mail_storage *storage, const char *name,
-                              uint64_t *bytes_r, uint64_t *count_r)
+static int
+quota_count_mailbox(struct quota_root *root, struct mail_storage *storage,
+                   const char *name, uint64_t *bytes_r, uint64_t *count_r)
 {
+       struct quota_rule *rule;
        struct mailbox *box;
        struct mailbox_transaction_context *trans;
        struct mail_search_context *ctx;
@@ -17,6 +19,12 @@ static int quota_count_mailbox(struct mail_storage *storage, const char *name,
        uoff_t size;
        int ret = 0;
 
+       rule = quota_root_rule_find(root, name);
+       if (rule != NULL && rule->ignore) {
+               /* mailbox not included in quota */
+               return 0;
+       }
+
        box = mailbox_open(storage, name, NULL,
                           MAILBOX_OPEN_READONLY | MAILBOX_OPEN_KEEP_RECENT);
        if (box == NULL)
@@ -51,8 +59,9 @@ static int quota_count_mailbox(struct mail_storage *storage, const char *name,
        return ret;
 }
 
-static int quota_count_storage(struct mail_storage *storage,
-                              uint64_t *bytes, uint64_t *count)
+static int
+quota_count_storage(struct quota_root *root, struct mail_storage *storage,
+                   uint64_t *bytes, uint64_t *count)
 {
        struct mailbox_list_iterate_context *ctx;
        const struct mailbox_info *info;
@@ -63,7 +72,7 @@ static int quota_count_storage(struct mail_storage *storage,
        while ((info = mailbox_list_iter_next(ctx)) != NULL) {
                if ((info->flags & (MAILBOX_NONEXISTENT |
                                    MAILBOX_NOSELECT)) == 0) {
-                       ret = quota_count_mailbox(storage, info->name,
+                       ret = quota_count_mailbox(root, storage, info->name,
                                                  bytes, count);
                        if (ret < 0)
                                break;
@@ -75,7 +84,7 @@ static int quota_count_storage(struct mail_storage *storage,
        return ret;
 }
 
-int quota_count(struct quota *quota, uint64_t *bytes_r, uint64_t *count_r)
+int quota_count(struct quota_root *root, uint64_t *bytes_r, uint64_t *count_r)
 {
        struct mail_storage *const *storages;
        unsigned int i, count;
@@ -83,9 +92,9 @@ int quota_count(struct quota *quota, uint64_t *bytes_r, uint64_t *count_r)
 
        *bytes_r = *count_r = 0;
 
-       storages = array_get(&quota->storages, &count);
+       storages = array_get(&root->quota->storages, &count);
        for (i = 0; i < count; i++) {
-               ret = quota_count_storage(storages[i], bytes_r, count_r);
+               ret = quota_count_storage(root, storages[i], bytes_r, count_r);
                if (ret < 0)
                        break;
        }
index a9caee7e68b355f53312d4bf2a4eac59d35a9be1..3166b52f1c34a80e4fee8bd110ec5283c5abb455 100644 (file)
@@ -78,7 +78,7 @@ dict_quota_count(struct dict_quota_root *root,
        struct dict_transaction_context *dt;
        uint64_t bytes, count;
 
-       if (quota_count(root->root.quota, &bytes, &count) < 0)
+       if (quota_count(&root->root, &bytes, &count) < 0)
                return -1;
 
        T_BEGIN {
index 29b56e2adc2c365ce0251598f504563c12e11fe8..694b1b85a3bdad60fe6afc2ba83c14b60175e8d2 100644 (file)
@@ -36,6 +36,7 @@ struct maildir_quota_root {
 
 struct maildir_list_context {
        struct mail_storage *storage;
+       struct maildir_quota_root *root;
        struct mailbox_list_iterate_context *iter;
        const struct mailbox_info *info;
 
@@ -121,12 +122,14 @@ static int maildir_sum_dir(const char *dir, uint64_t *total_bytes,
 }
 
 static struct maildir_list_context *
-maildir_list_init(struct mail_storage *storage)
+maildir_list_init(struct maildir_quota_root *root,
+                 struct mail_storage *storage)
 {
        struct maildir_list_context *ctx;
 
        ctx = i_new(struct maildir_list_context, 1);
        ctx->storage = storage;
+       ctx->root = root;
        ctx->path = str_new(default_pool, 512);
        ctx->iter = mailbox_list_iter_init(mail_storage_get_list(storage), "*",
                                           MAILBOX_LIST_ITER_RETURN_NO_FLAGS);
@@ -136,6 +139,7 @@ maildir_list_init(struct mail_storage *storage)
 static const char *
 maildir_list_next(struct maildir_list_context *ctx, time_t *mtime_r)
 {
+       struct quota_rule *rule;
        struct stat st;
        bool is_file;
 
@@ -144,6 +148,13 @@ maildir_list_next(struct maildir_list_context *ctx, time_t *mtime_r)
                        ctx->info = mailbox_list_iter_next(ctx->iter);
                        if (ctx->info == NULL)
                                return NULL;
+
+                       rule = quota_root_rule_find(&ctx->root->root,
+                                                   ctx->info->name);
+                       if (rule != NULL && rule->ignore) {
+                               /* mailbox not included in quota */
+                               continue;
+                       }
                }
 
                T_BEGIN {
@@ -185,13 +196,14 @@ static int maildir_list_deinit(struct maildir_list_context *ctx)
 }
 
 static int
-maildirs_check_have_changed(struct mail_storage *storage, time_t latest_mtime)
+maildirs_check_have_changed(struct maildir_quota_root *root,
+                           struct mail_storage *storage, time_t latest_mtime)
 {
        struct maildir_list_context *ctx;
        time_t mtime;
        int ret = 0;
 
-       ctx = maildir_list_init(storage);
+       ctx = maildir_list_init(root, storage);
        while (maildir_list_next(ctx, &mtime) != NULL) {
                if (mtime > latest_mtime) {
                        ret = 1;
@@ -270,7 +282,7 @@ static int maildirsize_recalculate_storage(struct maildir_quota_root *root,
        time_t mtime;
        int ret = 0;
 
-       ctx = maildir_list_init(storage);
+       ctx = maildir_list_init(root, storage);
        while ((dir = maildir_list_next(ctx, &mtime)) != NULL) {
                if (mtime > root->recalc_last_stamp)
                        root->recalc_last_stamp = mtime;
@@ -332,7 +344,7 @@ static int maildirsize_recalculate(struct maildir_quota_root *root)
        if (ret == 0) {
                /* check if any of the directories have changed */
                for (i = 0; i < count; i++) {
-                       ret = maildirs_check_have_changed(storages[i],
+                       ret = maildirs_check_have_changed(root, storages[i],
                                                root->recalc_last_stamp);
                        if (ret != 0)
                                break;
index afef4cba899ebb4d7af8f02443e90fcac41b8d2b..5ffe7a3e723835b747f9710090aa7810fc005eb9 100644 (file)
@@ -25,6 +25,9 @@ struct quota_rule {
        int64_t bytes_limit, count_limit;
        /* relative to default_rule */
        unsigned int bytes_percent, count_percent;
+
+       /* Don't include this mailbox in quota */
+       unsigned int ignore:1;
 };
 
 struct quota_warning_rule {
@@ -103,7 +106,10 @@ void quota_add_user_storage(struct quota *quota, struct mail_storage *storage);
 void quota_remove_user_storage(struct quota *quota, 
                               struct mail_storage *storage);
 
+struct quota_rule *
+quota_root_rule_find(struct quota_root *root, const char *name);
+
 void quota_root_recalculate_relative_rules(struct quota_root *root);
-int quota_count(struct quota *quota, uint64_t *bytes_r, uint64_t *count_r);
+int quota_count(struct quota_root *root, uint64_t *bytes_r, uint64_t *count_r);
 
 #endif
index 07ab48cb54239fd9c0230422caddd24844ef9cb7..2470ba007ddffb6ef31118d9db9dd164cbd39fd9 100644 (file)
@@ -176,7 +176,7 @@ void quota_root_deinit(struct quota_root **_root)
        pool_unref(&pool);
 }
 
-static struct quota_rule *
+struct quota_rule *
 quota_root_rule_find(struct quota_root *root, const char *name)
 {
        struct quota_rule *rules;
@@ -353,6 +353,15 @@ int quota_root_add_rule(struct quota_root *root, const char *rule_def,
                }
        }
 
+       if (strcmp(p, "ignore") == 0) {
+               rule->ignore = TRUE;
+               if (root->quota->debug) {
+                       i_info("Quota rule: root=%s mailbox=%s ignored",
+                              root->name, mailbox_name);
+               }
+               return 0;
+       }
+
        if (strncmp(p, "backend=", 8) == 0) {
                if (!root->backend.v.parse_rule(root, rule, p + 8, error_r))
                        ret = -1;
@@ -368,7 +377,7 @@ int quota_root_add_rule(struct quota_root *root, const char *rule_def,
        if (root->quota->debug) {
                i_info("Quota rule: root=%s mailbox=%s "
                       "bytes=%lld (%u%%) messages=%lld (%u%%)", root->name,
-                      rule->mailbox_name != NULL ? rule->mailbox_name : "",
+                      mailbox_name,
                       (long long)rule->bytes_limit, rule->bytes_percent,
                       (long long)rule->count_limit, rule->count_percent);
        }
@@ -393,8 +402,13 @@ static bool quota_root_get_rule_limits(struct quota_root *root,
 
        rule = quota_root_rule_find(root, mailbox_name);
        if (rule != NULL) {
-               bytes_limit += rule->bytes_limit;
-               count_limit += rule->count_limit;
+               if (!rule->ignore) {
+                       bytes_limit += rule->bytes_limit;
+                       count_limit += rule->count_limit;
+               } else {
+                       bytes_limit = 0;
+                       count_limit = 0;
+               }
                found = TRUE;
        }
 
@@ -724,8 +738,10 @@ static void quota_warnings_execute(struct quota_transaction_context *ctx,
 int quota_transaction_commit(struct quota_transaction_context **_ctx)
 {
        struct quota_transaction_context *ctx = *_ctx;
+       struct quota_rule *rule;
        struct quota_root *const *roots;
        unsigned int i, count;
+       const char *mailbox_name;
        int ret = 0;
 
        *_ctx = NULL;
@@ -734,8 +750,15 @@ int quota_transaction_commit(struct quota_transaction_context **_ctx)
                ret = -1;
        else if (ctx->bytes_used != 0 || ctx->count_used != 0 ||
                 ctx->recalculate) {
+               mailbox_name = mailbox_get_name(ctx->box);
                roots = array_get(&ctx->quota->roots, &count);
                for (i = 0; i < count; i++) {
+                       rule = quota_root_rule_find(roots[i], mailbox_name);
+                       if (rule != NULL && rule->ignore) {
+                               /* mailbox not included in quota */
+                               continue;
+                       }
+
                        if (roots[i]->backend.v.update(roots[i], ctx) < 0)
                                ret = -1;
                }