219
219
static int maildirsize_write(struct maildir_quota_root *root, const char *path)
221
const struct quota_rule *rule = &root->root.default_rule;
221
struct quota_root *_root = &root->root;
222
struct mail_storage *const *storages;
223
unsigned int i, count;
222
224
struct dotlock *dotlock;
225
const char *p, *dir, *gid_origin, *dir_gid_origin;
227
mode_t mode, dir_mode;
227
231
i_assert(root->fd == -1);
233
/* figure out what permissions we should use for maildirsize.
234
use the inbox namespace's permissions if possible. */
235
mode = 0600; dir_mode = 0700; gid_origin = "default";
236
gid = dir_gid = (gid_t)-1;
237
storages = array_get(&root->root.quota->storages, &count);
238
for (i = 0; i < count; i++) {
239
if ((storages[i]->ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
240
mailbox_list_get_permissions(storages[i]->ns->list,
243
mailbox_list_get_dir_permissions(storages[i]->ns->list,
229
251
dotlock_settings.use_excl_lock = getenv("DOTLOCK_USE_EXCL") != NULL;
230
252
dotlock_settings.nfs_flush = getenv("MAIL_NFS_STORAGE") != NULL;
231
fd = file_dotlock_open(&dotlock_settings, path,
232
DOTLOCK_CREATE_FLAG_NONBLOCK, &dotlock);
253
fd = file_dotlock_open_group(&dotlock_settings, path,
254
DOTLOCK_CREATE_FLAG_NONBLOCK,
255
mode, gid, gid_origin, &dotlock);
233
256
if (fd == -1 && errno == ENOENT) {
234
257
/* the control directory doesn't exist yet? create it */
235
258
p = strrchr(path, '/');
236
259
dir = t_strdup_until(path, p);
237
if (mkdir_parents(dir, 0700) < 0 && errno != EEXIST) {
260
if (mkdir_parents_chgrp(dir, dir_mode, dir_gid,
261
dir_gid_origin) < 0 &&
238
263
i_error("mkdir_parents(%s) failed: %m", dir);
241
fd = file_dotlock_open(&dotlock_settings, path,
242
DOTLOCK_CREATE_FLAG_NONBLOCK, &dotlock);
266
fd = file_dotlock_open_group(&dotlock_settings, path,
267
DOTLOCK_CREATE_FLAG_NONBLOCK,
268
mode, gid, gid_origin, &dotlock);
245
271
if (errno == EAGAIN) {
254
280
str = t_str_new(128);
255
281
/* if we have no limits, write 0S instead of an empty line */
256
if (rule->bytes_limit != 0 || rule->count_limit == 0) {
282
if (_root->bytes_limit != 0 || _root->count_limit == 0) {
257
283
str_printfa(str, "%lluS",
258
(unsigned long long)rule->bytes_limit);
284
(unsigned long long)_root->bytes_limit);
260
if (rule->count_limit != 0) {
286
if (_root->count_limit != 0) {
261
287
if (str_len(str) > 0)
262
288
str_append_c(str, ',');
263
289
str_printfa(str, "%lluC",
264
(unsigned long long)rule->count_limit);
290
(unsigned long long)_root->count_limit);
266
292
str_printfa(str, "\n%llu %llu\n",
267
293
(unsigned long long)root->total_bytes,
349
375
/* count mails from all storages */
350
376
storages = array_get(&root->root.quota->storages, &count);
351
377
for (i = 0; i < count; i++) {
378
if (!quota_root_is_storage_visible(&root->root, storages[i]))
352
381
if (maildirsize_recalculate_storage(root, storages[i]) < 0) {
359
388
/* check if any of the directories have changed */
360
389
for (i = 0; i < count; i++) {
390
if (!quota_root_is_storage_visible(&root->root,
361
394
ret = maildirs_check_have_changed(root, storages[i],
362
395
root->recalc_last_stamp);
406
439
static int maildirsize_parse(struct maildir_quota_root *root,
407
440
int fd, const char *const *lines)
409
struct quota_rule *rule = &root->root.default_rule;
442
struct quota_root *_root = &root->root;
410
443
uint64_t message_bytes_limit, message_count_limit;
411
444
long long bytes_diff, total_bytes;
412
445
int count_diff, total_count;
425
458
if (message_count_limit >= (1ULL << 63))
426
459
message_count_limit = (1ULL << 63) - 1;
428
if (rule->bytes_limit == (int64_t)message_bytes_limit &&
429
rule->count_limit == (int64_t)message_count_limit) {
461
if (root->root.bytes_limit == (int64_t)message_bytes_limit &&
462
root->root.count_limit == (int64_t)message_count_limit) {
430
463
/* limits haven't changed */
431
} else if (root->root.force_default_rule) {
464
} else if (root->root.set->force_default_rule) {
432
465
/* we know the limits and they've changed.
433
466
the file must be rewritten. */
436
469
/* we're using limits from the file. */
437
rule->bytes_limit = message_bytes_limit;
438
rule->count_limit = message_count_limit;
439
quota_root_recalculate_relative_rules(&root->root);
470
root->root.bytes_limit = message_bytes_limit;
471
root->root.count_limit = message_count_limit;
472
quota_root_recalculate_relative_rules(root->root.set);
442
475
if (*lines == NULL) {
462
if ((total_bytes > rule->bytes_limit && rule->bytes_limit != 0) ||
463
(total_count > rule->count_limit && rule->count_limit != 0)) {
495
if ((total_bytes > _root->bytes_limit && _root->bytes_limit != 0) ||
496
(total_count > _root->count_limit && _root->count_limit != 0)) {
464
497
/* we're over quota. don't trust these values if the file
465
498
contains more than the initial summary line, or if the file
466
499
is older than 15 minutes. */
595
628
return root->maildirsize_path != NULL;
598
static int maildirquota_refresh(struct maildir_quota_root *root)
631
static int maildirquota_read_limits(struct maildir_quota_root *root)
602
635
if (!maildirquota_limits_init(root))
606
639
ret = maildirsize_read(root);
645
maildirquota_refresh(struct maildir_quota_root *root, bool *recalculated_r)
649
*recalculated_r = FALSE;
651
ret = maildirquota_read_limits(root);
609
if (root->root.default_rule.bytes_limit == 0 &&
610
root->root.default_rule.count_limit == 0) {
653
if (root->root.bytes_limit == 0 &&
654
root->root.count_limit == 0 &&
655
root->root.set->default_rule.bytes_limit == 0 &&
656
root->root.set->default_rule.count_limit == 0) {
612
if (!root->root.force_default_rule)
658
if (!root->root.set->force_default_rule)
614
660
/* explicitly specified 0 as quota. keep the quota
615
661
updated even if it's not enforced. */
618
664
ret = maildirsize_recalculate(root);
666
*recalculated_r = TRUE;
620
668
return ret < 0 ? -1 : 0;
657
705
return &root->root;
708
static int maildir_quota_init(struct quota_root *_root, const char *args)
710
const char *const *tmp;
715
for (tmp = t_strsplit(args, ":"); *tmp != NULL; tmp++) {
716
if (strcmp(*tmp, "noenforcing") == 0)
717
_root->no_enforcing = TRUE;
718
else if (strncmp(*tmp, "ns=", 3) == 0)
719
_root->ns_prefix = p_strdup(_root->pool, *tmp + 3);
721
i_error("maildir quota: Invalid parameter: %s", *tmp);
660
728
static void maildir_quota_deinit(struct quota_root *_root)
662
730
struct maildir_quota_root *root = (struct maildir_quota_root *)_root;
711
786
roots = array_get_modifiable("a->roots, &count);
712
787
for (i = 0; i < count; i++) {
713
if (roots[i]->backend.name == quota_backend_maildir.name)
788
if (roots[i]->backend.name == quota_backend_maildir.name &&
789
((roots[i]->ns_prefix == NULL &&
790
storage->ns->type == NAMESPACE_PRIVATE) ||
791
roots[i]->ns == storage->ns))
714
792
maildir_quota_root_storage_added(roots[i], storage);
749
828
maildir_quota_update(struct quota_root *_root,
750
829
struct quota_transaction_context *ctx)
752
struct maildir_quota_root *root =
753
(struct maildir_quota_root *) _root;
831
struct maildir_quota_root *root = (struct maildir_quota_root *)_root;
755
834
if (!maildirquota_limits_init(root)) {
761
840
we do want to make sure the header gets updated if the limits have
762
841
changed. also this makes sure the maildirsize file is created if
763
842
it doesn't exist. */
764
if (maildirquota_refresh(root) < 0)
843
if (maildirquota_refresh(root, &recalculated) < 0)
767
if (root->fd == -1 || ctx->recalculate ||
768
maildirsize_update(root, ctx->count_used, ctx->bytes_used) < 0)
847
/* quota was just recalculated and it already contains the changes
849
} else if (root->fd == -1 || ctx->recalculate)
850
maildirsize_rebuild_later(root);
851
else if (maildirsize_update(root, ctx->count_used, ctx->bytes_used) < 0)
769
852
maildirsize_rebuild_later(root);
778
861
maildir_quota_alloc,
780
863
maildir_quota_deinit,
781
864
maildir_quota_parse_rule,
865
maildir_quota_init_limits,
782
866
maildir_quota_storage_added,
783
867
maildir_quota_root_get_resources,
784
868
maildir_quota_get_resource,
869
maildir_quota_update,