[dovecot-cvs] dovecot/src/lib-index mail-cache-compress.c, 1.41, 1.42 mail-cache-private.h, 1.28, 1.29 mail-cache.c, 1.79, 1.80

cras at dovecot.org cras at dovecot.org
Wed May 3 23:07:16 EEST 2006


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

Modified Files:
	mail-cache-compress.c mail-cache-private.h mail-cache.c 
Log Message:
Don't compress cache file if it was just compressed by another process.



Index: mail-cache-compress.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache-compress.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- mail-cache-compress.c	26 Feb 2006 10:05:13 -0000	1.41
+++ mail-cache-compress.c	3 May 2006 20:07:13 -0000	1.42
@@ -3,6 +3,9 @@
 #include "lib.h"
 #include "buffer.h"
 #include "ostream.h"
+#include "nfs-workarounds.h"
+#include "read-full.h"
+#include "close-keep-errno.h"
 #include "file-dotlock.h"
 #include "file-cache.h"
 #include "file-set-size.h"
@@ -236,21 +239,52 @@
 	return mail_index_transaction_commit(&t, &seq, &offset);
 }
 
+static int mail_cache_compress_has_file_changed(struct mail_cache *cache)
+{
+	struct mail_cache_header hdr;
+	unsigned int i;
+	int fd, ret;
+
+	for (i = 0;; i++) {
+		fd = nfs_safe_open(cache->filepath, O_RDONLY);
+		if (fd == -1) {
+			if (errno == ENOENT)
+				return 0;
+
+			mail_cache_set_syscall_error(cache, "open()");
+			return -1;
+		}
+
+		ret = read_full(fd, &hdr, sizeof(hdr));
+		close_keep_errno(fd);
+
+		if (ret >= 0) {
+			if (ret == 0)
+				return 0;
+			if (cache->need_compress_file_seq == (uint32_t)-1) {
+				/* previously it didn't exist */
+				return 1;
+			}
+			return hdr.file_seq != cache->need_compress_file_seq;
+		} else if (errno != ESTALE || i >= NFS_ESTALE_RETRY_COUNT) {
+			mail_cache_set_syscall_error(cache, "read()");
+			return -1;
+		}
+	}
+	return -1;
+}
+
 static int mail_cache_compress_locked(struct mail_cache *cache,
 				      struct mail_index_view *view)
 {
 	struct dotlock *dotlock;
         mode_t old_mask;
-	int fd;
+	int fd, ret;
 
 	/* get the latest info on fields */
 	if (mail_cache_header_fields_read(cache) < 0)
 		return -1;
 
-#ifdef DEBUG
-	i_warning("Compressing cache file %s", cache->filepath);
-#endif
-
 	old_mask = umask(cache->index->mode ^ 0666);
 	fd = file_dotlock_open(&cache->dotlock_settings, cache->filepath,
 			       0, &dotlock);
@@ -261,6 +295,21 @@
 		return -1;
 	}
 
+	if ((ret = mail_cache_compress_has_file_changed(cache)) != 0) {
+		if (ret < 0)
+			return -1;
+
+		/* was just compressed, forget this */
+		cache->need_compress_file_seq = 0;
+		file_dotlock_delete(&dotlock);
+		return mail_cache_reopen(cache);
+	}
+
+#ifdef DEBUG
+	i_warning("Compressing cache file %s (%u)",
+		  cache->filepath, cache->need_compress_file_seq);
+#endif
+
 	if (cache->index->gid != (gid_t)-1 &&
 	    fchown(fd, (uid_t)-1, cache->index->gid) < 0) {
 		mail_cache_set_syscall_error(cache, "fchown()");
@@ -268,8 +317,6 @@
 		return -1;
 	}
 
-	// FIXME: check that cache file wasn't just recreated
-
 	if (mail_cache_copy(cache, view, fd) < 0) {
 		(void)file_dotlock_delete(&dotlock);
 		return -1;
@@ -294,7 +341,7 @@
 	if (mail_cache_header_fields_read(cache) < 0)
 		return -1;
 
-	cache->need_compress = FALSE;
+	cache->need_compress_file_seq = 0;
 	return 0;
 }
 
@@ -329,5 +376,5 @@
 
 bool mail_cache_need_compress(struct mail_cache *cache)
 {
-	return cache->need_compress;
+	return cache->need_compress_file_seq != 0;
 }

Index: mail-cache-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache-private.h,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- mail-cache-private.h	5 Feb 2006 12:46:08 -0000	1.28
+++ mail-cache-private.h	3 May 2006 20:07:13 -0000	1.29
@@ -140,11 +140,14 @@
 	unsigned int fields_count;
 	struct hash_table *field_name_hash; /* name -> idx */
 
+	/* 0 is no need for compression, otherwise the file sequence number
+	   which we want compressed. */
+	uint32_t need_compress_file_seq;
+
 	unsigned int *file_field_map;
 	unsigned int file_fields_count;
 
 	unsigned int locked:1;
-	unsigned int need_compress:1;
 	unsigned int hdr_modified:1;
 	unsigned int field_header_write_pending:1;
 };

Index: mail-cache.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache.c,v
retrieving revision 1.79
retrieving revision 1.80
diff -u -d -r1.79 -r1.80
--- mail-cache.c	16 Feb 2006 15:23:03 -0000	1.79
+++ mail-cache.c	3 May 2006 20:07:13 -0000	1.80
@@ -4,6 +4,7 @@
 #include "array.h"
 #include "buffer.h"
 #include "hash.h"
+#include "nfs-workarounds.h"
 #include "file-cache.h"
 #include "mmap-util.h"
 #include "write-full.h"
@@ -71,17 +72,18 @@
 	const struct mail_index_ext *ext;
 
 	if (MAIL_CACHE_IS_UNUSABLE(cache) &&
-	    (cache->need_compress || MAIL_INDEX_IS_IN_MEMORY(cache->index))) {
+	    (cache->need_compress_file_seq != 0 ||
+	     MAIL_INDEX_IS_IN_MEMORY(cache->index))) {
 		/* reopening does no good */
 		return 0;
 	}
 
 	mail_cache_file_close(cache);
 
-	cache->fd = open(cache->filepath, O_RDWR);
+	cache->fd = nfs_safe_open(cache->filepath, O_RDWR);
 	if (cache->fd == -1) {
 		if (errno == ENOENT)
-			cache->need_compress = TRUE;
+			cache->need_compress_file_seq = (uint32_t)-1;
 		else
 			mail_cache_set_syscall_error(cache, "open()");
 		return -1;
@@ -103,7 +105,7 @@
 		   file_seq really is corrupted. either way, this shouldn't
 		   happen often so we'll just mark cache to be compressed
 		   later which fixes this. */
-		cache->need_compress = TRUE;
+		cache->need_compress_file_seq = cache->hdr->file_seq;
 		mail_index_view_close(&view);
 		return 0;
 	}
@@ -197,7 +199,9 @@
 		cache->hdr = cache->data;
 
 		if (offset == 0 && !mail_cache_verify_header(cache)) {
-			cache->need_compress = TRUE;
+			cache->need_compress_file_seq =
+				cache->hdr->file_seq != 0 ?
+				cache->hdr->file_seq : (uint32_t)-1;
 			return -1;
 		}
 		return 0;
@@ -216,7 +220,7 @@
 		if (cache->fd == -1) {
 			/* unusable, waiting for compression or
 			   index is in memory */
-			i_assert(cache->need_compress ||
+			i_assert(cache->need_compress_file_seq != 0 ||
 				 MAIL_INDEX_IS_IN_MEMORY(cache->index));
 			return -1;
 		}
@@ -237,7 +241,9 @@
 	cache->hdr = cache->mmap_base;
 
 	if (!mail_cache_verify_header(cache)) {
-		cache->need_compress = TRUE;
+		cache->need_compress_file_seq =
+			cache->hdr->file_seq != 0 ?
+			cache->hdr->file_seq : (uint32_t)-1;
 		return -1;
 	}
 
@@ -249,10 +255,10 @@
 	if (MAIL_INDEX_IS_IN_MEMORY(cache->index))
 		return 0;
 
-	cache->fd = open(cache->filepath, O_RDWR);
+	cache->fd = nfs_safe_open(cache->filepath, O_RDWR);
 	if (cache->fd == -1) {
 		if (errno == ENOENT) {
-			cache->need_compress = TRUE;
+			cache->need_compress_file_seq = (uint32_t)-1;
 			return 0;
 		}
 
@@ -327,7 +333,7 @@
 	struct mail_cache *cache;
 
 	cache = mail_cache_alloc(index);
-	cache->need_compress = TRUE;
+	cache->need_compress_file_seq = (uint32_t)-1;
 	return cache;
 }
 
@@ -449,14 +455,14 @@
 	if (cont_percentage >= COMPRESS_CONTINUED_PERCENTAGE &&
 	    hdr->used_file_size >= COMPRESS_MIN_SIZE) {
 		/* too many continued rows, compress */
-		cache->need_compress = TRUE;
+		cache->need_compress_file_seq = hdr->file_seq;
 	}
 
 	/* see if we've reached the max. deleted space in file */
 	max_del_space = hdr->used_file_size / 100 * COMPRESS_PERCENTAGE;
 	if (hdr->deleted_space >= max_del_space &&
 	    hdr->used_file_size >= COMPRESS_MIN_SIZE)
-		cache->need_compress = TRUE;
+		cache->need_compress_file_seq = hdr->file_seq;
 }
 
 int mail_cache_unlock(struct mail_cache *cache)



More information about the dovecot-cvs mailing list