From: Timo Sirainen Date: Wed, 20 Oct 2010 16:51:07 +0000 (+0100) Subject: mdbox: Added mdbox_preallocate_space setting to preallocate size for newly created... X-Git-Tag: 2.0.6~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f6aaada6101dd43cd80fe965ff1ab9bfaf776252;p=thirdparty%2Fdovecot%2Fcore.git mdbox: Added mdbox_preallocate_space setting to preallocate size for newly created files. --- diff --git a/doc/example-config/conf.d/10-mail.conf b/doc/example-config/conf.d/10-mail.conf index b28654a7eb..1e9443dd24 100644 --- a/doc/example-config/conf.d/10-mail.conf +++ b/doc/example-config/conf.d/10-mail.conf @@ -310,3 +310,8 @@ # Maximum dbox file age until it's rotated. Typically in days. Day begins # from midnight, so 1d = today, 2d = yesterday, etc. 0 = check disabled. #mdbox_rotate_interval = 1d + +# When creating new mdbox files, immediately preallocate their size to +# mdbox_rotate_size. This setting currently works only in Linux with some +# filesystems (ext4, xfs). +#mdbox_preallocate_space = no diff --git a/src/lib-storage/index/dbox-multi/mdbox-file.c b/src/lib-storage/index/dbox-multi/mdbox-file.c index b96a15f21d..745c8672c3 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-file.c +++ b/src/lib-storage/index/dbox-multi/mdbox-file.c @@ -9,6 +9,7 @@ #include "istream.h" #include "ostream.h" #include "file-lock.h" +#include "file-set-size.h" #include "mkdir-parents.h" #include "fdatasync-path.h" #include "eacces-error.h" @@ -97,14 +98,38 @@ static void mdbox_file_init_paths(struct mdbox_file *file, const char *fname) file->file.cur_path = file->file.primary_path; } -static int mdbox_file_create(struct dbox_file *file) +static int mdbox_file_create(struct mdbox_file *file) { + struct dbox_file *_file = &file->file; bool create_parents; + int ret; - create_parents = dbox_file_is_in_alt(file); - file->fd = file->storage->v. - file_create_fd(file, file->cur_path, create_parents); - return file->fd == -1 ? -1 : 0; + create_parents = dbox_file_is_in_alt(_file); + _file->fd = _file->storage->v. + file_create_fd(_file, _file->cur_path, create_parents); + if (_file->fd == -1) + return -1; + + if (file->storage->preallocate_space) { + ret = file_preallocate(_file->fd, + file->storage->set->mdbox_rotate_size); + if (ret < 0) { + switch (errno) { + case ENOSPC: + case EDQUOT: + /* ignore */ + break; + default: + i_error("file_preallocate(%s) failed: %m", + _file->cur_path); + break; + } + } else if (ret == 0) { + /* not supported by filesystem, disable. */ + file->storage->preallocate_space = FALSE; + } + } + return 0; } static struct dbox_file * @@ -142,7 +167,7 @@ mdbox_file_init_full(struct mdbox_storage *storage, if (file_id != 0) array_append(&storage->open_files, &file, 1); else - (void)mdbox_file_create(&file->file); + (void)mdbox_file_create(file); return &file->file; } diff --git a/src/lib-storage/index/dbox-multi/mdbox-settings.c b/src/lib-storage/index/dbox-multi/mdbox-settings.c index 2afb6c0873..bb19fe149e 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-settings.c +++ b/src/lib-storage/index/dbox-multi/mdbox-settings.c @@ -12,6 +12,7 @@ { type, #name, offsetof(struct mdbox_settings, name), NULL } static const struct setting_define mdbox_setting_defines[] = { + DEF(SET_BOOL, mdbox_preallocate_space), DEF(SET_SIZE, mdbox_rotate_size), DEF(SET_TIME, mdbox_rotate_interval), @@ -19,6 +20,7 @@ static const struct setting_define mdbox_setting_defines[] = { }; static const struct mdbox_settings mdbox_default_settings = { + .mdbox_preallocate_space = FALSE, .mdbox_rotate_size = 2*1024*1024, .mdbox_rotate_interval = 0 }; diff --git a/src/lib-storage/index/dbox-multi/mdbox-settings.h b/src/lib-storage/index/dbox-multi/mdbox-settings.h index 968f03a32a..353da69618 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-settings.h +++ b/src/lib-storage/index/dbox-multi/mdbox-settings.h @@ -2,6 +2,7 @@ #define MDBOX_SETTINGS_H struct mdbox_settings { + bool mdbox_preallocate_space; uoff_t mdbox_rotate_size; unsigned int mdbox_rotate_interval; }; diff --git a/src/lib-storage/index/dbox-multi/mdbox-storage.c b/src/lib-storage/index/dbox-multi/mdbox-storage.c index 38fa88c92d..94ee4b0888 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-storage.c +++ b/src/lib-storage/index/dbox-multi/mdbox-storage.c @@ -42,6 +42,7 @@ mdbox_storage_create(struct mail_storage *_storage, struct mail_namespace *ns, const char *dir; storage->set = mail_storage_get_driver_settings(_storage); + storage->preallocate_space = storage->set->mdbox_preallocate_space; if (*ns->list->set.mailbox_dir_name == '\0') { *error_r = "mdbox: MAILBOXDIR must not be empty"; diff --git a/src/lib-storage/index/dbox-multi/mdbox-storage.h b/src/lib-storage/index/dbox-multi/mdbox-storage.h index efb854f491..c318a95ac6 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-storage.h +++ b/src/lib-storage/index/dbox-multi/mdbox-storage.h @@ -39,6 +39,7 @@ struct mdbox_storage { unsigned int corrupted:1; unsigned int rebuilding_storage:1; + unsigned int preallocate_space:1; }; struct mdbox_mail_index_record {