changeset 12518:88577ccb1380

lib-storage: Removed struct index_transaction_context. All of its contents are now in struct mailbox_transaction_context.
author Timo Sirainen <tss@iki.fi>
date Sun, 05 Dec 2010 21:39:09 +0000
parents 7c147f053c9b
children b63ff46f82ee
files src/lib-storage/index/dbox-common/dbox-mail.c src/lib-storage/index/index-mail-headers.c src/lib-storage/index/index-mail.c src/lib-storage/index/index-mail.h src/lib-storage/index/index-storage.c src/lib-storage/index/index-storage.h src/lib-storage/index/index-transaction.c src/lib-storage/index/maildir/maildir-save.c src/lib-storage/index/mbox/mbox-mail.c src/lib-storage/index/mbox/mbox-save.c src/lib-storage/index/mbox/mbox-storage.c src/lib-storage/index/mbox/mbox-storage.h src/lib-storage/mail-storage-private.h src/plugins/virtual/virtual-mail.c src/plugins/virtual/virtual-save.c src/plugins/virtual/virtual-transaction.c src/plugins/virtual/virtual-transaction.h
diffstat 17 files changed, 158 insertions(+), 163 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/dbox-common/dbox-mail.c	Sun Dec 05 21:11:03 2010 +0000
+++ b/src/lib-storage/index/dbox-common/dbox-mail.c	Sun Dec 05 21:39:09 2010 +0000
@@ -167,8 +167,8 @@
 	string_t *str;
 
 	str = str_new(imail->data_pool, 64);
-	if (mail_cache_lookup_field(imail->trans->cache_view, str,
-				    imail->mail.mail.seq,
+	if (mail_cache_lookup_field(imail->mail.mail.transaction->cache_view,
+				    str, imail->mail.mail.seq,
 				    ibox->cache_fields[cache_field].idx) > 0) {
 		*value_r = str_c(str);
 		return 0;
--- a/src/lib-storage/index/index-mail-headers.c	Sun Dec 05 21:11:03 2010 +0000
+++ b/src/lib-storage/index/index-mail-headers.c	Sun Dec 05 21:39:09 2010 +0000
@@ -44,6 +44,7 @@
 
 static void index_mail_parse_header_finish(struct index_mail *mail)
 {
+	struct mail *_mail = &mail->mail.mail;
 	const struct index_mail_line *lines;
 	const unsigned char *header, *data;
 	const uint8_t *match;
@@ -68,9 +69,8 @@
 		while (match_idx < lines[i].field_idx &&
 		       match_idx < match_count) {
 			if (HEADER_MATCH_USABLE(mail, match[match_idx]) &&
-			    mail_cache_field_can_add(mail->trans->cache_trans,
-						     mail->data.seq,
-						     match_idx)) {
+			    mail_cache_field_can_add(_mail->transaction->cache_trans,
+						     _mail->seq, match_idx)) {
 				/* this header doesn't exist. remember that. */
 				i_assert((match[match_idx] &
 					  HEADER_MATCH_FLAG_FOUND) == 0);
@@ -87,9 +87,8 @@
 			match_idx++;
 		}
 
-		if (!mail_cache_field_can_add(mail->trans->cache_trans,
-					      mail->data.seq,
-					      lines[i].field_idx)) {
+		if (!mail_cache_field_can_add(_mail->transaction->cache_trans,
+					      _mail->seq, lines[i].field_idx)) {
 			/* header is already cached */
 			j = i + 1;
 			continue;
@@ -132,9 +131,8 @@
 
 	for (; match_idx < match_count; match_idx++) {
 		if (HEADER_MATCH_USABLE(mail, match[match_idx]) &&
-		    mail_cache_field_can_add(mail->trans->cache_trans,
-					     mail->data.seq,
-					     match_idx)) {
+		    mail_cache_field_can_add(_mail->transaction->cache_trans,
+					     _mail->seq, match_idx)) {
 			/* this header doesn't exist. remember that. */
 			i_assert((match[match_idx] &
 				  HEADER_MATCH_FLAG_FOUND) == 0);
@@ -176,17 +174,18 @@
 
 static void index_mail_parse_header_register_all_wanted(struct index_mail *mail)
 {
+	struct mail *_mail = &mail->mail.mail;
 	const struct mail_cache_field *all_cache_fields;
 	unsigned int i, count;
 
 	all_cache_fields =
-		mail_cache_register_get_list(mail->mail.mail.box->cache,
+		mail_cache_register_get_list(_mail->box->cache,
 					     pool_datastack_create(), &count);
 	for (i = 0; i < count; i++) {
 		if (strncasecmp(all_cache_fields[i].name, "hdr.", 4) != 0)
 			continue;
-		if (!mail_cache_field_want_add(mail->trans->cache_trans,
-					       mail->data.seq, i))
+		if (!mail_cache_field_want_add(_mail->transaction->cache_trans,
+					       _mail->seq, i))
 			continue;
 
 		array_idx_set(&mail->header_match, all_cache_fields[i].idx,
@@ -265,6 +264,7 @@
 
 static void index_mail_parse_finish_imap_envelope(struct index_mail *mail)
 {
+	struct mail *_mail = &mail->mail.mail;
 	const unsigned int cache_field_envelope =
 		mail->ibox->cache_fields[MAIL_CACHE_IMAP_ENVELOPE].idx;
 	string_t *str;
@@ -273,8 +273,8 @@
 	imap_envelope_write_part_data(mail->data.envelope_data, str);
 	mail->data.envelope = str_c(str);
 
-	if (mail_cache_field_can_add(mail->trans->cache_trans,
-				     mail->data.seq, cache_field_envelope)) {
+	if (mail_cache_field_can_add(_mail->transaction->cache_trans,
+				     _mail->seq, cache_field_envelope)) {
 		index_mail_cache_add_idx(mail, cache_field_envelope,
 					 str_data(str), str_len(str));
 	}
@@ -596,6 +596,7 @@
 index_mail_get_raw_headers(struct index_mail *mail, const char *field,
 			   const char *const **value_r)
 {
+	struct mail *_mail = &mail->mail.mail;
 	const char *headers[2], *value;
 	struct mailbox_header_lookup_ctx *headers_ctx;
 	unsigned char *data;
@@ -607,12 +608,12 @@
 
 	i_assert(field != NULL);
 
-	field_idx = get_header_field_idx(mail->mail.mail.box, field,
+	field_idx = get_header_field_idx(_mail->box, field,
 					 MAIL_CACHE_DECISION_TEMP);
 
 	dest = str_new(mail->data_pool, 128);
-	if (mail_cache_lookup_headers(mail->trans->cache_view, dest,
-				      mail->data.seq, &field_idx, 1) <= 0) {
+	if (mail_cache_lookup_headers(_mail->transaction->cache_view, dest,
+				      _mail->seq, &field_idx, 1) <= 0) {
 		/* not in cache / error - first see if it's already parsed */
 		p_free(mail->data_pool, dest);
 
@@ -620,8 +621,8 @@
 		    index_mail_header_is_parsed(mail, field_idx) < 0) {
 			/* parse */
 			headers[0] = field; headers[1] = NULL;
-			headers_ctx = mailbox_header_lookup_init(
-						mail->mail.mail.box, headers);
+			headers_ctx = mailbox_header_lookup_init(_mail->box,
+								 headers);
 			ret = index_mail_parse_headers(mail, headers_ctx);
 			mailbox_header_lookup_unref(&headers_ctx);
 			if (ret < 0)
@@ -818,8 +819,8 @@
 	}
 
 	dest = str_new(mail->data_pool, 256);
-	if (mail_cache_lookup_headers(mail->trans->cache_view, dest,
-				      mail->data.seq, headers->idx,
+	if (mail_cache_lookup_headers(_mail->transaction->cache_view, dest,
+				      _mail->seq, headers->idx,
 				      headers->count) > 0) {
 		mail->mail.stats_cache_hit_count++;
 		if (mail->data.filter_stream != NULL)
@@ -833,7 +834,7 @@
 	/* not in cache / error */
 	p_free(mail->data_pool, dest);
 
-	if (mail_get_stream(&mail->mail.mail, NULL, NULL, &input) < 0)
+	if (mail_get_stream(_mail, NULL, NULL, &input) < 0)
 		return -1;
 
 	if (mail->data.filter_stream != NULL)
--- a/src/lib-storage/index/index-mail.c	Sun Dec 05 21:11:03 2010 +0000
+++ b/src/lib-storage/index/index-mail.c	Sun Dec 05 21:39:09 2010 +0000
@@ -45,8 +45,8 @@
 {
 	int ret;
 
-	ret = mail_cache_lookup_field(mail->trans->cache_view, buf,
-				      mail->data.seq, field_idx);
+	ret = mail_cache_lookup_field(mail->mail.mail.transaction->cache_view,
+				      buf, mail->data.seq, field_idx);
 	if (ret > 0)
 		mail->mail.stats_cache_hit_count++;
 	return ret;
@@ -54,7 +54,7 @@
 
 static struct message_part *get_unserialized_parts(struct index_mail *mail)
 {
-	unsigned int field_idx =
+	const unsigned int field_idx =
 		mail->ibox->cache_fields[MAIL_CACHE_MESSAGE_PARTS].idx;
 	struct message_part *parts;
 	buffer_t *part_buf;
@@ -102,7 +102,7 @@
 				       enum index_cache_field field,
 				       void *data, size_t data_size)
 {
-	unsigned int field_idx = mail->ibox->cache_fields[field].idx;
+	const unsigned int field_idx = mail->ibox->cache_fields[field].idx;
 	buffer_t buf;
 	int ret;
 
@@ -421,21 +421,21 @@
 void index_mail_cache_add_idx(struct index_mail *mail, unsigned int field_idx,
 			      const void *data, size_t data_size)
 {
-	const struct mail_storage_settings *set =
-		mail->mail.mail.box->storage->set;
+	struct mail *_mail = &mail->mail.mail;
+	const struct mail_storage_settings *set = _mail->box->storage->set;
 	const struct mail_index_header *hdr;
 
 	if (set->mail_cache_min_mail_count > 0) {
 		/* First check if we've configured caching not to be used with
 		   low enough message count. */
-		hdr = mail_index_get_header(mail->mail.mail.box->view);
+		hdr = mail_index_get_header(_mail->box->view);
 		if (hdr->messages_count < set->mail_cache_min_mail_count)
 			return;
 	}
 
 	if (!mail->data.no_caching &&
 	    mail->data.dont_cache_field_idx != field_idx) {
-		mail_cache_add(mail->trans->cache_trans, mail->data.seq,
+		mail_cache_add(_mail->transaction->cache_trans, _mail->seq,
 			       field_idx, data, data_size);
 	}
 }
@@ -449,29 +449,36 @@
 
 static bool want_plain_bodystructure_cached(struct index_mail *mail)
 {
+	const unsigned int cache_field_body =
+		mail->ibox->cache_fields[MAIL_CACHE_IMAP_BODY].idx;
+	const unsigned int cache_field_bodystructure =
+		mail->ibox->cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
+	struct mail *_mail = &mail->mail.mail;
+
 	if ((mail->wanted_fields & (MAIL_FETCH_IMAP_BODY |
 				    MAIL_FETCH_IMAP_BODYSTRUCTURE)) != 0)
 		return TRUE;
 
-	if (mail_cache_field_want_add(mail->trans->cache_trans, mail->data.seq,
-		mail->ibox->cache_fields[MAIL_CACHE_IMAP_BODY].idx))
+	if (mail_cache_field_want_add(_mail->transaction->cache_trans,
+				      _mail->seq, cache_field_body))
 		return TRUE;
-	if (mail_cache_field_want_add(mail->trans->cache_trans, mail->data.seq,
-		mail->ibox->cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx))
+	if (mail_cache_field_want_add(_mail->transaction->cache_trans,
+				      _mail->seq, cache_field_bodystructure))
 		return TRUE;
 	return FALSE;
 }
 
 static void index_mail_body_parsed_cache_flags(struct index_mail *mail)
 {
+	struct mail *_mail = &mail->mail.mail;
 	struct index_mail_data *data = &mail->data;
 	unsigned int cache_flags_idx;
 	uint32_t cache_flags = data->cache_flags;
 	bool want_cached;
 
 	cache_flags_idx = mail->ibox->cache_fields[MAIL_CACHE_FLAGS].idx;
-	want_cached = mail_cache_field_want_add(mail->trans->cache_trans,
-						data->seq, cache_flags_idx);
+	want_cached = mail_cache_field_want_add(_mail->transaction->cache_trans,
+						_mail->seq, cache_flags_idx);
 
 	if (data->parsed_bodystructure &&
 	    imap_bodystructure_is_plain_7bit(data->parts) &&
@@ -490,12 +497,12 @@
 			 MAIL_CACHE_FLAG_HAS_NULS |
 			 MAIL_CACHE_FLAG_HAS_NO_NULS);
 	if ((data->parts->flags & MESSAGE_PART_FLAG_HAS_NULS) != 0) {
-		mail->mail.mail.has_nuls = TRUE;
-		mail->mail.mail.has_no_nuls = FALSE;
+		_mail->has_nuls = TRUE;
+		_mail->has_no_nuls = FALSE;
 		cache_flags |= MAIL_CACHE_FLAG_HAS_NULS;
 	} else {
-		mail->mail.mail.has_nuls = FALSE;
-		mail->mail.mail.has_no_nuls = TRUE;
+		_mail->has_nuls = FALSE;
+		_mail->has_no_nuls = TRUE;
 		cache_flags |= MAIL_CACHE_FLAG_HAS_NO_NULS;
 	}
 
@@ -513,20 +520,21 @@
 
 static void index_mail_body_parsed_cache_message_parts(struct index_mail *mail)
 {
+	struct mail *_mail = &mail->mail.mail;
 	struct index_mail_data *data = &mail->data;
-	unsigned int cache_field =
+	const unsigned int cache_field =
 		mail->ibox->cache_fields[MAIL_CACHE_MESSAGE_PARTS].idx;
 	enum mail_cache_decision_type decision;
 	buffer_t *buffer;
 
 	if (data->messageparts_saved_to_cache ||
-	    mail_cache_field_exists(mail->trans->cache_view, mail->data.seq,
+	    mail_cache_field_exists(_mail->transaction->cache_view, _mail->seq,
 				    cache_field) != 0) {
 		/* already cached */
 		return;
 	}
 
-	decision = mail_cache_field_get_decision(mail->mail.mail.box->cache,
+	decision = mail_cache_field_get_decision(_mail->box->cache,
 						 cache_field);
 	if (decision == (MAIL_CACHE_DECISION_NO | MAIL_CACHE_DECISION_FORCED)) {
 		/* we never want it cached */
@@ -554,12 +562,13 @@
 index_mail_body_parsed_cache_bodystructure(struct index_mail *mail,
 					   enum index_cache_field field)
 {
+	struct mail *_mail = &mail->mail.mail;
 	struct index_mail_data *data = &mail->data;
-	unsigned int cache_field_parts =
+	const unsigned int cache_field_parts =
 		mail->ibox->cache_fields[MAIL_CACHE_MESSAGE_PARTS].idx;
-	unsigned int cache_field_body =
+	const unsigned int cache_field_body =
 		mail->ibox->cache_fields[MAIL_CACHE_IMAP_BODY].idx;
-	unsigned int cache_field_bodystructure =
+	const unsigned int cache_field_bodystructure =
 		mail->ibox->cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
 	enum mail_cache_decision_type dec;
 	string_t *str;
@@ -569,8 +578,8 @@
 
 	if ((data->cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) != 0) {
 		if (data->messageparts_saved_to_cache ||
-		    mail_cache_field_exists(mail->trans->cache_view, data->seq,
-					    cache_field_parts) > 0) {
+		    mail_cache_field_exists(_mail->transaction->cache_view,
+					    _mail->seq, cache_field_parts) > 0) {
 			/* cached it as flag + message_parts */
 			plain_bodystructure = TRUE;
 		}
@@ -587,12 +596,12 @@
 	else if (field == MAIL_CACHE_IMAP_BODYSTRUCTURE ||
 		 (mail->wanted_fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) != 0) {
 		cache_bodystructure =
-			mail_cache_field_can_add(mail->trans->cache_trans,
-				data->seq, cache_field_bodystructure);
+			mail_cache_field_can_add(_mail->transaction->cache_trans,
+				_mail->seq, cache_field_bodystructure);
 	} else {
 		cache_bodystructure =
-			mail_cache_field_want_add(mail->trans->cache_trans,
-				data->seq, cache_field_bodystructure);
+			mail_cache_field_want_add(_mail->transaction->cache_trans,
+				_mail->seq, cache_field_bodystructure);
 	}
 	if (cache_bodystructure) {
 		str = str_new(mail->data_pool, 128);
@@ -604,13 +613,13 @@
 		bodystructure_cached = TRUE;
 	} else {
 		bodystructure_cached =
-			mail_cache_field_exists(mail->trans->cache_view,
-				data->seq, cache_field_bodystructure) > 0;
+			mail_cache_field_exists(_mail->transaction->cache_view,
+				_mail->seq, cache_field_bodystructure) > 0;
 	}
 
 	/* normally don't cache both BODY and BODYSTRUCTURE, but do it
 	   if BODY is forced to be cached */
-	dec = mail_cache_field_get_decision(mail->mail.mail.box->cache,
+	dec = mail_cache_field_get_decision(_mail->box->cache,
 					    cache_field_body);
 	if (plain_bodystructure ||
 	    (bodystructure_cached &&
@@ -618,12 +627,12 @@
 		cache_body = FALSE;
 	else if (field == MAIL_CACHE_IMAP_BODY) {
 		cache_body =
-			mail_cache_field_can_add(mail->trans->cache_trans,
-				data->seq, cache_field_body);
+			mail_cache_field_can_add(_mail->transaction->cache_trans,
+				_mail->seq, cache_field_body);
 	} else {
 		cache_body =
-			mail_cache_field_want_add(mail->trans->cache_trans,
-				data->seq, cache_field_body);
+			mail_cache_field_want_add(_mail->transaction->cache_trans,
+				_mail->seq, cache_field_body);
 	}
 
 	if (cache_body) {
@@ -639,6 +648,7 @@
 static bool
 index_mail_want_cache(struct index_mail *mail, enum index_cache_field field)
 {
+	struct mail *_mail = &mail->mail.mail;
 	enum mail_fetch_field fetch_field;
 	unsigned int cache_field;
 
@@ -667,11 +677,11 @@
 
 	cache_field = mail->ibox->cache_fields[field].idx;
 	if ((mail->data.cache_fetch_fields & fetch_field) != 0) {
-		return mail_cache_field_can_add(mail->trans->cache_trans,
-						mail->data.seq, cache_field);
+		return mail_cache_field_can_add(_mail->transaction->cache_trans,
+						_mail->seq, cache_field);
 	} else {
-		return mail_cache_field_want_add(mail->trans->cache_trans,
-						 mail->data.seq, cache_field);
+		return mail_cache_field_want_add(_mail->transaction->cache_trans,
+						 _mail->seq, cache_field);
 	}
 }
 
@@ -804,7 +814,8 @@
 
 enum index_mail_access_part index_mail_get_access_part(struct index_mail *mail)
 {
-	struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
+	struct mail *_mail = &mail->mail.mail;
+	const struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
 
 	if ((mail->data.access_part & (READ_HDR | PARSE_HDR)) != 0 &&
 	    (mail->data.access_part & (READ_BODY | PARSE_BODY)) != 0)
@@ -812,12 +823,11 @@
 
 	/* lazy virtual size access check */
 	if ((mail->wanted_fields & MAIL_FETCH_VIRTUAL_SIZE) != 0) {
-		unsigned int cache_field =
+		const unsigned int cache_field =
 			cache_fields[MAIL_CACHE_VIRTUAL_FULL_SIZE].idx;
 
-		if (mail_cache_field_exists(mail->trans->cache_view,
-					    mail->mail.mail.seq,
-					    cache_field) <= 0)
+		if (mail_cache_field_exists(_mail->transaction->cache_view,
+					    _mail->seq, cache_field) <= 0)
 			mail->data.access_part |= READ_HDR | READ_BODY;
 	}
 	return mail->data.access_part;
@@ -979,14 +989,14 @@
 {
 	struct index_mail *mail = (struct index_mail *)_mail;
 	struct index_mail_data *data = &mail->data;
-	struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
+	const struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
 	string_t *str;
 
 	switch (field) {
 	case MAIL_FETCH_IMAP_BODY: {
-		unsigned int body_cache_field =
+		const unsigned int body_cache_field =
                         cache_fields[MAIL_CACHE_IMAP_BODY].idx;
-		unsigned int bodystructure_cache_field =
+		const unsigned int bodystructure_cache_field =
                         cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
 
 		if (data->body != NULL) {
@@ -1036,7 +1046,7 @@
 		return 0;
 	}
 	case MAIL_FETCH_IMAP_BODYSTRUCTURE: {
-		unsigned int bodystructure_cache_field =
+		const unsigned int bodystructure_cache_field =
                         cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
 
 		if (data->bodystructure != NULL) {
@@ -1109,12 +1119,10 @@
 }
 
 void index_mail_init(struct index_mail *mail,
-		     struct mailbox_transaction_context *_t,
+		     struct mailbox_transaction_context *t,
 		     enum mail_fetch_field wanted_fields,
 		     struct mailbox_header_lookup_ctx *_wanted_headers)
 {
-	struct index_transaction_context *t =
-		(struct index_transaction_context *)_t;
 	struct index_header_lookup_ctx *wanted_headers =
 		(struct index_header_lookup_ctx *)_wanted_headers;
 	const struct mail_index_header *hdr;
@@ -1122,19 +1130,18 @@
 	array_create(&mail->mail.module_contexts, mail->mail.pool,
 		     sizeof(void *), 5);
 
-	mail->mail.v = *_t->box->mail_vfuncs;
-	mail->mail.mail.box = _t->box;
-	mail->mail.mail.transaction = &t->mailbox_ctx;
+	mail->mail.v = *t->box->mail_vfuncs;
+	mail->mail.mail.box = t->box;
+	mail->mail.mail.transaction = t;
 	mail->mail.wanted_fields = wanted_fields;
 	mail->mail.wanted_headers = _wanted_headers;
 
-	hdr = mail_index_get_header(_t->box->view);
+	hdr = mail_index_get_header(t->box->view);
 	mail->uid_validity = hdr->uid_validity;
 
 	t->mail_ref_count++;
 	mail->data_pool = pool_alloconly_create("index_mail", 16384);
-	mail->ibox = INDEX_STORAGE_CONTEXT(_t->box);
-	mail->trans = t;
+	mail->ibox = INDEX_STORAGE_CONTEXT(t->box);
 	mail->wanted_fields = wanted_fields;
 	if (wanted_headers != NULL) {
 		mail->wanted_headers = wanted_headers;
@@ -1198,7 +1205,8 @@
 
 static void check_envelope(struct index_mail *mail)
 {
-	unsigned int cache_field_envelope =
+	struct mail *_mail = &mail->mail.mail;
+	const unsigned int cache_field_envelope =
 		mail->ibox->cache_fields[MAIL_CACHE_IMAP_ENVELOPE].idx;
 	unsigned int cache_field_hdr;
 
@@ -1208,20 +1216,18 @@
 	}
 
 	/* if "imap.envelope" is cached, that's all we need */
-	if (mail_cache_field_exists(mail->trans->cache_view,
-				    mail->mail.mail.seq,
-				    cache_field_envelope) > 0)
+	if (mail_cache_field_exists(_mail->transaction->cache_view,
+				    _mail->seq, cache_field_envelope) > 0)
 		return;
 
 	/* don't waste time doing full checks for all required
 	   headers. assume that if we have "hdr.message-id" cached,
 	   we don't need to parse the header. */
-	cache_field_hdr = mail_cache_register_lookup(mail->mail.mail.box->cache,
+	cache_field_hdr = mail_cache_register_lookup(_mail->box->cache,
 						     "hdr.message-id");
 	if (cache_field_hdr == (unsigned int)-1 ||
-	    mail_cache_field_exists(mail->trans->cache_view,
-				    mail->mail.mail.seq,
-				    cache_field_hdr) <= 0)
+	    mail_cache_field_exists(_mail->transaction->cache_view,
+				    _mail->seq, cache_field_hdr) <= 0)
 		mail->data.access_part |= PARSE_HDR;
 	mail->data.save_envelope = TRUE;
 }
@@ -1230,8 +1236,8 @@
 {
 	struct index_mail *mail = (struct index_mail *)_mail;
 	struct index_mail_data *data = &mail->data;
-	struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
-	struct mail_cache_view *cache_view = mail->trans->cache_view;
+	const struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
+	struct mail_cache_view *cache_view = _mail->transaction->cache_view;
 	const struct mail_index_header *hdr;
 	struct istream *input;
 
@@ -1266,7 +1272,7 @@
 	/* see if wanted_fields can tell us if we need to read/parse
 	   header/body */
 	if ((mail->wanted_fields & MAIL_FETCH_MESSAGE_PARTS) != 0) {
-		unsigned int cache_field =
+		const unsigned int cache_field =
 			cache_fields[MAIL_CACHE_MESSAGE_PARTS].idx;
 
 		if (mail_cache_field_exists(cache_view, seq,
@@ -1282,9 +1288,9 @@
 	if ((mail->wanted_fields & MAIL_FETCH_IMAP_BODY) != 0 &&
 	    (data->cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) == 0) {
 		/* we need either imap.body or imap.bodystructure */
-		unsigned int cache_field1 =
+		const unsigned int cache_field1 =
 			cache_fields[MAIL_CACHE_IMAP_BODY].idx;
-		unsigned int cache_field2 =
+		const unsigned int cache_field2 =
 			cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
 
 		if (mail_cache_field_exists(cache_view,
@@ -1299,7 +1305,7 @@
 
 	if ((mail->wanted_fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) != 0 &&
 	    (data->cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) == 0) {
-		unsigned int cache_field =
+		const unsigned int cache_field =
 			cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
 
                 if (mail_cache_field_exists(cache_view, seq,
@@ -1311,7 +1317,7 @@
 	}
 
 	if ((mail->wanted_fields & MAIL_FETCH_DATE) != 0) {
-		unsigned int cache_field =
+		const unsigned int cache_field =
 			cache_fields[MAIL_CACHE_SENT_DATE].idx;
 
 		if (mail_cache_field_exists(cache_view, seq,
@@ -1369,8 +1375,8 @@
 
 	mail->mail.v.close(_mail);
 
-	i_assert(mail->trans->mail_ref_count > 0);
-	mail->trans->mail_ref_count--;
+	i_assert(_mail->transaction->mail_ref_count > 0);
+	_mail->transaction->mail_ref_count--;
 
 	if (mail->header_data != NULL)
 		buffer_free(&mail->header_data);
@@ -1543,7 +1549,7 @@
 	}
 
 	/* make sure we don't cache invalid values */
-	mail_cache_transaction_reset(imail->trans->cache_trans);
+	mail_cache_transaction_reset(mail->transaction->cache_trans);
 	imail->data.no_caching = TRUE;
 	imail->data.forced_no_caching = TRUE;
 	mail_cache_set_corrupted(mail->box->cache,
--- a/src/lib-storage/index/index-mail.h	Sun Dec 05 21:11:03 2010 +0000
+++ b/src/lib-storage/index/index-mail.h	Sun Dec 05 21:39:09 2010 +0000
@@ -120,7 +120,6 @@
 	struct index_mailbox_context *ibox;
 
 	pool_t data_pool;
-	struct index_transaction_context *trans;
 	uint32_t uid_validity;
 
 	enum mail_fetch_field wanted_fields;
--- a/src/lib-storage/index/index-storage.c	Sun Dec 05 21:11:03 2010 +0000
+++ b/src/lib-storage/index/index-storage.c	Sun Dec 05 21:39:09 2010 +0000
@@ -606,10 +606,6 @@
 		      uint32_t dest_seq, const char *name, buffer_t *buf)
 {
 	struct mailbox_transaction_context *dest_trans = ctx->transaction;
-	struct index_transaction_context *dest_itrans =
-		(struct index_transaction_context *)dest_trans;
-	struct index_transaction_context *src_itrans =
-		(struct index_transaction_context *)src_mail->transaction;
 	const struct mail_cache_field *dest_field;
 	unsigned int src_field_idx, dest_field_idx;
 
@@ -630,9 +626,9 @@
 	}
 
 	buffer_set_used_size(buf, 0);
-	if (mail_cache_lookup_field(src_itrans->cache_view, buf,
+	if (mail_cache_lookup_field(src_mail->transaction->cache_view, buf,
 				    src_mail->seq, src_field_idx) > 0) {
-		mail_cache_add(dest_itrans->cache_trans, dest_seq,
+		mail_cache_add(dest_trans->cache_trans, dest_seq,
 			       dest_field_idx, buf->data, buf->used);
 	}
 }
--- a/src/lib-storage/index/index-storage.h	Sun Dec 05 21:11:03 2010 +0000
+++ b/src/lib-storage/index/index-storage.h	Sun Dec 05 21:39:09 2010 +0000
@@ -16,17 +16,6 @@
 	MAILBOX_LOCK_NOTIFY_MAILBOX_OVERRIDE
 };
 
-struct index_transaction_context {
-	struct mailbox_transaction_context mailbox_ctx;
-	union mail_index_transaction_module_context module_ctx;
-
-	struct mail_index_transaction_vfuncs super;
-	int mail_ref_count;
-
-	struct mail_cache_view *cache_view;
-	struct mail_cache_transaction_ctx *cache_trans;
-};
-
 struct index_vsize_header {
 	uint64_t vsize;
 	uint32_t highest_uid;
@@ -159,7 +148,7 @@
 struct mailbox_transaction_context *
 index_transaction_begin(struct mailbox *box,
 			enum mailbox_transaction_flags flags);
-void index_transaction_init(struct index_transaction_context *it,
+void index_transaction_init(struct mailbox_transaction_context *t,
 			    struct mailbox *box,
 			    enum mailbox_transaction_flags flags);
 int index_transaction_commit(struct mailbox_transaction_context *t,
--- a/src/lib-storage/index/index-transaction.c	Sun Dec 05 21:11:03 2010 +0000
+++ b/src/lib-storage/index/index-transaction.c	Sun Dec 05 21:39:09 2010 +0000
@@ -5,11 +5,11 @@
 #include "index-storage.h"
 #include "index-mail.h"
 
-static void index_transaction_free(struct index_transaction_context *t)
+static void index_transaction_free(struct mailbox_transaction_context *t)
 {
 	mail_cache_view_close(t->cache_view);
-	mail_index_view_close(&t->mailbox_ctx.view);
-	array_free(&t->mailbox_ctx.module_contexts);
+	mail_index_view_close(&t->view);
+	array_free(&t->module_contexts);
 	i_free(t);
 }
 
@@ -17,9 +17,8 @@
 index_transaction_index_commit(struct mail_index_transaction *index_trans,
 			       struct mail_index_transaction_commit_result *result_r)
 {
-	struct index_transaction_context *it =
+	struct mailbox_transaction_context *t =
 		MAIL_STORAGE_CONTEXT(index_trans);
-	struct mailbox_transaction_context *t = &it->mailbox_ctx;
 	struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(t->box);
 	int ret = 0;
 
@@ -30,11 +29,11 @@
 		}
 	}
 
-	i_assert(it->mail_ref_count == 0);
+	i_assert(t->mail_ref_count == 0);
 	if (ret < 0)
-		it->super.rollback(index_trans);
+		t->super.rollback(index_trans);
 	else {
-		if (it->super.commit(index_trans, result_r) < 0) {
+		if (t->super.commit(index_trans, result_r) < 0) {
 			mail_storage_set_index_error(t->box);
 			ret = -1;
 		}
@@ -43,29 +42,30 @@
 	if (t->save_ctx != NULL)
 		ibox->save_commit_post(t->save_ctx, result_r);
 
-	index_transaction_free(it);
+	index_transaction_free(t);
 	return ret;
 }
 
-static void index_transaction_index_rollback(struct mail_index_transaction *t)
+static void
+index_transaction_index_rollback(struct mail_index_transaction *index_trans)
 {
-	struct index_transaction_context *it = MAIL_STORAGE_CONTEXT(t);
+	struct mailbox_transaction_context *t =
+		MAIL_STORAGE_CONTEXT(index_trans);
 	struct index_mailbox_context *ibox =
-		INDEX_STORAGE_CONTEXT(it->mailbox_ctx.box);
+		INDEX_STORAGE_CONTEXT(t->box);
 
-	if (it->mailbox_ctx.save_ctx != NULL)
-		ibox->save_rollback(it->mailbox_ctx.save_ctx);
+	if (t->save_ctx != NULL)
+		ibox->save_rollback(t->save_ctx);
 
-	i_assert(it->mail_ref_count == 0);
-	it->super.rollback(t);
-	index_transaction_free(it);
+	i_assert(t->mail_ref_count == 0);
+	t->super.rollback(index_trans);
+	index_transaction_free(t);
 }
 
-void index_transaction_init(struct index_transaction_context *it,
+void index_transaction_init(struct mailbox_transaction_context *t,
 			    struct mailbox *box,
 			    enum mailbox_transaction_flags flags)
 {
-	struct mailbox_transaction_context *t = &it->mailbox_ctx;
 	enum mail_index_transaction_flags trans_flags;
 
 	i_assert(box->opened);
@@ -85,26 +85,26 @@
 	array_create(&t->module_contexts, default_pool,
 		     sizeof(void *), 5);
 
-	it->cache_view = mail_cache_view_open(box->cache, t->view);
-	it->cache_trans = mail_cache_get_transaction(it->cache_view, t->itrans);
+	t->cache_view = mail_cache_view_open(box->cache, t->view);
+	t->cache_trans = mail_cache_get_transaction(t->cache_view, t->itrans);
 
 	/* set up after mail_cache_get_transaction(), so that we'll still
 	   have the cache_trans available in _index_commit() */
-	it->super = t->itrans->v;
+	t->super = t->itrans->v;
 	t->itrans->v.commit = index_transaction_index_commit;
 	t->itrans->v.rollback = index_transaction_index_rollback;
-	MODULE_CONTEXT_SET(t->itrans, mail_storage_mail_index_module, it);
+	MODULE_CONTEXT_SET(t->itrans, mail_storage_mail_index_module, t);
 }
 
 struct mailbox_transaction_context *
 index_transaction_begin(struct mailbox *box,
 			enum mailbox_transaction_flags flags)
 {
-	struct index_transaction_context *it;
+	struct mailbox_transaction_context *t;
 
-	it = i_new(struct index_transaction_context, 1);
-	index_transaction_init(it, box, flags);
-	return &it->mailbox_ctx;
+	t = i_new(struct mailbox_transaction_context, 1);
+	index_transaction_init(t, box, flags);
+	return t;
 }
 
 int index_transaction_commit(struct mailbox_transaction_context *t,
--- a/src/lib-storage/index/maildir/maildir-save.c	Sun Dec 05 21:11:03 2010 +0000
+++ b/src/lib-storage/index/maildir/maildir-save.c	Sun Dec 05 21:39:09 2010 +0000
@@ -491,14 +491,12 @@
 
 static void maildir_save_remove_last_filename(struct maildir_save_context *ctx)
 {
-	struct index_transaction_context *t =
-		(struct index_transaction_context *)ctx->ctx.transaction;
 	struct maildir_filename **fm;
 
 	mail_index_expunge(ctx->trans, ctx->seq);
 	/* currently we can't just drop pending cache updates for this one
 	   specific record, so we'll reset the whole cache transaction. */
-	mail_cache_transaction_reset(t->cache_trans);
+	mail_cache_transaction_reset(ctx->ctx.transaction->cache_trans);
 	ctx->seq--;
 
 	for (fm = &ctx->files; (*fm)->next != NULL; fm = &(*fm)->next) ;
@@ -764,8 +762,6 @@
 static void
 maildir_save_rollback_index_changes(struct maildir_save_context *ctx)
 {
-	struct index_transaction_context *t =
-		(struct index_transaction_context *)ctx->ctx.transaction;
 	uint32_t seq;
 
 	if (ctx->seq == 0)
@@ -774,7 +770,7 @@
 	for (seq = ctx->seq; seq >= ctx->first_seq; seq--)
 		mail_index_expunge(ctx->trans, seq);
 
-	mail_cache_transaction_reset(t->cache_trans);
+	mail_cache_transaction_reset(ctx->ctx.transaction->cache_trans);
 }
 
 static bool maildir_filename_has_conflict(struct maildir_filename *mf,
--- a/src/lib-storage/index/mbox/mbox-mail.c	Sun Dec 05 21:11:03 2010 +0000
+++ b/src/lib-storage/index/mbox/mbox-mail.c	Sun Dec 05 21:39:09 2010 +0000
@@ -33,7 +33,7 @@
 static int mbox_mail_seek(struct index_mail *mail)
 {
 	struct mbox_transaction_context *t =
-		(struct mbox_transaction_context *)mail->trans;
+		(struct mbox_transaction_context *)mail->mail.mail.transaction;
 	struct mail *_mail = &mail->mail.mail;
 	struct mbox_mailbox *mbox = (struct mbox_mailbox *)_mail->box;
 	enum mbox_sync_flags sync_flags = 0;
--- a/src/lib-storage/index/mbox/mbox-save.c	Sun Dec 05 21:11:03 2010 +0000
+++ b/src/lib-storage/index/mbox/mbox-save.c	Sun Dec 05 21:39:09 2010 +0000
@@ -255,7 +255,7 @@
 mbox_save_init_file(struct mbox_save_context *ctx,
 		    struct mbox_transaction_context *t, bool want_mail)
 {
-	struct mailbox_transaction_context *_t = &t->ictx.mailbox_ctx;
+	struct mailbox_transaction_context *_t = &t->t;
 	struct mbox_mailbox *mbox = ctx->mbox;
 	struct mail_storage *storage = &mbox->storage->storage;
 	bool empty = FALSE;
--- a/src/lib-storage/index/mbox/mbox-storage.c	Sun Dec 05 21:11:03 2010 +0000
+++ b/src/lib-storage/index/mbox/mbox-storage.c	Sun Dec 05 21:39:09 2010 +0000
@@ -641,8 +641,8 @@
 	struct mbox_transaction_context *mt;
 
 	mt = i_new(struct mbox_transaction_context, 1);
-	index_transaction_init(&mt->ictx, box, flags);
-	return &mt->ictx.mailbox_ctx;
+	index_transaction_init(&mt->t, box, flags);
+	return &mt->t;
 }
 
 static void mbox_transaction_unlock(struct mailbox *box, unsigned int lock_id)
--- a/src/lib-storage/index/mbox/mbox-storage.h	Sun Dec 05 21:11:03 2010 +0000
+++ b/src/lib-storage/index/mbox/mbox-storage.h	Sun Dec 05 21:39:09 2010 +0000
@@ -60,7 +60,9 @@
 };
 
 struct mbox_transaction_context {
-	struct index_transaction_context ictx;
+	struct mailbox_transaction_context t;
+	union mail_index_transaction_module_context module_ctx;
+
 	unsigned int mbox_lock_id;
 };
 
--- a/src/lib-storage/mail-storage-private.h	Sun Dec 05 21:11:03 2010 +0000
+++ b/src/lib-storage/mail-storage-private.h	Sun Dec 05 21:39:09 2010 +0000
@@ -383,10 +383,17 @@
 	struct mailbox *box;
 	enum mailbox_transaction_flags flags;
 
+	union mail_index_transaction_module_context module_ctx;
+	struct mail_index_transaction_vfuncs super;
+	int mail_ref_count;
+
 	struct mail_index_transaction *itrans;
 	/* view contains all changes done within this transaction */
 	struct mail_index_view *view;
 
+	struct mail_cache_view *cache_view;
+	struct mail_cache_transaction_ctx *cache_trans;
+
 	struct mail_transaction_commit_changes *changes;
 	ARRAY_DEFINE(module_contexts,
 		     union mailbox_transaction_module_context *);
--- a/src/plugins/virtual/virtual-mail.c	Sun Dec 05 21:11:03 2010 +0000
+++ b/src/plugins/virtual/virtual-mail.c	Sun Dec 05 21:39:09 2010 +0000
@@ -42,7 +42,6 @@
 	vmail->imail.data_pool =
 		pool_alloconly_create("virtual index_mail", 512);
 	vmail->imail.ibox = INDEX_STORAGE_CONTEXT(t->box);
-	vmail->imail.trans = (struct index_transaction_context *)t;
 
 	vmail->wanted_fields = wanted_fields;
 	if (wanted_headers != NULL) {
--- a/src/plugins/virtual/virtual-save.c	Sun Dec 05 21:11:03 2010 +0000
+++ b/src/plugins/virtual/virtual-save.c	Sun Dec 05 21:39:09 2010 +0000
@@ -25,7 +25,7 @@
 		return _t->save_ctx;
 
 	ctx = i_new(struct virtual_save_context, 1);
-	ctx->ctx.transaction = &t->ictx.mailbox_ctx;
+	ctx->ctx.transaction = &t->t;
 
 	if (mbox->save_bbox != NULL) {
 		backend_trans =
--- a/src/plugins/virtual/virtual-transaction.c	Sun Dec 05 21:11:03 2010 +0000
+++ b/src/plugins/virtual/virtual-transaction.c	Sun Dec 05 21:39:09 2010 +0000
@@ -35,8 +35,8 @@
 	vt = i_new(struct virtual_transaction_context, 1);
 	i_array_init(&vt->backend_transactions,
 		     array_count(&mbox->backend_boxes));
-	index_transaction_init(&vt->ictx, box, flags);
-	return &vt->ictx.mailbox_ctx;
+	index_transaction_init(&vt->t, box, flags);
+	return &vt->t;
 }
 
 int virtual_transaction_commit(struct mailbox_transaction_context *t,
--- a/src/plugins/virtual/virtual-transaction.h	Sun Dec 05 21:11:03 2010 +0000
+++ b/src/plugins/virtual/virtual-transaction.h	Sun Dec 05 21:39:09 2010 +0000
@@ -4,7 +4,7 @@
 #include "index-storage.h"
 
 struct virtual_transaction_context {
-	struct index_transaction_context ictx;
+	struct mailbox_transaction_context t;
 
 	ARRAY_DEFINE(backend_transactions,
 		     struct mailbox_transaction_context *);