]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
FS quota: Handle quota only for the quota roots which apply to the mailbox
authorTimo Sirainen <tss@iki.fi>
Sun, 20 Jul 2008 18:36:13 +0000 (21:36 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 20 Jul 2008 18:36:13 +0000 (21:36 +0300)
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
src/plugins/quota/quota-dirsize.c
src/plugins/quota/quota-fs.c
src/plugins/quota/quota-maildir.c
src/plugins/quota/quota-private.h
src/plugins/quota/quota.c

index 862b3277c8eccff00e87670257c213a155a026bc..0fd339ab03afe20910cdea0b09c951ac472eac9e 100644 (file)
@@ -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
        }
 };
index 97323950e654c6ecb67130750d037f9de8f46a8b..b05ab1298d097ec518076f11bcc0c5a0e485f663 100644 (file)
@@ -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
        }
 };
index 8f6be800f64483ea3f99b0ba7a8e6304d1050cdf..35c73a835809cfd72c2974aa6ff7e54895a1c1bf 100644 (file)
 #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
        }
 };
 
index 0a787588266b807e3b8c90e262aff6557d7d14c6..f81326fc428a61bdf4a48f9bdfb179edcbdb32a6 100644 (file)
@@ -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
        }
 };
index 5ffe7a3e723835b747f9710090aa7810fc005eb9..8c397539f542c19e57e7aa4d678a63062d85067c 100644 (file)
@@ -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 {
index 598d84e94afb031505060807ef18c2ff08c15f53..3e74a340b53faf38c38e0237bb39bb7761f40fa3 100644 (file)
@@ -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))