From: Timo Sirainen Date: Mon, 8 Mar 2010 18:28:08 +0000 (+0200) Subject: mdbox: Removed mdbox_max_open_files setting. X-Git-Tag: 2.0.beta4~100 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=04c3ac276103b56185119bcff9a66de7a8bb0e68;p=thirdparty%2Fdovecot%2Fcore.git mdbox: Removed mdbox_max_open_files setting. It's now hard coded to 2, and the files are closed after 30 seconds of being unused. --HG-- branch : HEAD --- diff --git a/src/lib-storage/index/dbox-multi/mdbox-file.c b/src/lib-storage/index/dbox-multi/mdbox-file.c index d897d55024..f91d616373 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-file.c +++ b/src/lib-storage/index/dbox-multi/mdbox-file.c @@ -26,18 +26,13 @@ static struct mdbox_file * mdbox_find_and_move_open_file(struct mdbox_storage *storage, uint32_t file_id) { - struct mdbox_file *const *files, *file; + struct mdbox_file *const *files; unsigned int i, count; files = array_get(&storage->open_files, &count); for (i = 0; i < count; i++) { - if (files[i]->file_id == file_id) { - /* move to last in the array */ - file = files[i]; - array_delete(&storage->open_files, i, 1); - array_append(&storage->open_files, &file, 1); - return file; - } + if (files[i]->file_id == file_id) + return files[i]; } return NULL; } @@ -127,9 +122,9 @@ mdbox_file_init_full(struct mdbox_storage *storage, } count = array_count(&storage->open_files); - if (count > storage->set->mdbox_max_open_files) { - mdbox_close_open_files(storage, count - - storage->set->mdbox_max_open_files); + if (count > MDBOX_MAX_OPEN_UNUSED_FILES) { + mdbox_close_open_files(storage, + count - MDBOX_MAX_OPEN_UNUSED_FILES); } file = i_new(struct mdbox_file, 1); @@ -187,6 +182,53 @@ int mdbox_file_assign_file_id(struct mdbox_file *file, uint32_t file_id) return 0; } +static struct mdbox_file * +mdbox_find_oldest_unused_file(struct mdbox_storage *storage, + unsigned int *idx_r) +{ + struct mdbox_file *const *files, *oldest_file = NULL; + unsigned int i, count; + + files = array_get(&storage->open_files, &count); + *idx_r = count; + for (i = 0; i < count; i++) { + if (files[i]->file.refcount == 0) { + if (oldest_file == NULL || + files[i]->close_time < oldest_file->close_time) { + oldest_file = files[i]; + *idx_r = i; + } + } + } + return oldest_file; +} + +static void mdbox_file_close_timeout(struct mdbox_storage *storage) +{ + struct mdbox_file *oldest; + unsigned int i; + time_t close_time = ioloop_time - MDBOX_CLOSE_UNUSED_FILES_TIMEOUT_SECS; + + while ((oldest = mdbox_find_oldest_unused_file(storage, &i)) != NULL) { + if (oldest->close_time > close_time) + break; + array_delete(&storage->open_files, i, 1); + dbox_file_free(&oldest->file); + } + + if (oldest == NULL) + timeout_remove(&storage->to_close_unused_files); +} + +static void mdbox_file_close_later(struct mdbox_file *mfile) +{ + if (mfile->storage->to_close_unused_files == NULL) { + mfile->storage->to_close_unused_files = + timeout_add(MDBOX_CLOSE_UNUSED_FILES_TIMEOUT_SECS*1000, + mdbox_file_close_timeout, mfile->storage); + } +} + void mdbox_file_unrefed(struct dbox_file *file) { struct mdbox_file *mfile = (struct mdbox_file *)file; @@ -195,24 +237,23 @@ void mdbox_file_unrefed(struct dbox_file *file) /* don't cache metadata seeks while file isn't being referenced */ file->metadata_read_offset = (uoff_t)-1; + mfile->close_time = ioloop_time; if (mfile->file_id != 0) { files = array_get(&mfile->storage->open_files, &count); - if (!file->deleted && - count <= mfile->storage->set->mdbox_max_open_files) { + if (!file->deleted && count <= MDBOX_MAX_OPEN_UNUSED_FILES) { /* we can leave this file open for now */ + mdbox_file_close_later(mfile); return; } /* close the oldest file with refcount=0 */ - for (i = 0; i < count; i++) { - if (files[i]->file.refcount == 0) - break; - } - oldest_file = files[i]; + oldest_file = mdbox_find_oldest_unused_file(mfile->storage, &i); + i_assert(oldest_file != NULL); array_delete(&mfile->storage->open_files, i, 1); if (oldest_file != mfile) { dbox_file_free(&oldest_file->file); + mdbox_file_close_later(mfile); return; } /* have to close ourself */ diff --git a/src/lib-storage/index/dbox-multi/mdbox-file.h b/src/lib-storage/index/dbox-multi/mdbox-file.h index 9548b726e7..4505364c67 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-file.h +++ b/src/lib-storage/index/dbox-multi/mdbox-file.h @@ -8,6 +8,7 @@ struct mdbox_file { struct mdbox_storage *storage; uint32_t file_id; + time_t close_time; }; struct dbox_file * diff --git a/src/lib-storage/index/dbox-multi/mdbox-settings.c b/src/lib-storage/index/dbox-multi/mdbox-settings.c index 7bee02e054..de5624e640 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-settings.c +++ b/src/lib-storage/index/dbox-multi/mdbox-settings.c @@ -11,14 +11,10 @@ #define DEF(type, name) \ { type, #name, offsetof(struct mdbox_settings, name), NULL } -static bool mdbox_settings_verify(void *_set, pool_t pool ATTR_UNUSED, - const char **error_r); - static const struct setting_define mdbox_setting_defines[] = { DEF(SET_SIZE, mdbox_rotate_size), DEF(SET_TIME, mdbox_rotate_interval), DEF(SET_TIME, mdbox_altmove), - DEF(SET_UINT, mdbox_max_open_files), SETTING_DEFINE_LIST_END }; @@ -26,8 +22,7 @@ static const struct setting_define mdbox_setting_defines[] = { static const struct mdbox_settings mdbox_default_settings = { .mdbox_rotate_size = 2*1024*1024, .mdbox_rotate_interval = 0, - .mdbox_altmove = 3600*24*7, - .mdbox_max_open_files = 64 + .mdbox_altmove = 3600*24*7 }; static const struct setting_parser_info mdbox_setting_parser_info = { @@ -39,25 +34,9 @@ static const struct setting_parser_info mdbox_setting_parser_info = { .struct_size = sizeof(struct mdbox_settings), .parent_offset = (size_t)-1, - .parent = &mail_user_setting_parser_info, - - .check_func = mdbox_settings_verify + .parent = &mail_user_setting_parser_info }; -/* */ -static bool mdbox_settings_verify(void *_set, pool_t pool ATTR_UNUSED, - const char **error_r) -{ - const struct mdbox_settings *set = _set; - - if (set->mdbox_max_open_files < 2) { - *error_r = "mdbox_max_open_files must be at least 2"; - return FALSE; - } - return TRUE; -} -/* */ - const struct setting_parser_info *mdbox_get_setting_parser_info(void) { return &mdbox_setting_parser_info; diff --git a/src/lib-storage/index/dbox-multi/mdbox-settings.h b/src/lib-storage/index/dbox-multi/mdbox-settings.h index b1fdcc0ec7..a0ef7782d5 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-settings.h +++ b/src/lib-storage/index/dbox-multi/mdbox-settings.h @@ -5,7 +5,6 @@ struct mdbox_settings { uoff_t mdbox_rotate_size; unsigned int mdbox_rotate_interval; unsigned int mdbox_altmove; - unsigned int mdbox_max_open_files; }; const struct setting_parser_info *mdbox_get_setting_parser_info(void); diff --git a/src/lib-storage/index/dbox-multi/mdbox-storage.c b/src/lib-storage/index/dbox-multi/mdbox-storage.c index d19e46ec5a..adb5f95060 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-storage.c +++ b/src/lib-storage/index/dbox-multi/mdbox-storage.c @@ -39,7 +39,6 @@ mdbox_storage_create(struct mail_storage *_storage, struct mail_namespace *ns, const char *dir; storage->set = mail_storage_get_driver_settings(_storage); - i_assert(storage->set->mdbox_max_open_files >= 2); if (*ns->list->set.mailbox_dir_name == '\0') { *error_r = "dbox: MAILBOXDIR must not be empty"; @@ -55,8 +54,7 @@ mdbox_storage_create(struct mail_storage *_storage, struct mail_namespace *ns, storage->alt_storage_dir = p_strconcat(_storage->pool, ns->list->set.alt_dir, "/"MDBOX_GLOBAL_DIR_NAME, NULL); - i_array_init(&storage->open_files, - I_MIN(storage->set->mdbox_max_open_files, 128)); + i_array_init(&storage->open_files, 64); storage->map = dbox_map_init(storage, ns->list, storage->storage_dir); return 0; @@ -73,6 +71,8 @@ static void mdbox_storage_destroy(struct mail_storage *_storage) mdbox_files_free(storage); dbox_map_deinit(&storage->map); + if (storage->to_close_unused_files != NULL) + timeout_remove(&storage->to_close_unused_files); array_free(&storage->open_files); } diff --git a/src/lib-storage/index/dbox-multi/mdbox-storage.h b/src/lib-storage/index/dbox-multi/mdbox-storage.h index ce21077bbe..340e4abe4f 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-storage.h +++ b/src/lib-storage/index/dbox-multi/mdbox-storage.h @@ -11,6 +11,8 @@ #define MDBOX_GLOBAL_DIR_NAME "storage" #define MDBOX_MAIL_FILE_PREFIX "m." #define MDBOX_MAIL_FILE_FORMAT MDBOX_MAIL_FILE_PREFIX"%u" +#define MDBOX_MAX_OPEN_UNUSED_FILES 2 +#define MDBOX_CLOSE_UNUSED_FILES_TIMEOUT_SECS 30 #define MDBOX_INDEX_HEADER_MIN_SIZE (sizeof(uint32_t)) struct mdbox_index_header { @@ -28,6 +30,7 @@ struct mdbox_storage { struct dbox_map *map; ARRAY_DEFINE(open_files, struct mdbox_file *); + struct timeout *to_close_unused_files; }; struct mdbox_mail_index_record {