[dovecot-cvs] dovecot/src/lib-index mailbox-list-index-private.h, 1.4, 1.5 mailbox-list-index-sync.c, 1.7, 1.8 mailbox-list-index.c, 1.7, 1.8 mailbox-list-index.h, 1.1, 1.2

tss at dovecot.org tss at dovecot.org
Thu Mar 15 15:34:53 EET 2007


Update of /var/lib/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv9898/lib-index

Modified Files:
	mailbox-list-index-private.h mailbox-list-index-sync.c 
	mailbox-list-index.c mailbox-list-index.h 
Log Message:
Fixed desyncing problems with mail index and mailbox list index.



Index: mailbox-list-index-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mailbox-list-index-private.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- mailbox-list-index-private.h	28 Dec 2006 16:28:30 -0000	1.4
+++ mailbox-list-index-private.h	15 Mar 2007 13:34:49 -0000	1.5
@@ -82,7 +82,7 @@
 				      const struct mailbox_list_dir_record *dir,
 				      const char *name,
 				      const struct mailbox_list_record **rec_r);
-int mailbox_list_index_get_dir(struct mailbox_list_index *index,
+int mailbox_list_index_get_dir(struct mailbox_list_index_view *view,
 			       uint32_t *offset,
 			       const struct mailbox_list_dir_record **dir_r);
 int mailbox_list_index_map(struct mailbox_list_index *index);

Index: mailbox-list-index-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mailbox-list-index-sync.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- mailbox-list-index-sync.c	15 Mar 2007 12:04:45 -0000	1.7
+++ mailbox-list-index-sync.c	15 Mar 2007 13:34:49 -0000	1.8
@@ -44,12 +44,13 @@
 
 struct mailbox_list_index_sync_ctx {
 	struct mailbox_list_index *index;
+	struct mailbox_list_index_view *view;
 	pool_t pool;
 
 	enum mailbox_list_sync_flags flags;
 	const char *sync_path;
 	struct mail_index_sync_ctx *mail_sync_ctx;
-	struct mail_index_view *view;
+	struct mail_index_view *mail_view;
 	struct mail_index_transaction *trans;
 
 	struct mailbox_list_index_header hdr;
@@ -96,7 +97,7 @@
 	size_t max_len;
 	unsigned int i;
 
-	if (mailbox_list_index_get_dir(ctx->index, &offset, &dir) < 0)
+	if (mailbox_list_index_get_dir(ctx->view, &offset, &dir) < 0)
 		return -1;
 
 	sync_dir = mailbox_list_alloc_sync_dir(ctx, dir->count +
@@ -198,7 +199,7 @@
 		return mailbox_list_index_set_corrupted(ctx->index,
 							"Record with UID=0");
 	}
-	if (mail_index_lookup_uid_range(ctx->view, rec->uid, rec->uid,
+	if (mail_index_lookup_uid_range(ctx->mail_view, rec->uid, rec->uid,
 					&rec->seq, &rec->seq) < 0)
 		return -1;
 
@@ -330,7 +331,7 @@
 	struct mail_index_sync_rec sync_rec;
 
 	if (mail_index_sync_begin(ctx->index->mail_index, &ctx->mail_sync_ctx,
-				  &ctx->view, (uint32_t)-1, 0,
+				  &ctx->mail_view, (uint32_t)-1, 0,
 				  FALSE, FALSE) < 0)
 		return -1;
 
@@ -347,7 +348,7 @@
 
 	ctx->hdr = *ctx->index->hdr;
 
-	hdr = mail_index_get_header(ctx->view);
+	hdr = mail_index_get_header(ctx->mail_view);
 	if (hdr->uid_validity != 0) {
 		if (hdr->uid_validity != ctx->hdr.uid_validity) {
 			return mailbox_list_index_set_corrupted(ctx->index,
@@ -355,7 +356,7 @@
 		}
 	}
 
-	ctx->trans = mail_index_transaction_begin(ctx->view, FALSE, TRUE);
+	ctx->trans = mail_index_transaction_begin(ctx->mail_view, FALSE, TRUE);
 	if (hdr->uid_validity == 0) {
 		mail_index_update_header(ctx->trans,
 			offsetof(struct mail_index_header, uid_validity),
@@ -386,6 +387,7 @@
 	ctx = p_new(pool, struct mailbox_list_index_sync_ctx, 1);
 	ctx->pool = pool;
 	ctx->index = index;
+	ctx->view = mailbox_list_index_view_init(index, NULL);
 	ctx->sync_path = p_strdup(pool, path);
 	ctx->flags = flags;
 
@@ -405,7 +407,7 @@
 struct mail_index_view *
 mailbox_list_index_sync_get_view(struct mailbox_list_index_sync_ctx *ctx)
 {
-	return ctx->view;
+	return ctx->mail_view;
 }
 
 struct mail_index_transaction *
@@ -553,7 +555,7 @@
 			/* expunge from mail index */
 			uint32_t seq;
 
-			if (mail_index_lookup_uid_range(ctx->view,
+			if (mail_index_lookup_uid_range(ctx->mail_view,
 							sync_recs[src].uid,
 							sync_recs[src].uid,
 							&seq, &seq) < 0)
@@ -646,7 +648,7 @@
 
 	i_assert(sync_dir->offset != 0);
 
-	if (mailbox_list_index_get_dir(ctx->index, &sync_dir->offset, &dir) < 0)
+	if (mailbox_list_index_get_dir(ctx->view, &sync_dir->offset, &dir) < 0)
 		return -1;
 
 	sync_recs = array_get(&sync_dir->records, &count);
@@ -831,6 +833,16 @@
 			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->trans != NULL) {
 		if (ret < 0)
 			mail_index_transaction_rollback(&ctx->trans);
@@ -852,6 +864,7 @@
 		}
 	}
 
+	mailbox_list_index_view_deinit(&ctx->view);
 	pool_unref(ctx->pool);
 	return ret;
 }

Index: mailbox-list-index.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mailbox-list-index.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- mailbox-list-index.c	15 Mar 2007 12:04:45 -0000	1.7
+++ mailbox-list-index.c	15 Mar 2007 13:34:49 -0000	1.8
@@ -23,9 +23,13 @@
 	unsigned int name_path_len;
 };
 
-struct mailbox_list_iter_ctx {
+struct mailbox_list_index_view {
 	struct mailbox_list_index *index;
+	struct mail_index_view *mail_view;
+};
 
+struct mailbox_list_iter_ctx {
+	struct mailbox_list_index_view *view;
 	unsigned int recurse_level;
 
 	struct mailbox_list_iter_path cur;
@@ -394,15 +398,24 @@
 	return ret;
 }
 
-int mailbox_list_index_get_dir(struct mailbox_list_index *index,
+int mailbox_list_index_get_dir(struct mailbox_list_index_view *view,
 			       uint32_t *offset,
 			       const struct mailbox_list_dir_record **dir_r)
 {
+	struct mailbox_list_index *index = view->index;
 	const struct mailbox_list_dir_record *dir;
-	uint32_t next_offset, cur_offset = *offset;
+	uint32_t next_offset, view_sync_offset, cur_offset = *offset;
 
 	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;
+	}
+
 	do {
 		if (cur_offset >= index->mmap_size - sizeof(*dir)) {
 			return mailbox_list_index_set_corrupted(index,
@@ -419,6 +432,11 @@
 			return mailbox_list_index_set_corrupted(index,
 				"next_offset points backwards");
 		}
+		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);
 
@@ -465,10 +483,11 @@
 }
 
 static int
-mailbox_list_index_lookup_rec(struct mailbox_list_index *index,
+mailbox_list_index_lookup_rec(struct mailbox_list_index_view *view,
 			      uint32_t dir_offset, const char *name,
 			      const struct mailbox_list_record **rec_r)
 {
+	struct mailbox_list_index *index = view->index;
 	const struct mailbox_list_dir_record *dir;
 	const char *p, *hier_name;
 	int ret;
@@ -479,7 +498,7 @@
 		return 0;
 	}
 
-	if (mailbox_list_index_get_dir(index, &dir_offset, &dir) < 0)
+	if (mailbox_list_index_get_dir(view, &dir_offset, &dir) < 0)
 		return -1;
 
 	p = strchr(name, index->separator);
@@ -499,7 +518,7 @@
 	if (dir_offset == 0)
 		return 0;
 
-	return mailbox_list_index_lookup_rec(index, dir_offset, p + 1, rec_r);
+	return mailbox_list_index_lookup_rec(view, dir_offset, p + 1, rec_r);
 }
 
 int mailbox_list_index_refresh(struct mailbox_list_index *index)
@@ -519,20 +538,40 @@
 	return mailbox_list_index_open_or_create(index);
 }
 
-int mailbox_list_index_lookup(struct mailbox_list_index *index,
+struct mailbox_list_index_view *
+mailbox_list_index_view_init(struct mailbox_list_index *index,
+			     struct mail_index_view *mail_view)
+{
+	struct mailbox_list_index_view *view;
+
+	view = i_new(struct mailbox_list_index_view, 1);
+	view->index = index;
+	view->mail_view = mail_view;
+	return view;
+}
+
+void mailbox_list_index_view_deinit(struct mailbox_list_index_view **_view)
+{
+	struct mailbox_list_index_view *view = *_view;
+
+	*_view = NULL;
+	i_free(view);
+}
+
+int mailbox_list_index_lookup(struct mailbox_list_index_view *view,
 			      const char *name, uint32_t *uid_r)
 {
 	const struct mailbox_list_record *rec;
-	uint32_t offset = sizeof(*index->hdr);
+	uint32_t offset = sizeof(*view->index->hdr);
 	int ret;
 
-	ret = mailbox_list_index_lookup_rec(index, offset, name, &rec);
+	ret = mailbox_list_index_lookup_rec(view, offset, name, &rec);
 	if (ret == 0) {
 		/* not found, see if it's found after a refresh */
-		if ((ret = mailbox_list_index_refresh(index)) <= 0)
+		if ((ret = mailbox_list_index_refresh(view->index)) <= 0)
 			return ret;
 
-		ret = mailbox_list_index_lookup_rec(index, offset, name, &rec);
+		ret = mailbox_list_index_lookup_rec(view, offset, name, &rec);
 	}
 
 	*uid_r = ret <= 0 ? 0 : rec->uid;
@@ -540,24 +579,24 @@
 }
 
 struct mailbox_list_iter_ctx *
-mailbox_list_index_iterate_init(struct mailbox_list_index *index,
+mailbox_list_index_iterate_init(struct mailbox_list_index_view *view,
 				const char *path, int recurse_level)
 {
 	struct mailbox_list_iter_ctx *ctx;
 	const struct mailbox_list_record *rec;
-	uint32_t offset = sizeof(*index->hdr);
+	uint32_t offset = sizeof(*view->index->hdr);
 	int ret;
 
 	ctx = i_new(struct mailbox_list_iter_ctx, 1);
-	ctx->index = index;
+	ctx->view = view;
 	ctx->recurse_level = recurse_level < 0 ? (unsigned int)-1 :
 		(unsigned int)recurse_level;
 	ctx->name_path = str_new(default_pool, 512);
 
-	if (mailbox_list_index_refresh(index) < 0)
+	if (mailbox_list_index_refresh(view->index) < 0)
 		ctx->failed = TRUE;
 	if (!ctx->failed && *path != '\0') {
-		ret = mailbox_list_index_lookup_rec(index, offset, path, &rec);
+		ret = mailbox_list_index_lookup_rec(view, offset, path, &rec);
 		if (ret < 0)
 			ctx->failed = TRUE;
 		else {
@@ -566,7 +605,7 @@
 		}
 	}
 	if (!ctx->failed && offset != 0) {
-		if (mailbox_list_index_get_dir(index, &offset,
+		if (mailbox_list_index_get_dir(view, &offset,
 					       &ctx->cur.dir) < 0)
 			ctx->failed = TRUE;
 	}
@@ -616,7 +655,7 @@
 	}
 
 	t_push();
-	if (mailbox_list_get_name(ctx->index, unsafe_data_stack_pool,
+	if (mailbox_list_get_name(ctx->view->index, unsafe_data_stack_pool,
 				  recs, &name) < 0) {
 		ctx->failed = TRUE;
 		t_pop();
@@ -624,7 +663,7 @@
 	}
 	str_truncate(ctx->name_path, ctx->cur.name_path_len);
 	if (ctx->cur.name_path_len > 0)
-		str_append_c(ctx->name_path, ctx->index->separator);
+		str_append_c(ctx->name_path, ctx->view->index->separator);
 	str_append(ctx->name_path, name);
 	t_pop();
 
@@ -635,7 +674,7 @@
 
 		ctx->cur.name_path_len = str_len(ctx->name_path);
 		ctx->cur.pos = 0;
-		if (mailbox_list_index_get_dir(ctx->index, &dir_offset,
+		if (mailbox_list_index_get_dir(ctx->view, &dir_offset,
 					       &ctx->cur.dir) < 0) {
 			ctx->failed = TRUE;
 			return -1;

Index: mailbox-list-index.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mailbox-list-index.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- mailbox-list-index.h	25 Nov 2006 22:17:40 -0000	1.1
+++ mailbox-list-index.h	15 Mar 2007 13:34:49 -0000	1.2
@@ -59,9 +59,17 @@
 int mailbox_list_index_sync_commit(struct mailbox_list_index_sync_ctx **ctx);
 void mailbox_list_index_sync_rollback(struct mailbox_list_index_sync_ctx **ctx);
 
+/* Mailbox list index and mail index must be kept in sync, so lookups and
+   iterations must know the mail index view. The mail_view can be set to NULL
+   to use the latest changes. */
+struct mailbox_list_index_view *
+mailbox_list_index_view_init(struct mailbox_list_index *index,
+			     struct mail_index_view *mail_view);
+void mailbox_list_index_view_deinit(struct mailbox_list_index_view **view);
+
 /* Get mailbox UID for a given name. Returns 1 if found, 0 if not,
    -1 if error */
-int mailbox_list_index_lookup(struct mailbox_list_index *index,
+int mailbox_list_index_lookup(struct mailbox_list_index_view *view,
 			      const char *name, uint32_t *uid_r);
 
 /* Iterate through all the mailboxes. If recurse_level is -1, all the child
@@ -69,7 +77,7 @@
    (0 = only the mailboxes directly under the path). Returned mailbox names
    are allocated from name_pool. */
 struct mailbox_list_iter_ctx *
-mailbox_list_index_iterate_init(struct mailbox_list_index *index,
+mailbox_list_index_iterate_init(struct mailbox_list_index_view *view,
 				const char *path, int recurse_level);
 /* Returns 1 if mailbox was returned, 0 at the end of iteration, -1 if error */
 int mailbox_list_index_iterate_next(struct mailbox_list_iter_ctx *ctx,



More information about the dovecot-cvs mailing list