From fbc2195f371dac8c5dad433d1b8f74a34ec2a4e2 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Wed, 7 Feb 2018 16:17:13 +0200 Subject: [PATCH] lib-index: Fix assert-crash with lock_method=dotlock The dotlock wasn't deleted in all code paths. Fix this by simplifying the unlocking to be done the same way with and without dotlock. Fixes: Panic: file mail-cache.c: line 624 (mail_cache_lock_file): assertion failed: (cache->dotlock == NULL) --- src/lib-index/mail-cache-private.h | 1 - src/lib-index/mail-cache.c | 16 +++++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/lib-index/mail-cache-private.h b/src/lib-index/mail-cache-private.h index 78655402fd..83f1be6248 100644 --- a/src/lib-index/mail-cache-private.h +++ b/src/lib-index/mail-cache-private.h @@ -108,7 +108,6 @@ struct mail_cache { unsigned int remap_counter; struct dotlock_settings dotlock_settings; - struct dotlock *dotlock; struct file_lock *file_lock; /* mmap_disable=no: hdr points to data / NULL when cache is invalid. diff --git a/src/lib-index/mail-cache.c b/src/lib-index/mail-cache.c index ce5ed1cd03..9596f3bbe9 100644 --- a/src/lib-index/mail-cache.c +++ b/src/lib-index/mail-cache.c @@ -609,8 +609,8 @@ static int mail_cache_lock_file(struct mail_cache *cache, bool nonblock) nonblock = TRUE; } + i_assert(cache->file_lock == NULL); 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); @@ -619,14 +619,15 @@ static int mail_cache_lock_file(struct mail_cache *cache, bool nonblock) nonblock ? 0 : timeout_secs, &cache->file_lock); } else { + struct dotlock *dotlock; enum dotlock_create_flags flags = nonblock ? DOTLOCK_CREATE_FLAG_NONBLOCK : 0; - i_assert(cache->dotlock == NULL); ret = file_dotlock_create(&cache->dotlock_settings, - cache->filepath, flags, - &cache->dotlock); - if (ret < 0) { + cache->filepath, flags, &dotlock); + if (ret > 0) + cache->file_lock = file_lock_from_dotlock(&dotlock); + else if (ret < 0) { mail_cache_set_syscall_error(cache, "file_dotlock_create()"); } @@ -646,10 +647,7 @@ static int mail_cache_lock_file(struct mail_cache *cache, bool nonblock) static void mail_cache_unlock_file(struct mail_cache *cache) { - if (cache->index->lock_method != FILE_LOCK_METHOD_DOTLOCK) - file_unlock(&cache->file_lock); - else - file_dotlock_delete(&cache->dotlock); + file_unlock(&cache->file_lock); } static int