changeset 6087:f479a774a416 HEAD

We can't check if list branch exists in mail_view by checking sync_size header. When compressing list index the sync_size check breaks, and we can't even fix it with file_seq checks or similar, because when reading there are no locks and the list file is recreated before changes to mail index are committed. So instead we'll just always check that uid < mail_view.next_uid before returning it.
author Timo Sirainen <tss@iki.fi>
date Thu, 19 Jul 2007 01:57:47 +0300
parents e562c6359cd1
children 7639a6df4acb
files src/lib-index/mailbox-list-index-sync.c src/lib-index/mailbox-list-index.c
diffstat 2 files changed, 32 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mailbox-list-index-sync.c	Thu Jul 19 01:55:14 2007 +0300
+++ b/src/lib-index/mailbox-list-index-sync.c	Thu Jul 19 01:57:47 2007 +0300
@@ -898,16 +898,6 @@
 			ret = mailbox_list_index_compress(ctx);
 	}
 
-	if (ret == 0) {
-		uint64_t used_space = ctx->hdr.used_space;
-
-		/* FIXME: we should use some extension header instead of
-		   reusing sync_size */
-		mail_index_update_header(ctx->trans,
-			offsetof(struct mail_index_header, sync_size),
-			&used_space, sizeof(used_space), FALSE);
-	}
-
 	if (ctx->mail_sync_ctx != NULL) {
 		if (ret < 0 && !ctx->restart)
 			mail_index_sync_rollback(&ctx->mail_sync_ctx);
--- a/src/lib-index/mailbox-list-index.c	Thu Jul 19 01:55:14 2007 +0300
+++ b/src/lib-index/mailbox-list-index.c	Thu Jul 19 01:57:47 2007 +0300
@@ -32,6 +32,7 @@
 struct mailbox_list_iter_ctx {
 	struct mailbox_list_index_view *view;
 	unsigned int recurse_level;
+	uint32_t max_uid;
 
 	struct mailbox_list_iter_path cur;
 	ARRAY_DEFINE(path, struct mailbox_list_iter_path);
@@ -425,20 +426,11 @@
 {
 	struct mailbox_list_index *index = view->index;
 	const struct mailbox_list_dir_record *dir;
-	uint32_t next_offset, view_sync_offset, cur_offset = *offset;
+	uint32_t next_offset, cur_offset = *offset;
 	int ret;
 
 	i_assert(index->mmap_size > 0);
 
-	if (view->mail_view == NULL)
-		view_sync_offset = (uint32_t)-1;
-	else {
-		const struct mail_index_header *hdr =
-			mail_index_get_header(view->mail_view);
-		view_sync_offset = hdr->sync_size;
-		i_assert(*offset < view_sync_offset);
-	}
-
 	do {
 		ret = mailbox_list_index_map_area(index, cur_offset,
 						  sizeof(*dir));
@@ -464,11 +456,6 @@
 			return mailbox_list_index_set_corrupted(index,
 				"dir_size is smaller than record count");
 		}
-		if (next_offset >= view_sync_offset) {
-			/* the list index has been changed since the mail
-			   view's last sync. don't show the changes. */
-			break;
-		}
 		cur_offset = next_offset;
 	} while (cur_offset != 0);
 
@@ -521,23 +508,6 @@
 	return 1;
 }
 
-static bool
-mailbox_list_index_offset_exists(struct mailbox_list_index_view *view,
-				 uint32_t offset)
-{
-	const struct mail_index_header *hdr;
-
-	if (view->index->mmap_size <= sizeof(*view->index->hdr))
-		return FALSE;
-
-	if (view->mail_view == NULL)
-		return TRUE;
-	else {
-		hdr = mail_index_get_header(view->mail_view);
-		return hdr->sync_size > offset;
-	}
-}
-
 static int
 mailbox_list_index_lookup_rec(struct mailbox_list_index_view *view,
 			      uint32_t dir_offset, const char *name,
@@ -549,7 +519,7 @@
 	int ret;
 
 	if (dir_offset == sizeof(*index->hdr) &&
-	    !mailbox_list_index_offset_exists(view, dir_offset)) {
+	    index->mmap_size <= sizeof(*index->hdr)) {
 		/* root doesn't exist in the file yet */
 		return 0;
 	}
@@ -573,10 +543,6 @@
 	dir_offset = mail_index_offset_to_uint32((*rec_r)->dir_offset);
 	if (dir_offset == 0)
 		return 0;
-	if (!mailbox_list_index_offset_exists(view, dir_offset)) {
-		/* child isn't visible yet */
-		return 0;
-	}
 
 	return mailbox_list_index_lookup_rec(view, dir_offset, p + 1, rec_r);
 }
@@ -654,6 +620,7 @@
 				const char *path, int recurse_level)
 {
 	struct mailbox_list_iter_ctx *ctx;
+	const struct mail_index_header *mail_hdr;
 	const struct mailbox_list_record *rec;
 	uint32_t offset = sizeof(*view->index->hdr);
 	int ret;
@@ -664,6 +631,13 @@
 		(unsigned int)recurse_level;
 	ctx->name_path = str_new(default_pool, 512);
 
+	if (view->mail_view != NULL) {
+		mail_hdr = mail_index_get_header(view->mail_view);
+		ctx->max_uid = mail_hdr->next_uid - 1;
+	} else {
+		ctx->max_uid = (uint32_t)-1;
+	}
+
 	if (mailbox_list_index_refresh(view->index) < 0)
 		ctx->failed = TRUE;
 	if (!ctx->failed && *path != '\0') {
@@ -676,8 +650,8 @@
 		}
 	}
 
-	if (!mailbox_list_index_offset_exists(view, offset)) {
-		/* root doesn't exist / offset isn't visible */
+	if (view->index->mmap_size <= sizeof(*view->index->hdr)) {
+		/* root doesn't exist */
 	} else if (!ctx->failed && offset != 0) {
 		if (mailbox_list_index_get_dir(view, &offset,
 					       &ctx->cur.dir) < 0)
@@ -705,27 +679,29 @@
 		return 0;
 	}
 
-	while (ctx->cur.pos == ctx->cur.dir->count) {
-		count = array_count(&ctx->path);
-		if (count == 0) {
-			/* we're done */
-			return 0;
-		}
+	for (;;) {
+		if (ctx->cur.pos == ctx->cur.dir->count) {
+			count = array_count(&ctx->path);
+			if (count == 0) {
+				/* we're done */
+				return 0;
+			}
 
-		/* go back to parent path */
-		cur = array_idx(&ctx->path, count-1);
-		ctx->cur = *cur;
-		array_delete(&ctx->path, count-1, 1);
+			/* go back to parent path */
+			cur = array_idx(&ctx->path, count-1);
+			ctx->cur = *cur;
+			array_delete(&ctx->path, count-1, 1);
 
-		ctx->cur.pos++;
-	}
+			ctx->cur.pos++;
+		} else {
+			recs = MAILBOX_LIST_RECORDS(ctx->cur.dir);
+			recs += ctx->cur.pos;
 
-	recs = MAILBOX_LIST_RECORDS(ctx->cur.dir);
-	recs += ctx->cur.pos;
+			if (!recs->deleted && recs->uid <= ctx->max_uid)
+				break;
 
-	if (recs->deleted) {
-		ctx->cur.pos++;
-		return mailbox_list_index_iterate_next(ctx, info_r);
+			ctx->cur.pos++;
+		}
 	}
 
 	t_push();
@@ -742,12 +718,6 @@
 	t_pop();
 
 	dir_offset = mail_index_offset_to_uint32(recs->dir_offset);
-	if (dir_offset != 0 &&
-	    !mailbox_list_index_offset_exists(ctx->view, dir_offset)) {
-		/* child isn't visible yet */
-		dir_offset = 0;
-	}
-
 	if (dir_offset != 0 && array_count(&ctx->path) < ctx->recurse_level) {
 		/* recurse into children */
 		array_append(&ctx->path, &ctx->cur, 1);