[dovecot-cvs] dovecot/src/plugins/quota Makefile.am, 1.4,
1.5 quota-dict.c, 1.8, 1.9 quota-dirsize.c, 1.6,
1.7 quota-maildir.c, NONE, 1.1 quota-private.h, 1.5,
1.6 quota.c, 1.6, 1.7
tss-movial at dovecot.org
tss-movial at dovecot.org
Mon Mar 6 12:31:14 EET 2006
- Previous message: [dovecot-cvs] dovecot/src/lib-storage/index/maildir maildir-list.c,
1.39, 1.40
- Next message: [dovecot-cvs] dovecot/src/plugins/quota quota-dirsize.c, 1.7,
1.8 quota-fs.c, 1.9, 1.10 quota-maildir.c, 1.1,
1.2 quota-private.h, 1.6, 1.7 quota.c, 1.7, 1.8
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /var/lib/cvs/dovecot/src/plugins/quota
In directory talvi:/tmp/cvs-serv29168
Modified Files:
Makefile.am quota-dict.c quota-dirsize.c quota-private.h
quota.c
Added Files:
quota-maildir.c
Log Message:
Maildir++ quota support.
Index: Makefile.am
===================================================================
RCS file: /var/lib/cvs/dovecot/src/plugins/quota/Makefile.am,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- Makefile.am 14 Dec 2005 21:50:57 -0000 1.4
+++ Makefile.am 6 Mar 2006 10:31:11 -0000 1.5
@@ -14,6 +14,7 @@
quota-fs.c \
quota-dict.c \
quota-dirsize.c \
+ quota-maildir.c \
quota-plugin.c \
quota-storage.c
Index: quota-dict.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/plugins/quota/quota-dict.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- quota-dict.c 1 Mar 2006 09:15:03 -0000 1.8
+++ quota-dict.c 6 Mar 2006 10:31:11 -0000 1.9
@@ -126,16 +126,16 @@
t_push();
(void)dict_lookup(root->dict, unsafe_data_stack_pool,
DICT_QUOTA_LIMIT_PATH"storage", &value);
- ctx->storage_limit = value == NULL ? 0 :
+ ctx->bytes_limit = value == NULL ? 0 :
strtoull(value, NULL, 10);
(void)dict_lookup(root->dict, unsafe_data_stack_pool,
DICT_QUOTA_CURRENT_PATH"storage", &value);
- ctx->storage_current = value == NULL ? 0 :
+ ctx->bytes_current = value == NULL ? 0 :
strtoull(value, NULL, 10);
t_pop();
} else {
- ctx->storage_limit = (uint64_t)-1;
+ ctx->bytes_limit = (uint64_t)-1;
}
return ctx;
@@ -170,9 +170,9 @@
dict_quota_try_alloc_bytes(struct quota_root_transaction_context *ctx,
uoff_t size, bool *too_large_r)
{
- *too_large_r = size > ctx->storage_limit;
+ *too_large_r = size > ctx->bytes_limit;
- if (ctx->storage_current + ctx->bytes_diff + size > ctx->storage_limit)
+ if (ctx->bytes_current + ctx->bytes_diff + size > ctx->bytes_limit)
return 0;
ctx->bytes_diff += size;
Index: quota-dirsize.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/plugins/quota/quota-dirsize.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- quota-dirsize.c 1 Mar 2006 09:15:03 -0000 1.6
+++ quota-dirsize.c 6 Mar 2006 10:31:11 -0000 1.7
@@ -198,21 +198,21 @@
/* Get dir usage only once at the beginning of transaction.
When copying/appending lots of mails we don't want to re-read the
entire directory structure after each mail. */
- if (get_quota_root_usage(root, &ctx->storage_current) < 0 ||
- ctx->storage_current == (uoff_t)-1) {
- ctx->storage_current = (uoff_t)-1;
+ if (get_quota_root_usage(root, &ctx->bytes_current) < 0 ||
+ ctx->bytes_current == (uint64_t)-1) {
+ ctx->bytes_current = (uint64_t)-1;
quota_set_error(_root->setup->quota,
"Internal quota calculation error");
}
- ctx->storage_limit = root->storage_limit * 1024;
+ ctx->bytes_limit = root->storage_limit * 1024;
return ctx;
}
static int
dirsize_quota_transaction_commit(struct quota_root_transaction_context *ctx)
{
- int ret = ctx->storage_current == (uoff_t)-1 ? -1 : 0;
+ int ret = ctx->bytes_current == (uint64_t)-1 ? -1 : 0;
i_free(ctx);
return ret;
@@ -228,12 +228,12 @@
dirsize_quota_try_alloc_bytes(struct quota_root_transaction_context *ctx,
uoff_t size, bool *too_large_r)
{
- if (ctx->storage_current == (uoff_t)-1)
+ if (ctx->bytes_current == (uint64_t)-1)
return -1;
- *too_large_r = size > ctx->storage_limit;
+ *too_large_r = size > ctx->bytes_limit;
- if (ctx->storage_current + ctx->bytes_diff + size > ctx->storage_limit)
+ if (ctx->bytes_current + ctx->bytes_diff + size > ctx->bytes_limit)
return 0;
ctx->bytes_diff += size;
@@ -246,7 +246,7 @@
{
uoff_t size;
- if (ctx->storage_current == (uoff_t)-1)
+ if (ctx->bytes_current == (uint64_t)-1)
return -1;
size = mail_get_physical_size(mail);
--- NEW FILE: quota-maildir.c ---
/* Copyright (C) 2006 Timo Sirainen */
#include "lib.h"
#include "array.h"
#include "ioloop.h"
#include "nfs-workarounds.h"
#include "file-dotlock.h"
#include "read-full.h"
#include "write-full.h"
#include "str.h"
#include "quota-private.h"
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#define MAILDIRSIZE_FILENAME "maildirsize"
#define MAILDIRSIZE_STALE_SECS (60*15)
struct maildir_quota_root {
struct quota_root root;
uint64_t message_bytes_limit;
uint64_t message_count_limit;
uint64_t total_bytes;
uint64_t total_count;
int fd;
};
struct maildir_list_context {
struct mailbox_list_context *ctx;
struct mailbox_list *list;
string_t *path;
int state;
};
extern struct quota_backend quota_backend_maildir;
const struct dotlock_settings dotlock_settings = {
MEMBER(temp_prefix) NULL,
MEMBER(lock_suffix) NULL,
MEMBER(timeout) 0,
MEMBER(stale_timeout) 30,
MEMBER(callback) NULL,
MEMBER(context) NULL,
MEMBER(use_excl_lock) FALSE
};
static int maildir_sum_dir(struct mail_storage *storage, const char *dir,
uint64_t *total_bytes, uint64_t *total_count)
{
DIR *dirp;
struct dirent *dp;
string_t *path;
const char *p;
size_t len;
uoff_t num;
int ret = 0;
dirp = opendir(dir);
if (dirp == NULL) {
if (errno == ENOENT || errno == ESTALE)
return 0;
mail_storage_set_critical(storage, "opendir(%s) failed: %m",
dir);
return -1;
}
path = t_str_new(256);
str_append(path, dir);
str_append_c(path, '/');
len = str_len(path);
while ((dp = readdir(dirp)) != NULL) {
p = strstr(dp->d_name, ",S=");
num = (uoff_t)-1;
if (p != NULL) {
/* ,S=nnnn[:,] */
p += 3;
for (num = 0; *p >= '0' && *p <= '9'; p++)
num = num * 10 + (*p - '0');
if (*p != ':' && *p != '\0' && *p != ',') {
/* not in expected format, fallback to stat() */
num = (uoff_t)-1;
} else {
*total_bytes += num;
*total_count += 1;
}
}
if (num == (uoff_t)-1) {
struct stat st;
str_truncate(path, len);
str_append(path, dp->d_name);
if (stat(str_c(path), &st) == 0) {
*total_bytes += st.st_size;
*total_count += 1;
} else if (errno != ENOENT && errno != ESTALE) {
mail_storage_set_critical(storage,
"stat(%s) failed: %m", str_c(path));
ret = -1;
}
}
}
if (closedir(dirp) < 0) {
mail_storage_set_critical(storage, "closedir(%s) failed: %m",
dir);
return -1;
}
return ret;
}
static struct maildir_list_context *
maildir_list_init(struct mail_storage *storage)
{
struct maildir_list_context *ctx;
ctx = i_new(struct maildir_list_context, 1);
ctx->path = str_new(default_pool, 512);
ctx->ctx = mail_storage_mailbox_list_init(storage, "", "*",
MAILBOX_LIST_FAST_FLAGS |
MAILBOX_LIST_INBOX);
return ctx;
}
static const char *
maildir_list_next(struct maildir_list_context *ctx, time_t *mtime_r)
{
struct stat st;
const char *path;
bool is_file;
for (;;) {
if (ctx->state == 0) {
ctx->list = mail_storage_mailbox_list_next(ctx->ctx);
if (ctx->list == NULL)
return NULL;
}
t_push();
path = mail_storage_get_mailbox_path(ctx->ctx->storage,
ctx->list->name,
&is_file);
str_truncate(ctx->path, 0);
str_append(ctx->path, path);
str_append(ctx->path, ctx->state == 0 ? "/new" : "/cur");
t_pop();
if (++ctx->state == 2)
ctx->state = 0;
if (stat(str_c(ctx->path), &st) == 0)
break;
/* ignore if the directory got lost, stale or if it was
actually a file and not a directory */
if (errno != ENOENT && errno != ESTALE && errno != ENOTDIR) {
mail_storage_set_critical(ctx->ctx->storage,
"stat(%s) failed: %m", str_c(ctx->path));
ctx->state = 0;
}
}
*mtime_r = st.st_size;
return str_c(ctx->path);
}
static int maildir_list_deinit(struct maildir_list_context *ctx)
{
int ret = mail_storage_mailbox_list_deinit(&ctx->ctx);
str_free(&ctx->path);
i_free(ctx);
return ret;
}
static int
maildirs_check_have_changed(struct mail_storage *storage, time_t latest_mtime)
{
struct maildir_list_context *ctx;
const char *dir;
time_t mtime;
int ret = 0;
ctx = maildir_list_init(storage);
while ((dir = maildir_list_next(ctx, &mtime)) != NULL) {
if (mtime > latest_mtime) {
ret = 1;
break;
}
}
if (maildir_list_deinit(ctx) < 0)
return -1;
return ret;
}
static int maildirsize_write(struct maildir_quota_root *root,
struct mail_storage *storage, const char *path)
{
struct dotlock *dotlock;
string_t *str;
int fd;
fd = file_dotlock_open(&dotlock_settings, path,
DOTLOCK_CREATE_FLAG_NONBLOCK, &dotlock);
if (fd == -1) {
if (errno == EAGAIN) {
/* someone's just in the middle of updating it */
return -1;
}
mail_storage_set_critical(storage,
"file_dotlock_open(%s) failed: %m", path);
return -1;
}
str = t_str_new(128);
if (root->message_bytes_limit != (uint64_t)-1) {
str_printfa(str, "S=%llu",
(unsigned long long)root->message_bytes_limit);
}
if (root->message_count_limit != (uint64_t)-1) {
if (str_len(str) > 0)
str_append_c(str, ',');
str_printfa(str, "C=%llu",
(unsigned long long)root->message_count_limit);
}
str_printfa(str, "\n%llu %llu\n",
(unsigned long long)root->total_bytes,
(unsigned long long)root->total_count);
if (write_full(fd, str_data(str), str_len(str)) < 0) {
mail_storage_set_critical(storage,
"write_full(%s) failed: %m", path);
file_dotlock_delete(&dotlock);
return -1;
}
if (file_dotlock_replace(&dotlock, 0) < 0) {
mail_storage_set_critical(storage,
"file_dotlock_replace(%s) failed: %m", path);
return -1;
}
return 0;
}
static const char *maildirsize_get_path(struct mail_storage *storage)
{
return t_strconcat(mail_storage_get_mailbox_control_dir(storage, ""),
"/"MAILDIRSIZE_FILENAME, NULL);
}
static int maildirsize_recalculate(struct maildir_quota_root *root,
struct mail_storage *storage)
{
struct maildir_list_context *ctx;
const char *dir, *path;
time_t mtime, last_stamp = 0;
int ret = 0;
root->total_bytes = root->total_count = 0;
ctx = maildir_list_init(storage);
while ((dir = maildir_list_next(ctx, &mtime)) != NULL) {
if (mtime > last_stamp)
last_stamp = mtime;
t_push();
if (maildir_sum_dir(storage, dir,
&root->total_bytes,
&root->total_count) < 0)
ret = -1;
t_pop();
}
if (maildir_list_deinit(ctx) < 0)
ret = -1;
if (ret == 0)
ret = maildirs_check_have_changed(storage, last_stamp);
t_push();
path = maildirsize_get_path(storage);
if (ret == 0) {
/* maildir didn't change, we can write the maildirsize file */
ret = maildirsize_write(root, storage, path);
}
if (ret != 0) {
/* make sure it gets rebuilt later */
if (unlink(path) < 0 && errno != ENOENT && errno != ESTALE) {
mail_storage_set_critical(storage,
"unlink(%s) failed: %m", path);
}
}
t_pop();
return ret;
}
static int maildirsize_parse(struct maildir_quota_root *root,
int fd, const char *const *lines)
{
unsigned long long bytes;
long long bytes_diff, total_bytes;
int count_diff, total_count;
unsigned int line_count = 0;
const char *const *limit;
char *pos;
if (*lines == NULL)
return -1;
/* first line contains the limits */
root->message_bytes_limit = (uint64_t)-1;
root->message_count_limit = (uint64_t)-1;
for (limit = t_strsplit(lines[0], ","); *limit != NULL; limit++) {
bytes = strtoull(*limit, &pos, 10);
if (pos[0] != '\0' && pos[1] == '\0') {
switch (pos[0]) {
case 'C':
root->message_count_limit = bytes;
break;
case 'S':
root->message_bytes_limit = bytes;
break;
}
}
}
/* rest of the lines contains <bytes> <count> diffs */
total_bytes = 0; total_count = 0;
for (lines++; **lines != '\0'; lines++, line_count++) {
if (sscanf(*lines, "%lld %d", &bytes_diff, &count_diff) != 2)
return -1;
total_bytes += bytes_diff;
total_count += count_diff;
}
/* we end always with LF, which shows up as empty last line. there
should be no other empty lines */
if (lines[1] != NULL)
return -1;
if (total_bytes < 0 || total_count < 0) {
/* corrupted */
return -1;
}
if ((uint64_t)total_bytes > root->message_bytes_limit ||
(uint64_t)total_count > root->message_count_limit) {
/* we're over quota. don't trust these values if the file
contains more than the initial summary line, or if the file
is older than 15 minutes. */
struct stat st;
if (line_count > 1)
return 0;
if (fstat(fd, &st) < 0 ||
st.st_mtime < ioloop_time - MAILDIRSIZE_STALE_SECS)
return 0;
}
root->total_bytes = (uint64_t)total_bytes;
root->total_count = (uint64_t)total_count;
return 1;
}
static int maildirsize_read(struct maildir_quota_root *root,
struct mail_storage *storage)
{
const char *path;
char buf[5120+1];
unsigned int size;
int fd, ret;
t_push();
path = maildirsize_get_path(storage);
if (root->fd != -1) {
if (close(root->fd) < 0) {
mail_storage_set_critical(storage,
"close(%s) failed: %m", path);
}
root->fd = -1;
}
fd = nfs_safe_open(path, O_RDWR | O_APPEND);
if (fd == -1) {
if (errno == ENOENT)
ret = 0;
else {
ret = -1;
mail_storage_set_critical(storage,
"open(%s) failed: %m", path);
}
t_pop();
return ret;
}
size = 0;
while ((ret = read(fd, buf, sizeof(buf)-1)) != 0) {
if (ret < 0) {
if (errno == ESTALE)
break;
mail_storage_set_critical(storage, "read(%s) failed: %m",
path);
}
size += ret;
}
if (ret < 0 || size == sizeof(buf)-1) {
/* error / recalculation needed. */
(void)close(fd);
t_pop();
return ret < 0 ? -1 : 0;
}
/* file is smaller than 5120 bytes, which means we can use it */
root->total_bytes = root->total_count = 0;
/* skip the last line if there's no LF at the end */
while (size > 0 && buf[size-1] != '\n') size--;
buf[size] = '\0';
if (maildirsize_parse(root, fd, t_strsplit(buf, "\n")) > 0) {
root->fd = fd;
ret = 1;
} else {
/* broken file / need recalculation */
(void)close(root->fd);
root->fd = -1;
ret = 0;
}
t_pop();
return ret;
}
static int maildirquota_refresh(struct maildir_quota_root *root,
struct mail_storage *storage)
{
int ret;
ret = maildirsize_read(root, storage);
if (ret == 0)
ret = maildirsize_recalculate(root, storage);
return ret < 0 ? -1 : 0;
}
static int maildirsize_update(struct maildir_quota_root *root,
struct mail_storage *storage,
int count_diff, int64_t bytes_diff)
{
const char *str;
int ret = 0;
t_push();
/* We rely on O_APPEND working in here. That isn't NFS-safe, but it
isn't necessarily that bad because the file is recreated once in
a while, and sooner if corruption cases calculations to go
over quota. This is also how Maildir++ spec specifies it should be
done.. */
str = t_strdup_printf("%d %lld\n", count_diff, (long long)bytes_diff);
if (write_full(root->fd, str, strlen(str)) < 0) {
ret = -1;
if (errno == ESTALE) {
/* deleted/replaced already, ignore */
} else {
mail_storage_set_critical(storage,
"write_full(%s) failed: %m",
maildirsize_get_path(storage));
}
}
t_pop();
return ret;
}
static struct quota_root *
maildir_quota_init(struct quota_setup *setup __attr_unused__,
const char *name __attr_unused__)
{
struct maildir_quota_root *root;
root = i_new(struct maildir_quota_root, 1);
root->root.name = i_strdup(name);
root->root.v = quota_backend_maildir.v;
root->fd = -1;
root->message_bytes_limit = (uint64_t)-1;
root->message_count_limit = (uint64_t)-1;
return &root->root;
}
static void maildir_quota_deinit(struct quota_root *_root)
{
struct maildir_quota_root *root = (struct maildir_quota_root *)_root;
i_free(root->root.name);
i_free(root);
}
static bool
maildir_quota_add_storage(struct quota_root *root __attr_unused__,
struct mail_storage *storage __attr_unused__)
{
return TRUE;
}
static void
maildir_quota_remove_storage(struct quota_root *root __attr_unused__,
struct mail_storage *storage __attr_unused__)
{
}
static const char *const *
maildir_quota_root_get_resources(struct quota_root *root __attr_unused__)
{
static const char *resources_both[] = {
QUOTA_NAME_STORAGE,
QUOTA_NAME_MESSAGES,
NULL
};
return resources_both;
}
static struct mail_storage *
maildir_quota_root_get_storage(struct quota_root *root)
{
/* FIXME: figure out how to support multiple storages */
struct mail_storage *const *storages;
unsigned int count;
storages = array_get(&root->storages, &count);
i_assert(count > 0);
return storages[0];
}
static int
maildir_quota_get_resource(struct quota_root *_root, const char *name,
uint64_t *value_r, uint64_t *limit_r)
{
struct maildir_quota_root *root = (struct maildir_quota_root *)_root;
if (maildirquota_refresh(root,
maildir_quota_root_get_storage(_root)) < 0)
return -1;
if (strcmp(name, QUOTA_NAME_STORAGE) == 0) {
*limit_r = root->message_bytes_limit / 1024;
*value_r = root->total_bytes / 1024;
} else {
*limit_r = root->message_count_limit;
*value_r = root->total_count;
}
return 0;
}
static int
maildir_quota_set_resource(struct quota_root *root,
const char *name __attr_unused__,
uint64_t value __attr_unused__)
{
quota_set_error(root->setup->quota, MAIL_STORAGE_ERR_NO_PERMISSION);
return -1;
}
static struct quota_root_transaction_context *
maildir_quota_transaction_begin(struct quota_root *_root,
struct quota_transaction_context *_ctx)
{
struct maildir_quota_root *root = (struct maildir_quota_root *)_root;
struct quota_root_transaction_context *ctx;
ctx = i_new(struct quota_root_transaction_context, 1);
ctx->root = _root;
ctx->ctx = _ctx;
if (maildirquota_refresh(root,
maildir_quota_root_get_storage(_root)) == 0) {
ctx->bytes_limit = root->message_bytes_limit;
ctx->count_limit = root->message_count_limit;
ctx->bytes_current = root->total_bytes;
ctx->count_current = root->total_count;
}
return ctx;
}
static int
maildir_quota_transaction_commit(struct quota_root_transaction_context *ctx)
{
struct maildir_quota_root *root =
(struct maildir_quota_root *)ctx->root;
if (root->fd != -1) {
/* if writing fails, we don't care all that much */
(void)maildirsize_update(root,
maildir_quota_root_get_storage(ctx->root),
ctx->count_diff, ctx->bytes_diff);
}
i_free(ctx);
return 0;
}
static void
maildir_quota_transaction_rollback(struct quota_root_transaction_context *ctx)
{
i_free(ctx);
}
static int
maildir_quota_try_alloc_bytes(struct quota_root_transaction_context *ctx,
uoff_t size, bool *too_large_r)
{
*too_large_r = size > ctx->bytes_limit;
if (ctx->bytes_current + ctx->bytes_diff + size > ctx->bytes_limit)
return 0;
if (ctx->count_current + ctx->count_diff + 1 > ctx->count_limit)
return 0;
ctx->count_diff++;
ctx->bytes_diff += size;
return 1;
}
static int
maildir_quota_try_alloc(struct quota_root_transaction_context *ctx,
struct mail *mail, bool *too_large_r)
{
uoff_t size;
size = mail_get_physical_size(mail);
if (size == (uoff_t)-1)
return -1;
return maildir_quota_try_alloc_bytes(ctx, size, too_large_r);
}
static void
maildir_quota_alloc(struct quota_root_transaction_context *ctx,
struct mail *mail)
{
uoff_t size;
size = mail_get_physical_size(mail);
if (size != (uoff_t)-1)
ctx->bytes_diff += size;
ctx->count_diff++;
}
static void
maildir_quota_free(struct quota_root_transaction_context *ctx,
struct mail *mail)
{
uoff_t size;
size = mail_get_physical_size(mail);
if (size != (uoff_t)-1)
ctx->bytes_diff -= size;
ctx->count_diff--;
}
struct quota_backend quota_backend_maildir = {
"maildir",
{
maildir_quota_init,
maildir_quota_deinit,
maildir_quota_add_storage,
maildir_quota_remove_storage,
maildir_quota_root_get_resources,
maildir_quota_get_resource,
maildir_quota_set_resource,
maildir_quota_transaction_begin,
maildir_quota_transaction_commit,
maildir_quota_transaction_rollback,
maildir_quota_try_alloc,
maildir_quota_try_alloc_bytes,
maildir_quota_alloc,
maildir_quota_free
}
};
Index: quota-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/plugins/quota/quota-private.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- quota-private.h 1 Mar 2006 09:15:03 -0000 1.5
+++ quota-private.h 6 Mar 2006 10:31:11 -0000 1.6
@@ -97,8 +97,8 @@
int count_diff;
int64_t bytes_diff;
- uint64_t storage_limit;
- uint64_t storage_current;
+ uint64_t bytes_limit, count_limit;
+ uint64_t bytes_current, count_current;
};
/* Register storage to all user's quota roots. */
Index: quota.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/plugins/quota/quota.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- quota.c 1 Mar 2006 09:15:03 -0000 1.6
+++ quota.c 6 Mar 2006 10:31:11 -0000 1.7
@@ -8,16 +8,18 @@
unsigned int quota_module_id = 0;
-extern struct quota_backend quota_backend_dirsize;
extern struct quota_backend quota_backend_dict;
+extern struct quota_backend quota_backend_dirsize;
extern struct quota_backend quota_backend_fs;
+extern struct quota_backend quota_backend_maildir;
static struct quota_backend *quota_backends[] = {
- "a_backend_dirsize,
- "a_backend_dict,
#ifdef HAVE_FS_QUOTA
- "a_backend_fs
+ "a_backend_fs,
#endif
+ "a_backend_dict,
+ "a_backend_dirsize,
+ "a_backend_maildir
};
#define QUOTA_CLASS_COUNT (sizeof(quota_backends)/sizeof(quota_backends[0]))
- Previous message: [dovecot-cvs] dovecot/src/lib-storage/index/maildir maildir-list.c,
1.39, 1.40
- Next message: [dovecot-cvs] dovecot/src/plugins/quota quota-dirsize.c, 1.7,
1.8 quota-fs.c, 1.9, 1.10 quota-maildir.c, 1.1,
1.2 quota-private.h, 1.6, 1.7 quota.c, 1.7, 1.8
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list