Mercurial > dovecot > core-2.2
changeset 11623:c3ee4421e86a HEAD
Added mail_max_lock_timeout setting.
This could be useful inside lda/lmtp protocol sections to avoid them from
spending too much time waiting for locks, since they can easily just
return "try again later".
line wrap: on
line diff
--- a/src/doveadm/doveadm-dump-index.c Wed Jun 23 16:58:18 2010 +0100 +++ b/src/doveadm/doveadm-dump-index.c Wed Jun 23 17:52:02 2010 +0100 @@ -533,8 +533,7 @@ index = path_open_index(argv[1]); if (index == NULL || - mail_index_open(index, MAIL_INDEX_OPEN_FLAG_READONLY, - FILE_LOCK_METHOD_FCNTL) <= 0) + mail_index_open(index, MAIL_INDEX_OPEN_FLAG_READONLY) <= 0) i_fatal("Couldn't open index %s", argv[1]); if (argv[2] != NULL) uid = atoi(argv[2]); @@ -577,8 +576,7 @@ if (index == NULL) return FALSE; - ret = mail_index_open(index, MAIL_INDEX_OPEN_FLAG_READONLY, - FILE_LOCK_METHOD_FCNTL) > 0; + ret = mail_index_open(index, MAIL_INDEX_OPEN_FLAG_READONLY) > 0; if (ret > 0) mail_index_close(index); mail_index_free(&index);
--- a/src/lib-index/mail-cache.c Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-index/mail-cache.c Wed Jun 23 17:52:02 2010 +0100 @@ -414,7 +414,8 @@ (index->flags & MAIL_INDEX_OPEN_FLAG_DOTLOCK_USE_EXCL) != 0; cache->dotlock_settings.nfs_flush = (index->flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0; - cache->dotlock_settings.timeout = MAIL_CACHE_LOCK_TIMEOUT; + cache->dotlock_settings.timeout = + I_MIN(MAIL_CACHE_LOCK_TIMEOUT, index->max_lock_timeout_secs); cache->dotlock_settings.stale_timeout = MAIL_CACHE_LOCK_CHANGE_TIMEOUT; if (!MAIL_INDEX_IS_IN_MEMORY(index) && @@ -488,6 +489,7 @@ static int mail_cache_lock_file(struct mail_cache *cache, bool nonblock) { + unsigned int timeout_secs; int ret; if (cache->last_lock_failed) { @@ -498,9 +500,12 @@ if (cache->index->lock_method != FILE_LOCK_METHOD_DOTLOCK) { i_assert(cache->file_lock == NULL); + timeout_secs = I_MIN(MAIL_CACHE_LOCK_TIMEOUT, + cache->index->max_lock_timeout_secs); + ret = mail_index_lock_fd(cache->index, cache->filepath, cache->fd, F_WRLCK, - nonblock ? 0 : MAIL_CACHE_LOCK_TIMEOUT, + nonblock ? 0 : timeout_secs, &cache->file_lock); } else { enum dotlock_create_flags flags =
--- a/src/lib-index/mail-index-lock.c Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-index/mail-index-lock.c Wed Jun 23 17:52:02 2010 +0100 @@ -139,10 +139,12 @@ int mail_index_lock_shared(struct mail_index *index, unsigned int *lock_id_r) { + unsigned int timeout_secs; int ret; - ret = mail_index_lock(index, F_RDLCK, MAIL_INDEX_SHARED_LOCK_TIMEOUT, - lock_id_r); + timeout_secs = I_MIN(MAIL_INDEX_SHARED_LOCK_TIMEOUT, + index->max_lock_timeout_secs); + ret = mail_index_lock(index, F_RDLCK, timeout_secs, lock_id_r); if (ret > 0) { mail_index_flush_read_cache(index, index->filepath, index->fd, TRUE);
--- a/src/lib-index/mail-index-private.h Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-index/mail-index-private.h Wed Jun 23 17:52:02 2010 +0100 @@ -208,6 +208,7 @@ int lock_type, shared_lock_count, excl_lock_count; unsigned int lock_id_counter; enum file_lock_method lock_method; + unsigned int max_lock_timeout_secs; struct file_lock *file_lock; struct dotlock *dotlock;
--- a/src/lib-index/mail-index-strmap.c Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-index/mail-index-strmap.c Wed Jun 23 17:52:02 2010 +0100 @@ -1041,6 +1041,7 @@ static int mail_index_strmap_lock(struct mail_index_strmap *strmap) { + unsigned int timeout_secs; int ret; i_assert(strmap->fd != -1); @@ -1048,9 +1049,10 @@ if (strmap->index->lock_method != FILE_LOCK_METHOD_DOTLOCK) { i_assert(strmap->file_lock == NULL); + timeout_secs = I_MIN(MAIL_INDEX_STRMAP_TIMEOUT_SECS, + strmap->index->max_lock_timeout_secs); ret = file_wait_lock(strmap->fd, strmap->path, F_WRLCK, - strmap->index->lock_method, - MAIL_INDEX_STRMAP_TIMEOUT_SECS, + strmap->index->lock_method, timeout_secs, &strmap->file_lock); if (ret <= 0) { mail_index_strmap_set_syscall_error(strmap,
--- a/src/lib-index/mail-index.c Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-index/mail-index.c Wed Jun 23 17:52:02 2010 +0100 @@ -44,6 +44,8 @@ index->mode = 0600; index->gid = (gid_t)-1; + index->lock_method = FILE_LOCK_METHOD_FCNTL; + index->max_lock_timeout_secs = -1U; index->keywords_ext_id = mail_index_ext_register(index, MAIL_INDEX_EXT_KEYWORDS, @@ -98,6 +100,14 @@ index->gid_origin = i_strdup(gid_origin); } +void mail_index_set_lock_method(struct mail_index *index, + enum file_lock_method lock_method, + unsigned int max_timeout_secs) +{ + index->lock_method = lock_method; + index->max_lock_timeout_secs = max_timeout_secs; +} + uint32_t mail_index_ext_register(struct mail_index *index, const char *name, uint32_t default_hdr_size, uint16_t default_record_size, @@ -482,8 +492,7 @@ return 1; } -int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags, - enum file_lock_method lock_method) +int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags) { int ret; @@ -508,7 +517,6 @@ index->log_locked = FALSE; index->flags = flags; index->readonly = (flags & MAIL_INDEX_OPEN_FLAG_READONLY) != 0; - index->lock_method = lock_method; if ((flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0 && (flags & MAIL_INDEX_OPEN_FLAG_FSYNC_DISABLE) != 0) @@ -530,13 +538,12 @@ } int mail_index_open_or_create(struct mail_index *index, - enum mail_index_open_flags flags, - enum file_lock_method lock_method) + enum mail_index_open_flags flags) { int ret; flags |= MAIL_INDEX_OPEN_FLAG_CREATE; - ret = mail_index_open(index, flags, lock_method); + ret = mail_index_open(index, flags); i_assert(ret != 0); return ret < 0 ? -1 : 0; }
--- a/src/lib-index/mail-index.h Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-index/mail-index.h Wed Jun 23 17:52:02 2010 +0100 @@ -213,15 +213,17 @@ enum mail_index_sync_type fsync_mask); void mail_index_set_permissions(struct mail_index *index, mode_t mode, gid_t gid, const char *gid_origin); +/* Set locking method and maximum time to wait for a lock (-1U = default). */ +void mail_index_set_lock_method(struct mail_index *index, + enum file_lock_method lock_method, + unsigned int max_timeout_secs); /* Open index. Returns 1 if ok, 0 if index doesn't exist and CREATE flags wasn't given, -1 if error. */ -int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags, - enum file_lock_method lock_method); +int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags); /* Open or create index. Returns 0 if ok, -1 if error. */ int mail_index_open_or_create(struct mail_index *index, - enum mail_index_open_flags flags, - enum file_lock_method lock_method); + enum mail_index_open_flags flags); void mail_index_close(struct mail_index *index); /* unlink() all the index files. */ int mail_index_unlink(struct mail_index *index);
--- a/src/lib-index/mail-transaction-log-file.c Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-index/mail-transaction-log-file.c Wed Jun 23 17:52:02 2010 +0100 @@ -320,6 +320,7 @@ int mail_transaction_log_file_lock(struct mail_transaction_log_file *file) { + unsigned int lock_timeout_secs; int ret; if (file->locked) @@ -334,8 +335,10 @@ return mail_transaction_log_file_dotlock(file); i_assert(file->file_lock == NULL); + lock_timeout_secs = I_MIN(MAIL_TRANSCATION_LOG_LOCK_TIMEOUT, + file->log->index->max_lock_timeout_secs); ret = mail_index_lock_fd(file->log->index, file->filepath, file->fd, - F_WRLCK, MAIL_TRANSCATION_LOG_LOCK_TIMEOUT, + F_WRLCK, lock_timeout_secs, &file->file_lock); if (ret > 0) { file->locked = TRUE;
--- a/src/lib-index/mail-transaction-log.c Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-index/mail-transaction-log.c Wed Jun 23 17:52:02 2010 +0100 @@ -37,7 +37,9 @@ log = i_new(struct mail_transaction_log, 1); log->index = index; - log->dotlock_settings.timeout = MAIL_TRANSCATION_LOG_LOCK_TIMEOUT; + log->dotlock_settings.timeout = + I_MIN(MAIL_TRANSCATION_LOG_LOCK_TIMEOUT, + index->max_lock_timeout_secs);; log->dotlock_settings.stale_timeout = MAIL_TRANSCATION_LOG_LOCK_CHANGE_TIMEOUT;
--- a/src/lib-storage/index/dbox-common/dbox-sync-rebuild.c Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-storage/index/dbox-common/dbox-sync-rebuild.c Wed Jun 23 17:52:02 2010 +0100 @@ -168,8 +168,9 @@ if (box->storage->set->mmap_disable) #endif open_flags |= MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE; - if (mail_index_open(ctx->backup_index, open_flags, - box->storage->set->parsed_lock_method) <= 0) + mail_index_set_lock_method(ctx->backup_index, + box->storage->set->parsed_lock_method, -1U); + if (mail_index_open(ctx->backup_index, open_flags) <= 0) mail_index_free(&ctx->backup_index); else ctx->backup_view = mail_index_view_open(ctx->backup_index);
--- a/src/lib-storage/index/dbox-multi/mdbox-map.c Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-storage/index/dbox-multi/mdbox-map.c Wed Jun 23 17:52:02 2010 +0100 @@ -57,6 +57,9 @@ map->set = storage->set; map->path = i_strdup(path); map->index = mail_index_alloc(path, MDBOX_GLOBAL_INDEX_PREFIX); + mail_index_set_lock_method(map->index, + MAP_STORAGE(map)->set->parsed_lock_method, + mail_storage_get_lock_timeout(MAP_STORAGE(map), -1U)); map->root_list = root_list; map->map_ext_id = mail_index_ext_register(map->index, "map", sizeof(struct mdbox_map_mail_index_header), @@ -137,8 +140,7 @@ if (mdbox_map_mkdir_storage(map) < 0) return -1; } - ret = mail_index_open(map->index, open_flags, - MAP_STORAGE(map)->set->parsed_lock_method); + ret = mail_index_open(map->index, open_flags); if (ret < 0) { mail_storage_set_internal_error(MAP_STORAGE(map)); mail_index_reset_error(map->index);
--- a/src/lib-storage/index/index-storage.c Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-storage/index/index-storage.c Wed Jun 23 17:52:02 2010 +0100 @@ -187,8 +187,6 @@ int index_storage_mailbox_open(struct mailbox *box, bool move_to_memory) { struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box); - enum file_lock_method lock_method = - box->storage->set->parsed_lock_method; enum mail_index_open_flags index_flags; int ret; @@ -211,7 +209,7 @@ return -1; } - ret = mail_index_open(box->index, index_flags, lock_method); + ret = mail_index_open(box->index, index_flags); if (ret <= 0 || move_to_memory) { if ((index_flags & MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY) != 0) { i_assert(ret <= 0); @@ -223,8 +221,7 @@ /* try opening once more. it should be created directly into memory now. */ if (mail_index_open_or_create(box->index, - index_flags, - lock_method) < 0) + index_flags) < 0) i_panic("in-memory index creation failed"); } } @@ -290,6 +287,9 @@ mail_index_set_permissions(box->index, box->file_create_mode, box->file_create_gid, box->file_create_gid_origin); + mail_index_set_lock_method(box->index, + box->storage->set->parsed_lock_method, + mail_storage_get_lock_timeout(box->storage, -1U)); } int index_storage_mailbox_enable(struct mailbox *box,
--- a/src/lib-storage/index/maildir/maildir-keywords.c Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-storage/index/maildir/maildir-keywords.c Wed Jun 23 17:52:02 2010 +0100 @@ -81,7 +81,9 @@ box->storage->set->dotlock_use_excl; mk->dotlock_settings.nfs_flush = box->storage->set->mail_nfs_storage; - mk->dotlock_settings.timeout = KEYWORDS_LOCK_STALE_TIMEOUT + 2; + mk->dotlock_settings.timeout = + mail_storage_get_lock_timeout(box->storage, + KEYWORDS_LOCK_STALE_TIMEOUT + 2); mk->dotlock_settings.stale_timeout = KEYWORDS_LOCK_STALE_TIMEOUT; mk->dotlock_settings.temp_prefix = mailbox_list_get_temp_prefix(box->list);
--- a/src/lib-storage/index/maildir/maildir-uidlist.c Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-storage/index/maildir/maildir-uidlist.c Wed Jun 23 17:52:02 2010 +0100 @@ -273,7 +273,8 @@ uidlist->dotlock_settings.nfs_flush = mbox->box.storage->set->mail_nfs_storage; uidlist->dotlock_settings.timeout = - MAILDIR_UIDLIST_LOCK_STALE_TIMEOUT + 2; + mail_storage_get_lock_timeout(&mbox->storage->storage, + MAILDIR_UIDLIST_LOCK_STALE_TIMEOUT + 2); uidlist->dotlock_settings.stale_timeout = MAILDIR_UIDLIST_LOCK_STALE_TIMEOUT; uidlist->dotlock_settings.callback = dotlock_callback;
--- a/src/lib-storage/index/mbox/mbox-lock.c Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-storage/index/mbox/mbox-lock.c Wed Jun 23 17:52:02 2010 +0100 @@ -405,7 +405,8 @@ memset(&set, 0, sizeof(set)); set.use_excl_lock = mbox->storage->storage.set->dotlock_use_excl; set.nfs_flush = mbox->storage->storage.set->mail_nfs_storage; - set.timeout = mbox->storage->set->mbox_lock_timeout; + set.timeout = mail_storage_get_lock_timeout(&mbox->storage->storage, + mbox->storage->set->mbox_lock_timeout); set.stale_timeout = mbox->storage->set->mbox_dotlock_change_timeout; set.callback = dotlock_callback; set.context = ctx; @@ -707,7 +708,9 @@ return 1; } - max_wait_time = time(NULL) + mbox->storage->set->mbox_lock_timeout; + max_wait_time = time(NULL) + + mail_storage_get_lock_timeout(&mbox->storage->storage, + mbox->storage->set->mbox_lock_timeout); memset(&ctx, 0, sizeof(ctx)); ctx.mbox = mbox;
--- a/src/lib-storage/list/index-mailbox-list.c Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-storage/list/index-mailbox-list.c Wed Jun 23 17:52:02 2010 +0100 @@ -457,19 +457,18 @@ struct index_mailbox_list *ilist = INDEX_LIST_CONTEXT(list); const char *path; enum mail_index_open_flags index_flags = 0; - enum file_lock_method lock_method = list->mail_set->parsed_lock_method; int ret; index_flags = mail_storage_settings_to_index_flags(list->mail_set); - if (mail_index_open_or_create(ilist->mail_index, index_flags, - lock_method) < 0) { + mail_index_set_lock_method(ilist->mail_index, + list->mail_set->parsed_lock_method, -1U); + if (mail_index_open_or_create(ilist->mail_index, index_flags) < 0) { if (mail_index_move_to_memory(ilist->mail_index) < 0) { /* try opening once more. it should be created directly into memory now. */ ret = mail_index_open_or_create(ilist->mail_index, - index_flags, - lock_method); + index_flags); if (ret < 0) { /* everything failed. there's a bug in the code, but just work around it by disabling
--- a/src/lib-storage/mail-storage-private.h Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-storage/mail-storage-private.h Wed Jun 23 17:52:02 2010 +0100 @@ -469,5 +469,7 @@ /* Returns -1 if error, 0 if failed with EEXIST, 1 if ok */ int mailbox_create_fd(struct mailbox *box, const char *path, int flags, int *fd_r); +unsigned int mail_storage_get_lock_timeout(struct mail_storage *storage, + unsigned int secs); #endif
--- a/src/lib-storage/mail-storage-settings.c Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-storage/mail-storage-settings.c Wed Jun 23 17:52:02 2010 +0100 @@ -28,6 +28,7 @@ DEF(SET_UINT, mail_cache_min_mail_count), DEF(SET_TIME, mailbox_idle_check_interval), DEF(SET_UINT, mail_max_keyword_length), + DEF(SET_TIME, mail_max_lock_timeout), DEF(SET_BOOL, mail_save_crlf), DEF(SET_BOOL, fsync_disable), DEF(SET_BOOL, mmap_disable), @@ -51,6 +52,7 @@ .mail_cache_min_mail_count = 0, .mailbox_idle_check_interval = 30, .mail_max_keyword_length = 50, + .mail_max_lock_timeout = 0, .mail_save_crlf = FALSE, .fsync_disable = FALSE, .mmap_disable = FALSE,
--- a/src/lib-storage/mail-storage-settings.h Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-storage/mail-storage-settings.h Wed Jun 23 17:52:02 2010 +0100 @@ -15,6 +15,7 @@ unsigned int mail_cache_min_mail_count; unsigned int mailbox_idle_check_interval; unsigned int mail_max_keyword_length; + unsigned int mail_max_lock_timeout; bool mail_save_crlf; bool fsync_disable; bool mmap_disable;
--- a/src/lib-storage/mail-storage.c Wed Jun 23 16:58:18 2010 +0100 +++ b/src/lib-storage/mail-storage.c Wed Jun 23 17:52:02 2010 +0100 @@ -1466,3 +1466,10 @@ *fd_r = fd; return 1; } + +unsigned int mail_storage_get_lock_timeout(struct mail_storage *storage, + unsigned int secs) +{ + return storage->set->mail_max_lock_timeout == 0 ? secs : + I_MIN(secs, storage->set->mail_max_lock_timeout); +}