From: Timo Sirainen Date: Wed, 7 Jul 2010 15:03:42 +0000 (+0100) Subject: lib-storage: Make sure index directory is created early enough for mailbox.log X-Git-Tag: 2.0.rc2~16 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4d84348ffcbb60de566108562c95ad64629e7a53;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Make sure index directory is created early enough for mailbox.log For example if subscriptions were added before any mailbox was opened, the index dir may not have been created yet. --HG-- branch : HEAD --- diff --git a/src/lib-storage/index/index-storage.c b/src/lib-storage/index/index-storage.c index 7728f6fc52..e7dcf84d5a 100644 --- a/src/lib-storage/index/index-storage.c +++ b/src/lib-storage/index/index-storage.c @@ -26,41 +26,6 @@ struct index_storage_module index_storage_module = MODULE_CONTEXT_INIT(&mail_storage_module_register); -int index_list_create_missing_index_dir(struct mailbox_list *list, - const char *name) -{ - const char *root_dir, *index_dir, *parent_dir, *p, *origin; - mode_t mode; - gid_t gid; - unsigned int n = 0; - - root_dir = mailbox_list_get_path(list, name, - MAILBOX_LIST_PATH_TYPE_MAILBOX); - index_dir = mailbox_list_get_path(list, name, - MAILBOX_LIST_PATH_TYPE_INDEX); - if (*index_dir == '\0' || strcmp(index_dir, root_dir) == 0) - return 0; - - mailbox_list_get_dir_permissions(list, name, &mode, &gid, &origin); - while (mkdir_chgrp(index_dir, mode, gid, origin) < 0) { - if (errno == EEXIST) - break; - - p = strrchr(index_dir, '/'); - if (errno != ENOENT || p == NULL || ++n == 2) { - mailbox_list_set_critical(list, - "mkdir(%s) failed: %m", index_dir); - return -1; - } - /* create the parent directory first */ - parent_dir = t_strdup_until(index_dir, p); - if (mailbox_list_mkdir(list, parent_dir, - MAILBOX_LIST_PATH_TYPE_INDEX) < 0) - return -1; - } - return 0; -} - static struct mail_index * index_storage_alloc(struct mailbox_list *list, const char *name, enum mailbox_flags flags, const char *prefix) @@ -204,7 +169,7 @@ int index_storage_mailbox_open(struct mailbox *box, bool move_to_memory) } } - if (index_list_create_missing_index_dir(box->list, box->name) < 0) { + if (mailbox_list_create_missing_index_dir(box->list, box->name) < 0) { mail_storage_set_internal_error(box->storage); return -1; } diff --git a/src/lib-storage/index/index-storage.h b/src/lib-storage/index/index-storage.h index 189414767d..0d46ae0484 100644 --- a/src/lib-storage/index/index-storage.h +++ b/src/lib-storage/index/index-storage.h @@ -170,7 +170,4 @@ void index_save_context_free(struct mail_save_context *ctx); bool index_keyword_array_cmp(const ARRAY_TYPE(keyword_indexes) *k1, const ARRAY_TYPE(keyword_indexes) *k2); -int index_list_create_missing_index_dir(struct mailbox_list *list, - const char *name); - #endif diff --git a/src/lib-storage/mailbox-list-private.h b/src/lib-storage/mailbox-list-private.h index 467d659398..46cfb87db7 100644 --- a/src/lib-storage/mailbox-list-private.h +++ b/src/lib-storage/mailbox-list-private.h @@ -111,6 +111,8 @@ struct mailbox_list { bool temporary_error; ARRAY_DEFINE(module_contexts, union mailbox_list_module_context *); + + unsigned int index_root_dir_created:1; }; struct mailbox_list_iterate_context { @@ -158,6 +160,8 @@ bool mailbox_list_name_is_too_large(const char *name, char sep); enum mailbox_list_file_type mailbox_list_get_file_type(const struct dirent *d); bool mailbox_list_try_get_absolute_path(struct mailbox_list *list, const char **name); +int mailbox_list_create_missing_index_dir(struct mailbox_list *list, + const char *name); void mailbox_list_add_change(struct mailbox_list *list, enum mailbox_log_record_type type, diff --git a/src/lib-storage/mailbox-list.c b/src/lib-storage/mailbox-list.c index e2c92c4e23..3a3d4e2adc 100644 --- a/src/lib-storage/mailbox-list.c +++ b/src/lib-storage/mailbox-list.c @@ -1141,6 +1141,11 @@ void mailbox_list_add_change(struct mailbox_list *list, mail_guid_128_is_empty(mailbox_guid)) return; + if (!list->index_root_dir_created) { + if (mailbox_list_create_missing_index_dir(list, NULL) < 0) + return; + } + stamp = list->changelog_timestamp != (time_t)-1 ? list->changelog_timestamp : ioloop_time; @@ -1404,6 +1409,42 @@ int mailbox_list_create_parent_dir(struct mailbox_list *list, return 0; } +int mailbox_list_create_missing_index_dir(struct mailbox_list *list, + const char *name) +{ + const char *root_dir, *index_dir, *parent_dir, *p, *origin; + mode_t mode; + gid_t gid; + unsigned int n = 0; + + list->index_root_dir_created = TRUE; + root_dir = mailbox_list_get_path(list, name, + MAILBOX_LIST_PATH_TYPE_MAILBOX); + index_dir = mailbox_list_get_path(list, name, + MAILBOX_LIST_PATH_TYPE_INDEX); + if (*index_dir == '\0' || strcmp(index_dir, root_dir) == 0) + return 0; + + mailbox_list_get_dir_permissions(list, name, &mode, &gid, &origin); + while (mkdir_chgrp(index_dir, mode, gid, origin) < 0) { + if (errno == EEXIST) + break; + + p = strrchr(index_dir, '/'); + if (errno != ENOENT || p == NULL || ++n == 2) { + mailbox_list_set_critical(list, + "mkdir(%s) failed: %m", index_dir); + return -1; + } + /* create the parent directory first */ + parent_dir = t_strdup_until(index_dir, p); + if (mailbox_list_mkdir(list, parent_dir, + MAILBOX_LIST_PATH_TYPE_INDEX) < 0) + return -1; + } + return 0; +} + const char *mailbox_list_get_last_error(struct mailbox_list *list, enum mail_error *error_r) {