]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added mail_max_lock_timeout setting.
authorTimo Sirainen <tss@iki.fi>
Wed, 23 Jun 2010 16:52:02 +0000 (17:52 +0100)
committerTimo Sirainen <tss@iki.fi>
Wed, 23 Jun 2010 16:52:02 +0000 (17:52 +0100)
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".

--HG--
branch : HEAD

20 files changed:
src/doveadm/doveadm-dump-index.c
src/lib-index/mail-cache.c
src/lib-index/mail-index-lock.c
src/lib-index/mail-index-private.h
src/lib-index/mail-index-strmap.c
src/lib-index/mail-index.c
src/lib-index/mail-index.h
src/lib-index/mail-transaction-log-file.c
src/lib-index/mail-transaction-log.c
src/lib-storage/index/dbox-common/dbox-sync-rebuild.c
src/lib-storage/index/dbox-multi/mdbox-map.c
src/lib-storage/index/index-storage.c
src/lib-storage/index/maildir/maildir-keywords.c
src/lib-storage/index/maildir/maildir-uidlist.c
src/lib-storage/index/mbox/mbox-lock.c
src/lib-storage/list/index-mailbox-list.c
src/lib-storage/mail-storage-private.h
src/lib-storage/mail-storage-settings.c
src/lib-storage/mail-storage-settings.h
src/lib-storage/mail-storage.c

index 9bd08083261a5e010c3cffd2d475c0c4581d949e..1ef50da55dedd561f55fdde915646ddc343a62c0 100644 (file)
@@ -533,8 +533,7 @@ static void cmd_dump_index(int argc ATTR_UNUSED, char *argv[])
 
        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 @@ static bool test_dump_index(const char *path)
        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);
index d71253c54cb06125573d2baed96c40f533124ee4..77fb4f7f1615e6c26a4d79e374cec4527d3bd410 100644 (file)
@@ -414,7 +414,8 @@ static struct mail_cache *mail_cache_alloc(struct mail_index *index)
                (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 @@ void mail_cache_free(struct mail_cache **_cache)
 
 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 @@ static int mail_cache_lock_file(struct mail_cache *cache, bool nonblock)
 
        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 =
index 2274ba477d231b3f6060b4e1351ff2be627b5483..ddec2e5ee21055eb3e36283e9097ef2e4478a1e2 100644 (file)
@@ -139,10 +139,12 @@ void mail_index_flush_read_cache(struct mail_index *index, const char *path,
 
 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);
index a03c14393c128f1ec7c7363c85e4f0d7e85cd501..f31ee057bd8035943acf825aab47385cb0fb3d16 100644 (file)
@@ -208,6 +208,7 @@ struct mail_index {
        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;
index a435c07a26691c974ac5ed31996d9aeec4efdae1..8533d21254cab4ede6d2068f005cd727948f2b9a 100644 (file)
@@ -1041,6 +1041,7 @@ static int mail_index_strmap_recreate(struct mail_index_strmap_view *view)
 
 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 @@ static int mail_index_strmap_lock(struct mail_index_strmap *strmap)
        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,
index b41376be16fa61cbbbdaf5a2af416988d26f8730..667bde56678e00bb38948be8f74474bf9797fb2b 100644 (file)
@@ -44,6 +44,8 @@ struct mail_index *mail_index_alloc(const char *dir, const char *prefix)
 
        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 @@ void mail_index_set_permissions(struct mail_index *index,
        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 @@ static int mail_index_open_files(struct mail_index *index,
        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 @@ int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags,
        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(struct mail_index *index, enum mail_index_open_flags flags,
 }
 
 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;
 }
index e62681b51a4ede30240d7ad90a3b967f309e343f..dddde3542d5161c2e9d9b695c07b468fe8295da1 100644 (file)
@@ -213,15 +213,17 @@ void mail_index_set_fsync_types(struct mail_index *index,
                                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);
index 477cdbb8652aa2f0f414c7db9f5af4ca28b7ba4e..cb6a55588783cb8d2352e645be7290979802c4ac 100644 (file)
@@ -320,6 +320,7 @@ mail_transaction_log_file_undotlock(struct mail_transaction_log_file *file)
 
 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 @@ int mail_transaction_log_file_lock(struct mail_transaction_log_file *file)
                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;
index a878a4f5d6191bf80c3a49d6f01dd28dd8910baa..7be2a762fd4bf926b0fdac3a36a303e13a8146b4 100644 (file)
@@ -37,7 +37,9 @@ mail_transaction_log_alloc(struct mail_index *index)
        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;
 
index 187d29ef9071d893935467cca14ecb2514a7b6ca..edc231ab5d91f38df49debc3f02f147c060e109d 100644 (file)
@@ -168,8 +168,9 @@ dbox_sync_index_rebuild_init(struct mailbox *box,
        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);
index be278b366c5b78efd16c43de1aae3fe3a2cae2b1..046f638127338f011e09c5644e36f569b8b7615a 100644 (file)
@@ -57,6 +57,9 @@ mdbox_map_init(struct mdbox_storage *storage, struct mailbox_list *root_list,
        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 @@ static int mdbox_map_open_internal(struct mdbox_map *map, bool create_missing)
                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);
index aaa0d1409c3b6b2d49cba42e9cf20ca003210a40..ca67f08479125f5d172e1b4febd9b5c5a87f60e4 100644 (file)
@@ -187,8 +187,6 @@ void index_storage_lock_notify_reset(struct mailbox *box)
 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 @@ int index_storage_mailbox_open(struct mailbox *box, bool move_to_memory)
                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 @@ int index_storage_mailbox_open(struct mailbox *box, bool move_to_memory)
                        /* 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 @@ void index_storage_mailbox_alloc(struct mailbox *box, const char *name,
        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,
index 13e864baee191a1fbe91add8924be3ef97ce53a4..90f27dd56a6375276ff07c2c274b4f09c18fbb43 100644 (file)
@@ -81,7 +81,9 @@ maildir_keywords_init_readonly(struct mailbox *box)
                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);
index cbaffc27db75a46375af51b28fb23cfac505baf4..d373e98ef9c5b7c1fae203b7b1b568e3575a1b16 100644 (file)
@@ -273,7 +273,8 @@ struct maildir_uidlist *maildir_uidlist_init(struct maildir_mailbox *mbox)
        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;
index 2a677b97a4ca713c508ec17be517959842d60764..e84554ff62a3acb6957060e4035d4dbfc6fc1934 100644 (file)
@@ -405,7 +405,8 @@ mbox_lock_dotlock_int(struct mbox_lock_context *ctx, int lock_type, bool try)
        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 @@ static int mbox_update_locking(struct mbox_mailbox *mbox, int lock_type,
                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;
index 92f18cf0b60c8b8f0ff756289fae959d8ff899a9..d069aa9fdbc0d37cafa4806645f757f409e294d9 100644 (file)
@@ -457,19 +457,18 @@ static int index_mailbox_list_open_indexes(struct mailbox_list *list,
        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
index 82a0b6658ab9948699906728f13fd301dfc34f01..40a66a52707e9913eaeefcd882595f09b8cab99b 100644 (file)
@@ -469,5 +469,7 @@ void mailbox_refresh_permissions(struct mailbox *box);
 /* 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
index 98b16838124426e3c8d408b5b9c286bc5a1dc967..f58f2699aad41dbe45c84c9e00c6e5f357af04c4 100644 (file)
@@ -28,6 +28,7 @@ static const struct setting_define mail_storage_setting_defines[] = {
        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 @@ const struct mail_storage_settings mail_storage_default_settings = {
        .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,
index 0e6da85c61ffa5bc86c55034dd9957fb2046264a..c4465fb617aa8a4f0b07c351f07df2e8c510fa68 100644 (file)
@@ -15,6 +15,7 @@ struct mail_storage_settings {
        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;
index fc428581124064f7d05c526f41c80b043f38c155..6b53b1f20d5c35e024072b8c23967a54179c8d38 100644 (file)
@@ -1466,3 +1466,10 @@ int mailbox_create_fd(struct mailbox *box, const char *path, int flags,
        *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);
+}