[dovecot-cvs] dovecot/src/lib-index mail-cache-compress.c, 1.8, 1.9 mail-cache-transaction.c, 1.10, 1.11 mail-index-private.h, 1.23, 1.24 mail-index-transaction-private.h, 1.9, 1.10 mail-index-transaction.c, 1.17, 1.18 mail-transaction-log.c, 1.43, 1.44

cras at procontrol.fi cras at procontrol.fi
Mon Jul 5 00:56:14 EEST 2004


Update of /home/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv31690/lib-index

Modified Files:
	mail-cache-compress.c mail-cache-transaction.c 
	mail-index-private.h mail-index-transaction-private.h 
	mail-index-transaction.c mail-transaction-log.c 
Log Message:
Make sure we don't set cache_offsets to old cache files.



Index: mail-cache-compress.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-cache-compress.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- mail-cache-compress.c	4 Jul 2004 21:07:43 -0000	1.8
+++ mail-cache-compress.c	4 Jul 2004 21:56:12 -0000	1.9
@@ -188,7 +188,8 @@
 		if (keep_fields == cached_fields &&
 		    cache_rec->prev_offset == 0) {
 			/* just one unmodified block, save it */
-                        mail_index_update_cache(t, seq, output->offset, NULL);
+			mail_index_update_cache(t, seq, hdr.file_seq,
+						output->offset, NULL);
 			o_stream_send(output, cache_rec, cache_rec->size);
 
 			if ((cache_rec->size & 3) != 0) {
@@ -198,7 +199,8 @@
 		} else {
 			/* a) dropping fields
 			   b) multiple blocks, sort them into buffer */
-                        mail_index_update_cache(t, seq, output->offset, NULL);
+			mail_index_update_cache(t, seq, hdr.file_seq,
+						output->offset, NULL);
 
 			t_push();
 			cache_rec = mail_cache_compress_record(cache_view, seq,

Index: mail-cache-transaction.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-cache-transaction.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- mail-cache-transaction.c	4 Jul 2004 20:00:47 -0000	1.10
+++ mail-cache-transaction.c	4 Jul 2004 21:56:12 -0000	1.11
@@ -369,6 +369,7 @@
 		   synced. */
 		for (; seq_idx < seq_limit; seq_idx++) {
 			mail_index_update_cache(ctx->trans, seq[seq_idx],
+						cache->hdr->file_seq,
 						write_offset, &old_offset);
 			if (old_offset != 0) {
 				/* we added records for this message multiple

Index: mail-index-private.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-private.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- mail-index-private.h	4 Jul 2004 20:00:47 -0000	1.23
+++ mail-index-private.h	4 Jul 2004 21:56:12 -0000	1.24
@@ -132,8 +132,8 @@
 
 void mail_index_reset_cache(struct mail_index_transaction *t,
 			    uint32_t new_file_seq);
-void mail_index_update_cache(struct mail_index_transaction *t,
-			     uint32_t seq, uint32_t offset,
+void mail_index_update_cache(struct mail_index_transaction *t, uint32_t seq,
+			     uint32_t file_seq, uint32_t offset,
 			     uint32_t *old_offset_r);
 
 int mail_index_fix_header(struct mail_index *index, struct mail_index_map *map,

Index: mail-index-transaction-private.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-transaction-private.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- mail-index-transaction-private.h	4 Jul 2004 20:00:47 -0000	1.9
+++ mail-index-transaction-private.h	4 Jul 2004 21:56:12 -0000	1.10
@@ -22,7 +22,7 @@
 
 	buffer_t *extra_rec_updates[MAIL_INDEX_MAX_EXTRA_RECORDS];
 
-	uint32_t new_cache_file_seq;
+	uint32_t new_cache_file_seq, last_cache_file_seq;
 	buffer_t *cache_updates;
         struct mail_cache_transaction_ctx *cache_trans_ctx;
 

Index: mail-index-transaction.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-transaction.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- mail-index-transaction.c	4 Jul 2004 20:00:47 -0000	1.17
+++ mail-index-transaction.c	4 Jul 2004 21:56:12 -0000	1.18
@@ -563,18 +563,44 @@
 	return FALSE;
 }
 
+static void
+mail_index_transaction_reset_cache_updates(struct mail_index_transaction *t)
+{
+	struct mail_index_record *rec;
+	uint32_t seq;
+
+	if (t->last_cache_file_seq == 0)
+		return;
+
+	buffer_set_used_size(t->cache_updates, 0);
+
+	if (t->first_new_seq != 0) {
+		for (seq = t->first_new_seq; seq <= t->last_new_seq; seq++) {
+			rec = mail_index_transaction_lookup(t, seq);
+			rec->cache_offset = 0;
+		}
+	}
+}
+
 void mail_index_reset_cache(struct mail_index_transaction *t,
 			    uint32_t new_file_seq)
 {
+	mail_index_transaction_reset_cache_updates(t);
 	t->new_cache_file_seq = new_file_seq;
+        t->last_cache_file_seq = new_file_seq;
 }
 
-void mail_index_update_cache(struct mail_index_transaction *t,
-			     uint32_t seq, uint32_t offset,
+void mail_index_update_cache(struct mail_index_transaction *t, uint32_t seq,
+			     uint32_t file_seq, uint32_t offset,
 			     uint32_t *old_offset_r)
 {
 	struct mail_index_record *rec;
 
+	if (file_seq > t->last_cache_file_seq) {
+		mail_index_transaction_reset_cache_updates(t);
+                t->last_cache_file_seq = file_seq;
+	}
+
 	if (seq >= t->first_new_seq) {
 		/* just appended message, modify it directly */
 		rec = mail_index_transaction_lookup(t, seq);

Index: mail-transaction-log.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-log.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- mail-transaction-log.c	28 Jun 2004 12:08:00 -0000	1.43
+++ mail-transaction-log.c	4 Jul 2004 21:56:12 -0000	1.44
@@ -883,62 +883,45 @@
 	return ret;
 }
 
-static int mail_transaction_log_fix_appends(struct mail_transaction_log *log,
-					    struct mail_index_transaction *t)
+static void
+mail_transaction_log_append_fix(struct mail_index_transaction *t,
+				const struct mail_transaction_header *hdr,
+				const void *data)
 {
-	struct mail_transaction_log_view *sync_view;
+        const struct mail_transaction_append_header *append_hdr = data;
 	const struct mail_index_record *old, *old_end;
 	struct mail_index_record *appends, *end, *rec, *dest;
-        const struct mail_transaction_append_header *append_hdr;
-	const struct mail_transaction_header *hdr;
-	const void *data;
+	uint32_t record_size = t->append_record_size;
 	size_t size;
-	uint32_t record_size;
-	int ret, deleted = FALSE;
+	int deleted = FALSE;
 
 	if (t->appends == NULL)
-		return 0;
+		return;
 
-	record_size = t->append_record_size;
 	appends = buffer_get_modifyable_data(t->appends, &size);
 	end = PTR_OFFSET(appends, size);
 
 	if (appends == end)
-		return 0;
+		return;
 
 	/* we'll just check that none of the appends are already in
 	   transaction log. this could happen if we crashed before we had
 	   a chance to update index file */
-	sync_view = mail_transaction_log_view_open(log);
-	ret = mail_transaction_log_view_set(sync_view, t->view->log_file_seq,
-					    t->view->log_file_offset,
-					    log->head->hdr.file_seq,
-					    log->head->hdr.used_size,
-					    MAIL_TRANSACTION_TYPE_MASK);
-	while ((ret = mail_transaction_log_view_next(sync_view,
-						     &hdr, &data, NULL)) == 1) {
-		if ((hdr->type & MAIL_TRANSACTION_TYPE_MASK) !=
-		    MAIL_TRANSACTION_APPEND)
-			continue;
-
-                append_hdr = data;
-
-		old = CONST_PTR_OFFSET(data, sizeof(*append_hdr));
-		old_end = CONST_PTR_OFFSET(data, hdr->size);
-		while (old != old_end) {
-			/* appends are sorted */
-			for (rec = appends; rec != end; ) {
-				if (rec->uid >= old->uid) {
-					if (rec->uid == old->uid) {
-						rec->uid = 0;
-						deleted = TRUE;
-					}
-					break;
+	old = CONST_PTR_OFFSET(data, sizeof(*append_hdr));
+	old_end = CONST_PTR_OFFSET(data, hdr->size);
+	while (old != old_end) {
+		/* appends are sorted */
+		for (rec = appends; rec != end; ) {
+			if (rec->uid >= old->uid) {
+				if (rec->uid == old->uid) {
+					rec->uid = 0;
+					deleted = TRUE;
 				}
-				rec = PTR_OFFSET(rec, record_size);
+				break;
 			}
-                        old = CONST_PTR_OFFSET(old, append_hdr->record_size);
+			rec = PTR_OFFSET(rec, record_size);
 		}
+		old = CONST_PTR_OFFSET(old, append_hdr->record_size);
 	}
 
 	if (deleted) {
@@ -953,6 +936,44 @@
 		buffer_set_used_size(t->appends,
 				     (char *)dest - (char *)appends);
 	}
+}
+
+static int mail_transaction_log_scan_pending(struct mail_transaction_log *log,
+					     struct mail_index_transaction *t)
+{
+	struct mail_transaction_log_view *sync_view;
+	const struct mail_transaction_header *hdr;
+	const void *data;
+	uint32_t max_cache_file_seq = 0;
+	int ret;
+
+	sync_view = mail_transaction_log_view_open(log);
+	ret = mail_transaction_log_view_set(sync_view, t->view->log_file_seq,
+					    t->view->log_file_offset,
+					    log->head->hdr.file_seq,
+					    log->head->hdr.used_size,
+					    MAIL_TRANSACTION_TYPE_MASK);
+	while ((ret = mail_transaction_log_view_next(sync_view,
+						     &hdr, &data, NULL)) == 1) {
+		switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
+		case MAIL_TRANSACTION_APPEND:
+			mail_transaction_log_append_fix(t, hdr, data);
+			break;
+		case MAIL_TRANSACTION_CACHE_RESET: {
+			const struct mail_transaction_cache_reset *reset = data;
+
+			max_cache_file_seq = reset->new_file_seq;
+			break;
+		}
+		}
+	}
+
+	/* make sure we're not writing cache_offsets to old cache file */
+	if (t->new_cache_file_seq == 0 && max_cache_file_seq != 0 &&
+	    max_cache_file_seq != t->last_cache_file_seq) {
+		buffer_free(t->cache_updates);
+		t->cache_updates = NULL;
+	}
 
 	mail_transaction_log_view_close(sync_view);
 	return ret;
@@ -1107,10 +1128,15 @@
 	file = log->head;
 	append_offset = file->hdr.used_size;
 
-	if (mail_transaction_log_fix_appends(log, t) < 0) {
-		if (!log->index->log_locked)
-			(void)mail_transaction_log_file_lock(file, F_UNLCK);
-		return -1;
+	if (t->appends != NULL ||
+	    (t->cache_updates != NULL && t->new_cache_file_seq == 0)) {
+		if (mail_transaction_log_scan_pending(log, t) < 0) {
+			if (!log->index->log_locked) {
+				(void)mail_transaction_log_file_lock(file,
+								     F_UNLCK);
+			}
+			return -1;
+		}
 	}
 
 	ret = 0;



More information about the dovecot-cvs mailing list