From: Timo Sirainen Date: Fri, 7 Mar 2025 10:27:06 +0000 (+0200) Subject: lib-storage: Try to use cached mailbox settings X-Git-Tag: 2.4.1~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f5e126ef73f8333e772b9d24c228e053fd6fc186;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Try to use cached mailbox settings --- diff --git a/src/lib-storage/mail-storage-private.h b/src/lib-storage/mail-storage-private.h index f93f9204c8..eaeb202013 100644 --- a/src/lib-storage/mail-storage-private.h +++ b/src/lib-storage/mail-storage-private.h @@ -931,6 +931,12 @@ static inline const char *mailbox_name_sanitize(const char *name) struct event * mail_storage_mailbox_create_event(struct event *parent, struct mailbox_list *list, const char *vname); +/* Try to get mailbox_settings for a mailbox. Returns 1 on success, -1 on + error, 0 if settings need to be merged and caller should be calling + settings_get() instead with the mailbox event. */ +int mailbox_name_try_get_settings(struct mailbox_list *list, const char *vname, + const struct mailbox_settings **set_r, + const char **error_r); /* for unit testing */ int mailbox_verify_name(struct mailbox *box); diff --git a/src/lib-storage/mail-storage.c b/src/lib-storage/mail-storage.c index b172440fec..ca51ab5d13 100644 --- a/src/lib-storage/mail-storage.c +++ b/src/lib-storage/mail-storage.c @@ -1048,6 +1048,55 @@ bool mail_storage_set_error_from_errno(struct mail_storage *storage) return TRUE; } +static int +mailbox_list_get_default_box_settings(struct mailbox_list *list, + const struct mailbox_settings **set_r, + const char **error_r) +{ + if (list->default_box_set == NULL) { + if (settings_get(list->event, + &mailbox_setting_parser_info, 0, + &list->default_box_set, error_r) < 0) + return -1; + } + pool_ref(list->default_box_set->pool); + *set_r = list->default_box_set; + return 1; +} + +int mailbox_name_try_get_settings(struct mailbox_list *list, const char *vname, + const struct mailbox_settings **set_r, + const char **error_r) +{ + if (array_is_empty(&list->ns->set->mailboxes)) + return mailbox_list_get_default_box_settings(list, set_r, error_r); + + const char *vname_without_prefix = + mailbox_get_name_without_prefix(list->ns, vname); + unsigned int i, count; + const struct mailbox_settings *set = NULL, *const *mailboxes = + array_get(&list->ns->set->parsed_mailboxes, &count); + + for (i = 0; i < count; i++) { + if (!wildcard_match(vname_without_prefix, mailboxes[i]->name)) + continue; + + if (set == NULL) + set = mailboxes[i]; + else { + /* multiple mailbox named list filters match - need to + lookup settings to get them merged. */ + return 0; + } + } + if (set == NULL) + return mailbox_list_get_default_box_settings(list, set_r, error_r); + + pool_ref(set->pool); + *set_r = set; + return 1; +} + struct mailbox *mailbox_alloc(struct mailbox_list *list, const char *vname, enum mailbox_flags flags) { @@ -1082,8 +1131,10 @@ struct mailbox *mailbox_alloc(struct mailbox_list *list, const char *vname, } T_BEGIN { - const char *orig_vname = vname; + const char *error, *orig_vname = vname; enum mailbox_list_get_storage_flags storage_flags = 0; + int ret; + if ((flags & MAILBOX_FLAG_SAVEONLY) != 0) storage_flags |= MAILBOX_LIST_GET_STORAGE_FLAG_SAVEONLY; if (mailbox_list_get_storage(&new_list, &vname, @@ -1095,15 +1146,20 @@ struct mailbox *mailbox_alloc(struct mailbox_list *list, const char *vname, } box = storage->v.mailbox_alloc(storage, new_list, vname, flags); - const char *error; if (open_error != 0) { box->open_error = open_error; mail_storage_set_error(storage, open_error, errstr); - } else if (settings_get(box->event, - &mailbox_setting_parser_info, 0, - &box->set, &error) < 0) { + } else if ((ret = mailbox_name_try_get_settings(box->list, + vname, &box->set, &error)) < 0) { mailbox_set_critical(box, "%s", error); box->open_error = box->storage->error; + } else if (ret == 0) { + if (settings_get(box->event, + &mailbox_setting_parser_info, 0, + &box->set, &error) < 0) { + mailbox_set_critical(box, "%s", error); + box->open_error = box->storage->error; + } } if (strcmp(orig_vname, vname) != 0) box->mailbox_not_original = TRUE; diff --git a/src/lib-storage/mailbox-list-private.h b/src/lib-storage/mailbox-list-private.h index f39c9830ca..0e078cfe50 100644 --- a/src/lib-storage/mailbox-list-private.h +++ b/src/lib-storage/mailbox-list-private.h @@ -114,6 +114,7 @@ struct mailbox_list { pool_t pool; struct mail_namespace *ns; const struct mail_storage_settings *mail_set; + const struct mailbox_settings *default_box_set; enum mailbox_list_flags flags; /* may not be set yet, use mailbox_list_get_permissions() to access */ diff --git a/src/lib-storage/mailbox-list.c b/src/lib-storage/mailbox-list.c index fb120096b8..8e1bca079d 100644 --- a/src/lib-storage/mailbox-list.c +++ b/src/lib-storage/mailbox-list.c @@ -555,6 +555,7 @@ void mailbox_list_destroy(struct mailbox_list **_list) struct event *event = list->event; settings_free(list->mail_set); + settings_free(list->default_box_set); list->v.deinit(list); event_unref(&event); }