changeset 22824:bd5cea4da2ce

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)
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Wed, 07 Feb 2018 16:17:13 +0200
parents c2133393765c
children 2df6a22a5ad1
files src/lib-index/mail-cache-private.h src/lib-index/mail-cache.c
diffstat 2 files changed, 7 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-cache-private.h	Tue Jan 09 15:37:25 2018 -0500
+++ b/src/lib-index/mail-cache-private.h	Wed Feb 07 16:17:13 2018 +0200
@@ -108,7 +108,6 @@
 	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.
--- a/src/lib-index/mail-cache.c	Tue Jan 09 15:37:25 2018 -0500
+++ b/src/lib-index/mail-cache.c	Wed Feb 07 16:17:13 2018 +0200
@@ -611,8 +611,8 @@
 		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);
 
@@ -621,14 +621,15 @@
 					 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()");
 		}
@@ -648,10 +649,7 @@
 
 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