[dovecot-cvs] dovecot/src/lib-index mail-cache-compress.c, 1.36, 1.37 mail-cache-fields.c, 1.17, 1.18 mail-cache-private.h, 1.25, 1.26 mail-cache-sync-update.c, 1.8, 1.9 mail-cache-transaction.c, 1.44, 1.45 mail-cache.c, 1.72, 1.73

cras at dovecot.org cras at dovecot.org
Fri Sep 30 21:46:32 EEST 2005


Update of /var/lib/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv7024/lib-index

Modified Files:
	mail-cache-compress.c mail-cache-fields.c mail-cache-private.h 
	mail-cache-sync-update.c mail-cache-transaction.c mail-cache.c 
Log Message:
Unlocking cache file can also corrupt it since it modifies it. Added a
return value for it and checks to handle the failure. Fixes a crash in some
error situations.



Index: mail-cache-compress.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache-compress.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- mail-cache-compress.c	25 Sep 2005 10:44:05 -0000	1.36
+++ mail-cache-compress.c	30 Sep 2005 18:46:30 -0000	1.37
@@ -319,7 +319,8 @@
 	default:
 		/* locking succeeded. */
 		ret = mail_cache_compress_locked(cache, view);
-		mail_cache_unlock(cache);
+		if (mail_cache_unlock(cache) < 0)
+			ret = -1;
 		return ret;
 	}
 }

Index: mail-cache-fields.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache-fields.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- mail-cache-fields.c	25 Sep 2005 10:44:05 -0000	1.17
+++ mail-cache-fields.c	30 Sep 2005 18:46:30 -0000	1.18
@@ -349,7 +349,8 @@
 		return -1;
 
 	ret = mail_cache_header_fields_update_locked(cache);
-	mail_cache_unlock(cache);
+	if (mail_cache_unlock(cache) < 0)
+		ret = -1;
 	return ret;
 }
 

Index: mail-cache-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache-private.h,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- mail-cache-private.h	14 May 2005 11:29:36 -0000	1.25
+++ mail-cache-private.h	30 Sep 2005 18:46:30 -0000	1.26
@@ -175,7 +175,8 @@
 /* Explicitly lock the cache file. Returns -1 if error, 1 if ok, 0 if we
    couldn't lock */
 int mail_cache_lock(struct mail_cache *cache);
-void mail_cache_unlock(struct mail_cache *cache);
+/* Returns -1 if cache is / just got corrupted, 0 if ok. */
+int mail_cache_unlock(struct mail_cache *cache);
 
 int mail_cache_write(struct mail_cache *cache, const void *data, size_t size,
 		     uoff_t offset);

Index: mail-cache-sync-update.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache-sync-update.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- mail-cache-sync-update.c	16 Jun 2005 19:26:46 -0000	1.8
+++ mail-cache-sync-update.c	30 Sep 2005 18:46:30 -0000	1.9
@@ -18,7 +18,7 @@
 		return;
 
 	if (ctx->locked)
-		mail_cache_unlock(sync_ctx->view->index->cache);
+		(void)mail_cache_unlock(sync_ctx->view->index->cache);
 	i_free(ctx);
 }
 

Index: mail-cache-transaction.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache-transaction.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -d -r1.44 -r1.45
--- mail-cache-transaction.c	28 Aug 2005 17:04:18 -0000	1.44
+++ mail-cache-transaction.c	30 Sep 2005 18:46:30 -0000	1.45
@@ -294,17 +294,17 @@
 	}
 }
 
-static void
+static int
 mail_cache_transaction_free_space(struct mail_cache_transaction_ctx *ctx)
 {
 	int locked = ctx->cache->locked;
 
 	if (ctx->reserved_space == 0)
-		return;
+		return 0;
 
 	if (!locked) {
 		if (mail_cache_transaction_lock(ctx) <= 0)
-			return;
+			return 0;
 	}
 
 	/* check again - locking might have reopened the cache file */
@@ -316,8 +316,11 @@
                 ctx->reserved_space = 0;
 	}
 
-	if (!locked)
-		mail_cache_unlock(ctx->cache);
+	if (!locked) {
+		if (mail_cache_unlock(ctx->cache) < 0)
+			return -1;
+	}
+	return 0;
 }
 
 static int
@@ -343,8 +346,10 @@
 		}
 		ret = mail_cache_transaction_reserve_more(ctx, max_size,
 							  commit);
-		if (!locked)
-			mail_cache_unlock(ctx->cache);
+		if (!locked) {
+			if (mail_cache_unlock(ctx->cache) < 0)
+				return -1;
+		}
 
 		if (ret < 0)
 			return -1;
@@ -369,7 +374,8 @@
 	if (size == max_size && commit) {
 		/* final commit - see if we can free the rest of the
 		   reserved space */
-		mail_cache_transaction_free_space(ctx);
+		if (mail_cache_transaction_free_space(ctx) < 0)
+			return -1;
 	}
 
 	i_assert(size >= min_size);
@@ -568,7 +574,8 @@
 		ret = -1;
 	}
 
-	mail_cache_unlock(cache);
+	if (mail_cache_unlock(cache) < 0)
+		ret = -1;
 	mail_cache_transaction_free(ctx);
 	return ret;
 }
@@ -598,7 +605,7 @@
 							      buf[size+1]);
 				} while (size > 0);
 			}
-			mail_cache_unlock(cache);
+			(void)mail_cache_unlock(cache);
 		}
 	}
 
@@ -620,13 +627,14 @@
 
 	/* re-read header to make sure we don't lose any fields. */
 	if (mail_cache_header_fields_read(cache) < 0) {
-		mail_cache_unlock(cache);
+		(void)mail_cache_unlock(cache);
 		return -1;
 	}
 
 	if (ctx->cache->field_file_map[field] != (uint32_t)-1) {
 		/* it was already added */
-		mail_cache_unlock(cache);
+		if (mail_cache_unlock(cache) < 0)
+			return -1;
 		return 0;
 	}
 
@@ -660,7 +668,8 @@
 	}
 	t_pop();
 
-	mail_cache_unlock(cache);
+	if (mail_cache_unlock(cache) < 0)
+		ret = -1;
 	return ret;
 }
 

Index: mail-cache.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache.c,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -d -r1.72 -r1.73
--- mail-cache.c	27 Aug 2005 12:29:54 -0000	1.72
+++ mail-cache.c	30 Sep 2005 18:46:30 -0000	1.73
@@ -391,7 +391,7 @@
 		}
 
 		/* okay, so it was just compressed. try again. */
-		mail_cache_unlock(cache);
+		(void)mail_cache_unlock(cache);
 		if ((ret = mail_cache_reopen(cache)) <= 0)
 			break;
 		ret = 0;
@@ -406,7 +406,7 @@
 		if (mail_cache_map(cache, 0, 0) == 0)
 			cache->hdr_copy = *cache->hdr;
 		else {
-			mail_cache_unlock(cache);
+			(void)mail_cache_unlock(cache);
 			ret = -1;
 		}
 	}
@@ -438,29 +438,33 @@
 		cache->need_compress = TRUE;
 }
 
-void mail_cache_unlock(struct mail_cache *cache)
+int mail_cache_unlock(struct mail_cache *cache)
 {
+	int ret = 0;
+
 	i_assert(cache->locked);
 
 	if (cache->field_header_write_pending)
-                (void)mail_cache_header_fields_update(cache);
+                ret = mail_cache_header_fields_update(cache);
 
 	cache->locked = FALSE;
 
 	if (MAIL_CACHE_IS_UNUSABLE(cache)) {
 		/* we found it to be broken during the lock. just clean up. */
 		cache->hdr_modified = FALSE;
-		return;
+		return -1;
 	}
 
 	if (cache->hdr_modified) {
 		cache->hdr_modified = FALSE;
-		(void)mail_cache_write(cache, &cache->hdr_copy,
-				       sizeof(cache->hdr_copy), 0);
+		if (mail_cache_write(cache, &cache->hdr_copy,
+				     sizeof(cache->hdr_copy), 0) < 0)
+			ret = -1;
 		mail_cache_update_need_compress(cache);
 	}
 
 	(void)mail_cache_lock_file(cache, F_UNLCK);
+	return ret;
 }
 
 int mail_cache_write(struct mail_cache *cache, const void *data, size_t size,



More information about the dovecot-cvs mailing list