Mercurial > dovecot > core-2.2
changeset 20387:d87dda55464b
lib-storage: Add autoexpunge_max_mails configuration to autoexpunge
Mails are expunged until mail count is at autoexpunge_max_mails or below.
In below example, autoexpunge will expunge 1 mail when message count > 100
and *then* try to expunge mails that are still older than 2 minutes:
namespace {
..
mailbox Trash {
autoexpunge = 2 mins
autoexpunge_max_mails = 100
}
}
author | Baofeng Wang <baofeng.wang@dovecot.fi> |
---|---|
date | Mon, 20 Jun 2016 15:10:55 +0300 |
parents | 564a32262929 |
children | 056cab1babda |
files | src/lib-storage/mail-autoexpunge.c src/lib-storage/mail-storage-settings.c src/lib-storage/mail-storage-settings.h |
diffstat | 3 files changed, 41 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/mail-autoexpunge.c Tue Jun 21 12:04:24 2016 +0300 +++ b/src/lib-storage/mail-autoexpunge.c Mon Jun 20 15:10:55 2016 +0300 @@ -8,20 +8,35 @@ #include "mail-user.h" #include "mail-autoexpunge.h" -static int mailbox_autoexpunge(struct mailbox *box, time_t expire_time) +static int +mailbox_autoexpunge(struct mailbox *box, unsigned int interval_time, + unsigned int max_mails) { struct mailbox_transaction_context *t; struct mail *mail; struct mailbox_metadata metadata; const struct mail_index_header *hdr; + struct mailbox_status status; uint32_t seq; - time_t timestamp; + time_t timestamp, expire_time; int ret = 0; + if ((unsigned int)ioloop_time < interval_time) + expire_time = 0; + else + expire_time = ioloop_time - interval_time; + /* first try to check quickly from mailbox list index if we should bother opening this mailbox. */ - if (mailbox_get_metadata(box, MAILBOX_METADATA_FIRST_SAVE_DATE, - &metadata) == 0) { + if (mailbox_get_status(box, STATUS_MESSAGES, &status) < 0) + return -1; + if (interval_time == 0 && status.messages <= max_mails) + return 0; + + if (max_mails == 0 || status.messages <= max_mails) { + if (mailbox_get_metadata(box, MAILBOX_METADATA_FIRST_SAVE_DATE, + &metadata) < 0) + return -1; if (metadata.first_save_date == (time_t)-1 || metadata.first_save_date > expire_time) return 0; @@ -41,7 +56,15 @@ hdr = mail_index_get_header(box->view); for (seq = 1; seq <= hdr->messages_count; seq++) { mail_set_seq(mail, seq); - if (mail_get_save_date(mail, ×tamp) == 0) { + if (max_mails > 0 && hdr->messages_count - seq + 1 > max_mails) { + /* max_mails is still being reached -> expunge. + don't even check saved-dates before we're + below max_mails. */ + mail_expunge(mail); + } else if (interval_time == 0) { + /* only max_mails is used. nothing further to do. */ + break; + } else if (mail_get_save_date(mail, ×tamp) == 0) { if (timestamp > expire_time) break; mail_expunge(mail); @@ -61,18 +84,16 @@ static void mailbox_autoexpunge_set(struct mail_namespace *ns, const char *vname, - unsigned int autoexpunge) + unsigned int autoexpunge, + unsigned int autoexpunge_max_mails) { struct mailbox *box; - time_t expire_time; - - expire_time = ioloop_time - autoexpunge; /* autoexpunge is configured by admin, so we can safely ignore any ACLs the user might normally have against expunging in the mailbox. */ box = mailbox_alloc(ns->list, vname, MAILBOX_FLAG_IGNORE_ACLS); - if (mailbox_autoexpunge(box, expire_time) < 0) { + if (mailbox_autoexpunge(box, autoexpunge, autoexpunge_max_mails) < 0) { i_error("Failed to autoexpunge mailbox '%s': %s", mailbox_get_vname(box), mailbox_get_last_error(box, NULL)); @@ -92,7 +113,8 @@ MAILBOX_LIST_ITER_SKIP_ALIASES | MAILBOX_LIST_ITER_RETURN_NO_FLAGS); while ((info = mailbox_list_iter_next(iter)) != NULL) T_BEGIN { - mailbox_autoexpunge_set(ns, info->vname, set->autoexpunge); + mailbox_autoexpunge_set(ns, info->vname, set->autoexpunge, + set->autoexpunge_max_mails); } T_END; if (mailbox_list_iter_deinit(&iter) < 0) { i_error("Failed to iterate autoexpunge mailboxes '%s%s': %s", @@ -110,8 +132,8 @@ return; array_foreach(&ns->set->mailboxes, box_set) { - if ((*box_set)->autoexpunge == 0 || - (unsigned int)ioloop_time < (*box_set)->autoexpunge) + if ((*box_set)->autoexpunge == 0 && + (*box_set)->autoexpunge_max_mails == 0) continue; if (strpbrk((*box_set)->name, "*?") != NULL) @@ -122,7 +144,8 @@ vname = t_strndup(ns->prefix, ns->prefix_len - 1); else vname = t_strconcat(ns->prefix, (*box_set)->name, NULL); - mailbox_autoexpunge_set(ns, vname, (*box_set)->autoexpunge); + mailbox_autoexpunge_set(ns, vname, (*box_set)->autoexpunge, + (*box_set)->autoexpunge_max_mails); } } }
--- a/src/lib-storage/mail-storage-settings.c Tue Jun 21 12:04:24 2016 +0300 +++ b/src/lib-storage/mail-storage-settings.c Mon Jun 20 15:10:55 2016 +0300 @@ -127,6 +127,7 @@ DEF(SET_STR, driver), DEF(SET_STR, comment), DEF(SET_TIME, autoexpunge), + DEF(SET_UINT, autoexpunge_max_mails), SETTING_DEFINE_LIST_END }; @@ -139,7 +140,8 @@ .special_use = "", .driver = "", .comment = "", - .autoexpunge = 0 + .autoexpunge = 0, + .autoexpunge_max_mails = 0 }; const struct setting_parser_info mailbox_setting_parser_info = {
--- a/src/lib-storage/mail-storage-settings.h Tue Jun 21 12:04:24 2016 +0300 +++ b/src/lib-storage/mail-storage-settings.h Mon Jun 20 15:10:55 2016 +0300 @@ -82,6 +82,7 @@ const char *driver; const char *comment; unsigned int autoexpunge; + unsigned int autoexpunge_max_mails; }; struct mail_user_settings {