when counting quota.
--HG--
branch : HEAD
#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;
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)
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;
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;
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;
*bytes_r = *count_r = 0;
- storages = array_get("a->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;
}
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 {
struct maildir_list_context {
struct mail_storage *storage;
+ struct maildir_quota_root *root;
struct mailbox_list_iterate_context *iter;
const struct mailbox_info *info;
}
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);
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;
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 {
}
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;
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;
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;
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 {
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
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;
}
}
+ 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;
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);
}
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;
}
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;
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;
}