[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