]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
quota: Added "count" backend, which simply sums up mailboxes' vsizes.
authorTimo Sirainen <tss@iki.fi>
Mon, 21 Sep 2015 13:36:05 +0000 (16:36 +0300)
committerTimo Sirainen <tss@iki.fi>
Mon, 21 Sep 2015 13:36:05 +0000 (16:36 +0300)
In a way this is similar to the simple "dirsize" backend, but much more
efficient. As long as mailbox_list_index=yes, the quota can typically be
looked up only by reading the dovecot.list.index* files.

This backend enforces using quota_vsizes=yes setting to keep the performance
good, because physical sizes don't have a similar optimized vsize header.
There's also no especially good reason why this backend should support
physical sizes - they were originally mainly used to allow quickly stat()ing
Maildir files.

src/plugins/quota/quota-count.c
src/plugins/quota/quota.c

index 5946df4b1c57f0af6ffafc5361b0a371ddd5c641..132b328ba0a0995cfadda338c8f95d1a1d6a3478 100644 (file)
@@ -107,3 +107,78 @@ int quota_count(struct quota_root *root, uint64_t *bytes_r, uint64_t *count_r)
        root->recounting = FALSE;
        return ret;
 }
+
+static struct quota_root *count_quota_alloc(void)
+{
+       return i_new(struct quota_root, 1);
+}
+
+static int count_quota_init(struct quota_root *root, const char *args,
+                           const char **error_r)
+{
+       if (!root->quota->set->vsizes) {
+               *error_r = "quota count backend requires quota_vsizes=yes";
+               return -1;
+       }
+       return quota_root_default_init(root, args, error_r);
+}
+
+static void count_quota_deinit(struct quota_root *_root)
+{
+       i_free(_root);
+}
+
+static const char *const *
+count_quota_root_get_resources(struct quota_root *root ATTR_UNUSED)
+{
+       static const char *resources[] = {
+               QUOTA_NAME_STORAGE_KILOBYTES, QUOTA_NAME_MESSAGES, NULL
+       };
+       return resources;
+}
+
+static int
+count_quota_get_resource(struct quota_root *root,
+                        const char *name, uint64_t *value_r)
+{
+       uint64_t bytes, count;
+
+       if (quota_count(root, &bytes, &count) < 0)
+               return -1;
+
+       if (strcmp(name, QUOTA_NAME_STORAGE_BYTES) == 0)
+               *value_r = bytes;
+       else if (strcmp(name, QUOTA_NAME_MESSAGES) == 0)
+               *value_r = count;
+       else
+               return 0;
+       return 1;
+}
+
+static int
+count_quota_update(struct quota_root *root ATTR_UNUSED,
+                  struct quota_transaction_context *ctx ATTR_UNUSED)
+{
+       if (ctx->recalculate) {
+               //FIXME: remove cached values from index
+       }
+       return 0;
+}
+
+struct quota_backend quota_backend_count = {
+       "count",
+
+       {
+               count_quota_alloc,
+               count_quota_init,
+               count_quota_deinit,
+               NULL,
+               NULL,
+               NULL,
+               count_quota_root_get_resources,
+               count_quota_get_resource,
+               count_quota_update,
+               NULL,
+               NULL
+       }
+};
index f4da6bb47417309e57eb24d0db5aec409c4c1a2c..ca9ac2f899aa771022576f1ba5a868d99944bba1 100644 (file)
@@ -29,6 +29,7 @@ struct quota_root_iter {
 
 unsigned int quota_module_id = 0;
 
+extern struct quota_backend quota_backend_count;
 extern struct quota_backend quota_backend_dict;
 extern struct quota_backend quota_backend_dirsize;
 extern struct quota_backend quota_backend_fs;
@@ -38,6 +39,7 @@ static const struct quota_backend *quota_backends[] = {
 #ifdef HAVE_FS_QUOTA
        &quota_backend_fs,
 #endif
+       &quota_backend_count,
        &quota_backend_dict,
        &quota_backend_dirsize,
        &quota_backend_maildir