[dovecot-cvs] dovecot/src/lib-index mail-cache.c,1.1,1.2 mail-index.h,1.86,1.87

cras at procontrol.fi cras at procontrol.fi
Mon Aug 11 05:26:48 EEST 2003


Update of /home/cvs/dovecot/src/lib-index
In directory danu:/tmp/cvs-serv11533

Modified Files:
	mail-cache.c mail-index.h 
Log Message:
Fixes for opening broken cache file.



Index: mail-cache.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-cache.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- mail-cache.c	6 Aug 2003 20:15:31 -0000	1.1
+++ mail-cache.c	11 Aug 2003 01:26:46 -0000	1.2
@@ -86,6 +86,7 @@
 
 	unsigned int anon_mmap:1;
 	unsigned int mmap_refresh:1;
+	unsigned int silent:1;
 };
 
 struct mail_cache_transaction_ctx {
@@ -212,7 +213,20 @@
 
 static int mmap_verify_header(struct mail_cache *cache)
 {
-	struct mail_cache_header *hdr = cache->header;
+	struct mail_cache_header *hdr;
+
+	/* check that the header is still ok */
+	if (cache->mmap_length < sizeof(struct mail_cache_header))
+		return mail_cache_set_corrupted(cache, "File too small");
+	cache->header = hdr = cache->mmap_base;
+
+	if (cache->header->indexid != cache->index->indexid) {
+		/* index id changed */
+		if (cache->header->indexid != 0)
+			mail_cache_set_corrupted(cache, "indexid changed");
+		cache->index->inconsistent = TRUE; /* easiest way to rebuild */
+		return FALSE;
+	}
 
 	if (cache->trans_ctx != NULL) {
 		/* we've updated used_file_size, do nothing */
@@ -243,7 +257,8 @@
 	return TRUE;
 }
 
-static int mmap_update(struct mail_cache *cache, size_t offset, size_t size)
+static int mmap_update_nocheck(struct mail_cache *cache,
+			       size_t offset, size_t size)
 {
 	if (cache->header != NULL &&
 	    cache->header->indexid != cache->index->indexid) {
@@ -294,12 +309,13 @@
 		return mail_cache_set_syscall_error(cache, "mmap()");
 	}
 
-	/* check that the header is still ok */
-	if (cache->mmap_length < sizeof(struct mail_cache_header))
-		return mail_cache_set_corrupted(cache, "File too small");
+	return TRUE;
+}
 
-	cache->header = cache->mmap_base;
-	return mmap_verify_header(cache);
+static int mmap_update(struct mail_cache *cache, size_t offset, size_t size)
+{
+	return mmap_update_nocheck(cache, offset, size) &&
+		mmap_verify_header(cache);
 }
 
 static int mail_cache_open_and_verify(struct mail_cache *cache, int silent)
@@ -326,19 +342,33 @@
 		return 0;
 
 	cache->mmap_refresh = TRUE;
-	if (!mmap_update(cache, 0, sizeof(struct mail_cache_header)))
+	if (!mmap_update_nocheck(cache, 0, sizeof(struct mail_cache_header)))
 		return -1;
 
 	/* verify that this really is the cache for wanted index */
-	if (cache->header->indexid != cache->index->indexid) {
-		if (!silent)
-			mail_cache_set_corrupted(cache, "IndexID mismatch");
+	cache->silent = silent;
+	if (!mmap_verify_header(cache)) {
+		cache->silent = FALSE;
 		return 0;
 	}
 
+	cache->silent = FALSE;
 	return 1;
 }
 
+static void mail_index_clear_cache_offsets(struct mail_index *index)
+{
+	struct mail_index_record *rec;
+
+	index->file_sync_stamp = ioloop_time-61;
+
+	rec = index->lookup(index, 1);
+	while (rec != NULL) {
+		rec->cache_offset = 0;
+		rec = index->next(index, rec);
+	}
+}
+
 static int mail_cache_open_or_create_file(struct mail_cache *cache,
 					  struct mail_cache_header *hdr)
 {
@@ -351,6 +381,11 @@
 	if (ret != 0)
 		return ret > 0;
 
+	/* we'll have to clear cache_offsets which requires exclusive lock */
+	cache->index->inconsistent = FALSE;
+	if (!mail_index_set_lock(cache->index, MAIL_LOCK_EXCLUSIVE))
+		return FALSE;
+
 	/* maybe a rebuild.. */
 	fd = file_dotlock_open(cache->filepath, NULL, MAIL_CACHE_LOCK_TIMEOUT,
 			       MAIL_CACHE_LOCK_STALE_TIMEOUT, NULL, NULL);
@@ -378,6 +413,8 @@
 		return FALSE;
 	}
 
+	mail_index_clear_cache_offsets(cache->index);
+
 	mail_cache_file_close(cache);
 	cache->fd = dup(fd);
 
@@ -424,6 +461,9 @@
 		}
 	}
 
+	/* unset inconsistency - we already rebuilt the cache file */
+	index->inconsistent = FALSE;
+
 	return TRUE;
 }
 
@@ -552,7 +592,7 @@
 	while (rec != NULL) {
 		cache_rec = mail_cache_lookup(cache, rec);
 		if (cache_rec == NULL)
-			rec->data_offset = 0;
+			rec->cache_offset = 0;
 		else if ((nbo_to_uint32(cache_rec->next_offset) & 2) == 0 &&
 			 remove_fields == 0) {
 			/* just one unmodified block, copy it */
@@ -560,7 +600,7 @@
 			i_assert(offset + size <= new_file_size);
 
 			memcpy(mmap_base + offset, cache_rec, size);
-			rec->data_offset = uint32_to_nbo(offset | 2);
+			rec->cache_offset = uint32_to_nbo(offset | 2);
 
 			size = (size + 3) & ~3;
 			offset += size;
@@ -575,7 +615,7 @@
 			used_fields |= cache_rec->fields;
 			t_pop();
 
-			rec->data_offset = uint32_to_nbo(offset | 2);
+			rec->cache_offset = uint32_to_nbo(offset | 2);
 			offset += size;
 		}
 
@@ -1280,15 +1320,15 @@
 	rec = INDEX_RECORD_AT(ctx->cache->index, ctx->last_idx);
 	ctx->last_idx = (unsigned int)-1;
 
-	cache_rec = cache_get_record(cache, rec->data_offset);
+	cache_rec = cache_get_record(cache, rec->cache_offset);
 	if (cache_rec == NULL) {
 		/* first cache record - update offset in index file */
 		i_assert(cache->index->lock_type == MAIL_LOCK_EXCLUSIVE);
 
-		rec->data_offset = uint32_to_nbo(write_offset);
+		rec->cache_offset = uint32_to_nbo(write_offset);
 
 		/* mark used-bit to be updated later */
-		update_offset = (char *) &rec->data_offset -
+		update_offset = (char *) &rec->cache_offset -
 			(char *) cache->index->mmap_base;
 		mark_update(&ctx->index_marks, update_offset, write_offset | 2);
 	} else {
@@ -1339,14 +1379,10 @@
 			return NULL;
 	}
 
-	cache_rec = cache_get_record(cache, rec->data_offset);
+	cache_rec = cache_get_record(cache, rec->cache_offset);
 	if (cache_rec == NULL)
 		return NULL;
 
-	if (cache_rec->fields == 0) {
-		mail_cache_set_corrupted(cache, "record has no fields");
-		return NULL;
-	}
 	return cache_rec;
 }
 
@@ -1690,9 +1726,11 @@
 {
 	va_list va;
 
-	/* rebuild */
-        INDEX_MARK_CORRUPTED(cache->index);
-        mail_cache_mark_file_deleted(cache);
+	mail_cache_mark_file_deleted(cache);
+	cache->index->inconsistent = TRUE; /* easiest way to rebuild */
+
+	if (cache->silent)
+		return FALSE;
 
 	va_start(va, fmt);
 	t_push();

Index: mail-index.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index.h,v
retrieving revision 1.86
retrieving revision 1.87
diff -u -d -r1.86 -r1.87
--- mail-index.h	10 Aug 2003 23:56:22 -0000	1.86
+++ mail-index.h	11 Aug 2003 01:26:46 -0000	1.87
@@ -25,10 +25,6 @@
 	_MAIL_INDEX_OPEN_FLAG_CREATING		= 0x100
 };
 
-enum mail_index_header_compat {
-	MAIL_INDEX_COMPAT_LITTLE_ENDIAN	= 0x01
-};
-
 enum mail_index_header_flag {
 	/* Rebuild flag is set while index is being rebuilt or when
 	   some error is noticed in the index file. If this flag is set,
@@ -133,7 +129,7 @@
 struct mail_index_record {
 	uint32_t uid;
 	uint32_t msg_flags;
-	uint32_t data_offset;
+	uint32_t cache_offset;
 };
 
 struct mail_index {



More information about the dovecot-cvs mailing list