dovecot-1.2: Mail cache: lock_method=dotlock could have caused a...

dovecot at dovecot.org dovecot at dovecot.org
Thu Sep 11 16:52:54 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/f1203dce2d8c
changeset: 8187:f1203dce2d8c
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Sep 11 16:52:47 2008 +0300
description:
Mail cache: lock_method=dotlock could have caused a process to deadlock with itself.

diffstat:

3 files changed, 27 insertions(+), 21 deletions(-)
src/lib-index/mail-cache-compress.c |   44 +++++++++++++++++++----------------
src/lib-index/mail-cache-private.h  |    1 
src/lib-index/mail-cache.c          |    3 +-

diffs (92 lines):

diff -r 2358ee07d2db -r f1203dce2d8c src/lib-index/mail-cache-compress.c
--- a/src/lib-index/mail-cache-compress.c	Thu Sep 11 16:37:32 2008 +0300
+++ b/src/lib-index/mail-cache-compress.c	Thu Sep 11 16:52:47 2008 +0300
@@ -433,6 +433,7 @@ static int mail_cache_compress_locked(st
 	cache->fd = fd;
 	cache->st_ino = st.st_ino;
 	cache->st_dev = st.st_dev;
+	cache->field_header_write_pending = FALSE;
 
 	if (cache->file_cache != NULL)
 		file_cache_set_fd(cache->file_cache, cache->fd);
@@ -451,6 +452,8 @@ int mail_cache_compress(struct mail_cach
 {
 	bool unlock = FALSE;
 	int ret;
+
+	i_assert(!cache->compressing);
 
 	if (MAIL_INDEX_IS_IN_MEMORY(cache->index) || cache->index->readonly)
 		return 0;
@@ -463,26 +466,27 @@ int mail_cache_compress(struct mail_cach
 						    cache->filepath, cache->fd,
 						    FALSE);
 		}
-		return mail_cache_compress_locked(cache, trans, &unlock);
-	}
-
-	switch (mail_cache_lock(cache, FALSE)) {
-	case -1:
-		return -1;
-	case 0:
-		/* couldn't lock, either it's broken or doesn't exist.
-		   just start creating it. */
-		return mail_cache_compress_locked(cache, trans, &unlock);
-	default:
-		/* locking succeeded. */
-		unlock = TRUE;
-		ret = mail_cache_compress_locked(cache, trans, &unlock);
-		if (unlock) {
-			if (mail_cache_unlock(cache) < 0)
-				ret = -1;
-		}
-		return ret;
-	}
+	} else {
+		switch (mail_cache_lock(cache, FALSE)) {
+		case -1:
+			return -1;
+		case 0:
+			/* couldn't lock, either it's broken or doesn't exist.
+			   just start creating it. */
+			break;
+		default:
+			/* locking succeeded. */
+			unlock = TRUE;
+		}
+	}
+	cache->compressing = TRUE;
+	ret = mail_cache_compress_locked(cache, trans, &unlock);
+	cache->compressing = FALSE;
+	if (unlock) {
+		if (mail_cache_unlock(cache) < 0)
+			ret = -1;
+	}
+	return ret;
 }
 
 bool mail_cache_need_compress(struct mail_cache *cache)
diff -r 2358ee07d2db -r f1203dce2d8c src/lib-index/mail-cache-private.h
--- a/src/lib-index/mail-cache-private.h	Thu Sep 11 16:37:32 2008 +0300
+++ b/src/lib-index/mail-cache-private.h	Thu Sep 11 16:52:47 2008 +0300
@@ -173,6 +173,7 @@ struct mail_cache {
 	unsigned int locked:1;
 	unsigned int hdr_modified:1;
 	unsigned int field_header_write_pending:1;
+	unsigned int compressing:1;
 };
 
 struct mail_cache_loop_track {
diff -r 2358ee07d2db -r f1203dce2d8c src/lib-index/mail-cache.c
--- a/src/lib-index/mail-cache.c	Thu Sep 11 16:37:32 2008 +0300
+++ b/src/lib-index/mail-cache.c	Thu Sep 11 16:52:47 2008 +0300
@@ -667,7 +667,8 @@ void mail_cache_view_close(struct mail_c
 {
 	i_assert(view->trans_view == NULL);
 
-	if (view->cache->field_header_write_pending)
+	if (view->cache->field_header_write_pending &&
+	    !view->cache->compressing)
                 (void)mail_cache_header_fields_update(view->cache);
 
 	buffer_free(&view->cached_exists_buf);


More information about the dovecot-cvs mailing list