From 6d6bbe8787354bbb69d0c03187adfe0f497d70b8 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Sun, 20 Jul 2008 21:36:13 +0300 Subject: [PATCH] FS quota: Handle quota only for the quota roots which apply to the mailbox when there are multiple roots. With a single quota root the check is usually unnecessary. Based on patch by Ralf Becker. --HG-- branch : HEAD --- src/plugins/quota/quota-dict.c | 3 ++- src/plugins/quota/quota-dirsize.c | 3 ++- src/plugins/quota/quota-fs.c | 39 +++++++++++++++++++++++++++++-- src/plugins/quota/quota-maildir.c | 3 ++- src/plugins/quota/quota-private.h | 2 ++ src/plugins/quota/quota.c | 29 ++++++++++++++++++++--- 6 files changed, 71 insertions(+), 8 deletions(-) diff --git a/src/plugins/quota/quota-dict.c b/src/plugins/quota/quota-dict.c index 862b3277c8..0fd339ab03 100644 --- a/src/plugins/quota/quota-dict.c +++ b/src/plugins/quota/quota-dict.c @@ -182,6 +182,7 @@ struct quota_backend quota_backend_dict = { NULL, dict_quota_root_get_resources, dict_quota_get_resource, - dict_quota_update + dict_quota_update, + NULL } }; diff --git a/src/plugins/quota/quota-dirsize.c b/src/plugins/quota/quota-dirsize.c index 97323950e6..b05ab1298d 100644 --- a/src/plugins/quota/quota-dirsize.c +++ b/src/plugins/quota/quota-dirsize.c @@ -212,6 +212,7 @@ struct quota_backend quota_backend_dirsize = { NULL, dirsize_quota_root_get_resources, dirsize_quota_get_resource, - dirsize_quota_update + dirsize_quota_update, + NULL } }; diff --git a/src/plugins/quota/quota-fs.c b/src/plugins/quota/quota-fs.c index 8f6be800f6..35c73a8358 100644 --- a/src/plugins/quota/quota-fs.c +++ b/src/plugins/quota/quota-fs.c @@ -30,7 +30,11 @@ #endif #ifndef DEV_BSIZE -# define DEV_BSIZE 512 +# ifdef DQBSIZE +# define DEV_BSIZE DQBSIZE /* AIX */ +# else +# define DEV_BSIZE 512 +# endif #endif #ifdef HAVE_STRUCT_DQBLK_CURSPACE @@ -584,6 +588,35 @@ fs_quota_get_one_resource(struct fs_quota_root *root, bool group, bool bytes, #endif } +static bool fs_quota_match_box(struct quota_root *_root, struct mailbox *box) +{ + struct fs_quota_root *root = (struct fs_quota_root *)_root; + struct stat mst, rst; + const char *mailbox_path; + bool is_file, match; + + mailbox_path = mail_storage_get_mailbox_path(box->storage, box->name, + &is_file); + if (stat(mailbox_path, &mst) < 0) { + if (errno != ENOENT) + i_error("stat(%s) failed: %m", mailbox_path); + return FALSE; + } + if (stat(root->storage_mount_path, &rst) < 0) { + if (getenv("DEBUG") != NULL) { + i_error("stat(%s) failed: %m", + root->storage_mount_path); + } + return FALSE; + } + match = CMP_DEV_T(mst.st_dev, rst.st_dev); + if (getenv("DEBUG") != NULL) { + i_info("box=%s mount=%s match=%s", mailbox_path, + root->storage_mount_path, match ? "yes" : "no"); + } + return match; +} + static int fs_quota_get_resource(struct quota_root *_root, const char *name, uint64_t *value_r) @@ -648,7 +681,9 @@ struct quota_backend quota_backend_fs = { fs_quota_root_get_resources, fs_quota_get_resource, - fs_quota_update + fs_quota_update, + + fs_quota_match_box } }; diff --git a/src/plugins/quota/quota-maildir.c b/src/plugins/quota/quota-maildir.c index 0a78758826..f81326fc42 100644 --- a/src/plugins/quota/quota-maildir.c +++ b/src/plugins/quota/quota-maildir.c @@ -758,6 +758,7 @@ struct quota_backend quota_backend_maildir = { maildir_quota_storage_added, maildir_quota_root_get_resources, maildir_quota_get_resource, - maildir_quota_update + maildir_quota_update, + NULL } }; diff --git a/src/plugins/quota/quota-private.h b/src/plugins/quota/quota-private.h index 5ffe7a3e72..8c397539f5 100644 --- a/src/plugins/quota/quota-private.h +++ b/src/plugins/quota/quota-private.h @@ -54,6 +54,8 @@ struct quota_backend_vfuncs { int (*update)(struct quota_root *root, struct quota_transaction_context *ctx); + bool (*match_box)(struct quota_root *root, struct mailbox *box); + }; struct quota_backend { diff --git a/src/plugins/quota/quota.c b/src/plugins/quota/quota.c index 598d84e94a..3e74a340b5 100644 --- a/src/plugins/quota/quota.c +++ b/src/plugins/quota/quota.c @@ -551,6 +551,22 @@ quota_root_iter_init(struct quota *quota, struct mailbox *box) return iter; } +static bool +quota_root_is_visible(struct quota_root *root, struct mailbox *box, + bool enforce) +{ + if (root->no_enforcing && enforce) { + /* we don't want to include this root in quota enforcing */ + return FALSE; + } + if (array_count(&root->quota->roots) == 1) { + /* a single quota root: don't bother checking further */ + return TRUE; + } + return root->backend.v.match_box == NULL ? TRUE : + root->backend.v.match_box(root, box); +} + struct quota_root *quota_root_iter_next(struct quota_root_iter *iter) { struct quota_root *const *roots, *root = NULL; @@ -563,6 +579,9 @@ struct quota_root *quota_root_iter_next(struct quota_root_iter *iter) return NULL; for (; iter->i < count; iter->i++) { + if (!quota_root_is_visible(roots[iter->i], iter->box, FALSE)) + continue; + ret = quota_get_resource(roots[iter->i], "", QUOTA_NAME_STORAGE_KILOBYTES, &value, &limit); @@ -684,10 +703,8 @@ static int quota_transaction_set_limits(struct quota_transaction_context *ctx) /* find the lowest quota limits from all roots and use them */ roots = array_get(&ctx->quota->roots, &count); for (i = 0; i < count; i++) { - if (roots[i]->no_enforcing) { - /* we don't care what the current quota is */ + if (!quota_root_is_visible(roots[i], ctx->box, TRUE)) continue; - } ret = quota_get_resource(roots[i], mailbox_name, QUOTA_NAME_STORAGE_BYTES, @@ -781,6 +798,9 @@ int quota_transaction_commit(struct quota_transaction_context **_ctx) mailbox_name = mailbox_get_name(ctx->box); roots = array_get(&ctx->quota->roots, &count); for (i = 0; i < count; i++) { + if (!quota_root_is_visible(roots[i], ctx->box, TRUE)) + continue; + rule = quota_root_rule_find(roots[i], mailbox_name); if (rule != NULL && rule->ignore) { /* mailbox not included in quota */ @@ -854,6 +874,9 @@ static int quota_default_test_alloc(struct quota_transaction_context *ctx, for (i = 0; i < count; i++) { uint64_t bytes_limit, count_limit; + if (!quota_root_is_visible(roots[i], ctx->box, TRUE)) + continue; + if (!quota_root_get_rule_limits(roots[i], mailbox_get_name(ctx->box), &bytes_limit, &count_limit)) -- 2.47.3