dovecot-2.2: lib-index: mail_cache_map() API cleanup

dovecot at dovecot.org dovecot at dovecot.org
Mon Oct 29 17:55:54 EET 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/022d0d21e56d
changeset: 15311:022d0d21e56d
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Oct 18 05:10:29 2012 +0300
description:
lib-index: mail_cache_map() API cleanup

diffstat:

 src/lib-index/mail-cache-compress.c    |   3 +-
 src/lib-index/mail-cache-fields.c      |  46 +++++++++++++++++----------------
 src/lib-index/mail-cache-lookup.c      |  10 ++++--
 src/lib-index/mail-cache-private.h     |   3 +-
 src/lib-index/mail-cache-transaction.c |  17 +++++++-----
 src/lib-index/mail-cache.c             |  36 ++++++++++++++++++++-----
 6 files changed, 72 insertions(+), 43 deletions(-)

diffs (truncated from 337 to 300 lines):

diff -r 41aac09497ee -r 022d0d21e56d src/lib-index/mail-cache-compress.c
--- a/src/lib-index/mail-cache-compress.c	Tue Oct 16 03:34:51 2012 +0300
+++ b/src/lib-index/mail-cache-compress.c	Thu Oct 18 05:10:29 2012 +0300
@@ -353,6 +353,7 @@
 	uint32_t file_seq, old_offset;
 	ARRAY_TYPE(uint32_t) ext_offsets;
 	const uint32_t *offsets;
+	const void *data;
 	unsigned int i, count;
 	int fd, ret;
 
@@ -440,7 +441,7 @@
 	if (cache->file_cache != NULL)
 		file_cache_set_fd(cache->file_cache, cache->fd);
 
-	if (mail_cache_map(cache, 0, 0) < 0)
+	if (mail_cache_map(cache, 0, 0, &data) < 0)
 		return -1;
 	if (mail_cache_header_fields_read(cache) < 0)
 		return -1;
diff -r 41aac09497ee -r 022d0d21e56d src/lib-index/mail-cache-fields.c
--- a/src/lib-index/mail-cache-fields.c	Tue Oct 16 03:34:51 2012 +0300
+++ b/src/lib-index/mail-cache-fields.c	Thu Oct 18 05:10:29 2012 +0300
@@ -198,11 +198,14 @@
 	return list;
 }
 
-static int mail_cache_header_fields_get_offset(struct mail_cache *cache,
-					       uint32_t *offset_r, bool map)
+static int
+mail_cache_header_fields_get_offset(struct mail_cache *cache,
+				    uint32_t *offset_r,
+				    const struct mail_cache_header_fields **field_hdr_r)
 {
 	const struct mail_cache_header_fields *field_hdr;
 	struct mail_cache_header_fields tmp_field_hdr;
+	const void *data;
 	uint32_t offset = 0, next_offset;
 	unsigned int next_count = 0;
 	bool invalidate = FALSE;
@@ -210,6 +213,8 @@
 
 	if (MAIL_CACHE_IS_UNUSABLE(cache)) {
 		*offset_r = 0;
+		if (field_hdr_r != NULL)
+			*field_hdr_r = NULL;
 		return 0;
 	}
 
@@ -228,16 +233,16 @@
 		invalidate = TRUE;
 
 		if (cache->mmap_base != NULL) {
-			if (mail_cache_map(cache, offset,
-					   sizeof(*field_hdr)) < 0)
-				return -1;
-			if (offset >= cache->mmap_length) {
+			ret = mail_cache_map(cache, offset, sizeof(*field_hdr),
+					     &data);
+			if (ret <= 0) {
+				if (ret < 0)
+					return -1;
 				mail_cache_set_corrupted(cache,
 					"header field next_offset points outside file");
 				return -1;
 			}
-
-			field_hdr = CONST_PTR_OFFSET(cache->data, offset);
+			field_hdr = data;
 		} else {
 			/* if we need to follow multiple offsets to get to
 			   the last one, it's faster to just pread() the file
@@ -270,7 +275,7 @@
 	if (next_count > MAIL_CACHE_HEADER_FIELD_CONTINUE_COUNT)
 		cache->need_compress_file_seq = cache->hdr->file_seq;
 
-	if (map) {
+	if (field_hdr_r != NULL) {
 		if (cache->file_cache != NULL && invalidate) {
 			/* if this isn't the first header in file and we hadn't
 			   read this before, we can't trust that the cached
@@ -278,17 +283,23 @@
 			file_cache_invalidate(cache->file_cache, offset,
 					      field_hdr->size);
 		}
-		if (mail_cache_map(cache, offset, field_hdr->size) < 0)
+		ret = mail_cache_map(cache, offset, field_hdr->size, &data);
+		if (ret < 0)
 			return -1;
+		if (ret == 0) {
+			mail_cache_set_corrupted(cache,
+				"header field size outside file");
+			return -1;
+		}
+		*field_hdr_r = data;
 	}
-
 	*offset_r = offset;
 	return 0;
 }
 
 int mail_cache_header_fields_read(struct mail_cache *cache)
 {
-	const struct mail_cache_header_fields *field_hdr = NULL;
+	const struct mail_cache_header_fields *field_hdr;
 	struct mail_cache_field field;
 	const uint32_t *last_used, *sizes;
 	const uint8_t *types, *decisions;
@@ -299,7 +310,7 @@
 	time_t max_drop_time;
 	uint32_t offset, i;
 
-	if (mail_cache_header_fields_get_offset(cache, &offset, TRUE) < 0)
+	if (mail_cache_header_fields_get_offset(cache, &offset, &field_hdr) < 0)
 		return -1;
 
 	if (offset == 0) {
@@ -307,13 +318,6 @@
 		return 0;
 	}
 
-	field_hdr = CONST_PTR_OFFSET(cache->data, offset);
-	if (offset + field_hdr->size > cache->mmap_length) {
-		mail_cache_set_corrupted(cache,
-					 "field header points outside file");
-		return -1;
-	}
-
 	/* check the fixed size of the header. name[] has to be checked
 	   separately */
 	if (field_hdr->size < sizeof(*field_hdr) +
@@ -322,9 +326,7 @@
 		return -1;
 	}
 
-	field_hdr = CONST_PTR_OFFSET(cache->data, offset);
 	new_fields_count = field_hdr->fields_count;
-
 	if (new_fields_count != 0) {
 		cache->file_field_map =
 			i_realloc(cache->file_field_map,
diff -r 41aac09497ee -r 022d0d21e56d src/lib-index/mail-cache-lookup.c
--- a/src/lib-index/mail-cache-lookup.c	Tue Oct 16 03:34:51 2012 +0300
+++ b/src/lib-index/mail-cache-lookup.c	Thu Oct 18 05:10:29 2012 +0300
@@ -14,6 +14,7 @@
 			  const struct mail_cache_record **rec_r)
 {
 	const struct mail_cache_record *rec;
+	const void *data;
 
 	i_assert(offset != 0);
 
@@ -24,14 +25,15 @@
 	}
 
 	/* we don't know yet how large the record is, so just guess */
-	if (mail_cache_map(cache, offset, sizeof(*rec) + CACHE_PREFETCH) < 0)
+	if (mail_cache_map(cache, offset, sizeof(*rec) + CACHE_PREFETCH,
+			   &data) < 0)
 		return -1;
 
 	if (offset + sizeof(*rec) > cache->mmap_length) {
 		mail_cache_set_corrupted(cache, "record points outside file");
 		return -1;
 	}
-	rec = CACHE_RECORD(cache, offset);
+	rec = data;
 
 	if (rec->size < sizeof(*rec)) {
 		mail_cache_set_corrupted(cache, "invalid record size");
@@ -39,9 +41,9 @@
 	}
 	if (rec->size > CACHE_PREFETCH) {
 		/* larger than we guessed. map the rest of the record. */
-		if (mail_cache_map(cache, offset, rec->size) < 0)
+		if (mail_cache_map(cache, offset, rec->size, &data) < 0)
 			return -1;
-		rec = CACHE_RECORD(cache, offset);
+		rec = data;
 	}
 
 	if (rec->size > cache->mmap_length ||
diff -r 41aac09497ee -r 022d0d21e56d src/lib-index/mail-cache-private.h
--- a/src/lib-index/mail-cache-private.h	Tue Oct 16 03:34:51 2012 +0300
+++ b/src/lib-index/mail-cache-private.h	Thu Oct 18 05:10:29 2012 +0300
@@ -256,7 +256,8 @@
 int mail_cache_lookup_iter_next(struct mail_cache_lookup_iterate_ctx *ctx,
 				struct mail_cache_iterate_field *field_r);
 
-int mail_cache_map(struct mail_cache *cache, size_t offset, size_t size);
+int mail_cache_map(struct mail_cache *cache, size_t offset, size_t size,
+		   const void **data_r);
 void mail_cache_file_close(struct mail_cache *cache);
 int mail_cache_reopen(struct mail_cache *cache);
 
diff -r 41aac09497ee -r 022d0d21e56d src/lib-index/mail-cache-transaction.c
--- a/src/lib-index/mail-cache-transaction.c	Tue Oct 16 03:34:51 2012 +0300
+++ b/src/lib-index/mail-cache-transaction.c	Thu Oct 18 05:10:29 2012 +0300
@@ -1091,6 +1091,8 @@
 		    uint32_t new_offset)
 {
 	const struct mail_cache_record *rec;
+	const void *data;
+	int ret;
 
 	i_assert(cache->locked);
 
@@ -1107,15 +1109,16 @@
 	   records at the same time. we'd rather not lose those additions, so
 	   force the linking order to be new_offset -> old_offset if it isn't
 	   already. */
-	if (mail_cache_map(cache, new_offset, sizeof(*rec)) < 0)
-		return -1;
-	if (new_offset + sizeof(*rec) > cache->mmap_length) {
-		mail_cache_set_corrupted(cache,
-			"Cache record offset %u points outside file",
-			new_offset);
+	ret = mail_cache_map(cache, new_offset, sizeof(*rec), &data);
+	if (ret <= 0) {
+		if (ret == 0) {
+			mail_cache_set_corrupted(cache,
+				"Cache record offset %u points outside file",
+				new_offset);
+		}
 		return -1;
 	}
-	rec = CACHE_RECORD(cache, new_offset);
+	rec = data;
 	if (rec->prev_offset == old_offset) {
 		/* link is already correct */
 		return 0;
diff -r 41aac09497ee -r 022d0d21e56d src/lib-index/mail-cache.c
--- a/src/lib-index/mail-cache.c	Tue Oct 16 03:34:51 2012 +0300
+++ b/src/lib-index/mail-cache.c	Thu Oct 18 05:10:29 2012 +0300
@@ -145,6 +145,7 @@
 {
 	struct mail_index_view *view;
 	const struct mail_index_ext *ext;
+	const void *data;
 
 	i_assert(!cache->locked);
 
@@ -167,7 +168,7 @@
 
 	mail_cache_init_file_cache(cache);
 
-	if (mail_cache_map(cache, 0, 0) < 0)
+	if (mail_cache_map(cache, 0, 0, &data) < 0)
 		return -1;
 
 	if (mail_cache_header_fields_read(cache) < 0)
@@ -265,8 +266,10 @@
 	return TRUE;
 }
 
-int mail_cache_map(struct mail_cache *cache, size_t offset, size_t size)
+int mail_cache_map(struct mail_cache *cache, size_t offset, size_t size,
+		   const void **data_r)
 {
+	const void *data;
 	ssize_t ret;
 
 	cache->remap_counter++;
@@ -309,13 +312,22 @@
 		cache->hdr = &cache->hdr_ro_copy;
 		if (offset == 0)
 			mail_cache_update_need_compress(cache);
-		return 0;
+
+		data = file_cache_get_map(cache->file_cache,
+					  &cache->mmap_length);
+		if (offset > cache->mmap_length) {
+			*data_r = NULL;
+			return 0;
+		}
+		*data_r = CONST_PTR_OFFSET(data, offset);
+		return offset + size > cache->mmap_length ? 0 : 1;
 	}
 
 	if (offset < cache->mmap_length &&
 	    size <= cache->mmap_length - offset) {
 		/* already mapped */
-		return 0;
+		*data_r = CONST_PTR_OFFSET(cache->mmap_base, offset);
+		return 1;
 	}
 
 	if (cache->mmap_base != NULL) {
@@ -355,11 +367,18 @@
 	cache->hdr = cache->data;
 	if (offset == 0)
 		mail_cache_update_need_compress(cache);
-	return 0;
+	if (offset > cache->mmap_length) {
+		*data_r = NULL;
+		return 0;
+	}
+	*data_r = CONST_PTR_OFFSET(cache->mmap_base, offset);
+	return offset + size > cache->mmap_length ? 0 : 1;
 }


More information about the dovecot-cvs mailing list