[dovecot-cvs] dovecot/src/lib-index mailbox-list-index-private.h, 1.5, 1.6 mailbox-list-index-sync.c, 1.9, 1.10 mailbox-list-index.c, 1.8, 1.9
tss at dovecot.org
tss at dovecot.org
Fri Mar 16 01:30:37 EET 2007
Update of /var/lib/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv31639
Modified Files:
mailbox-list-index-private.h mailbox-list-index-sync.c
mailbox-list-index.c
Log Message:
More desyncing fixes
Index: mailbox-list-index-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mailbox-list-index-private.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- mailbox-list-index-private.h 15 Mar 2007 13:34:49 -0000 1.5
+++ mailbox-list-index-private.h 15 Mar 2007 23:30:35 -0000 1.6
@@ -29,6 +29,8 @@
/* If non-zero, contains a pointer to updated directory list.
Stored using mail_index_uint32_to_offset(). */
uint32_t next_offset;
+ /* Bytes used by this record, including mailbox names. */
+ uint32_t dir_size;
uint32_t count;
/* The records are sorted by their name_hash */
Index: mailbox-list-index-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mailbox-list-index-sync.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- mailbox-list-index-sync.c 15 Mar 2007 17:02:07 -0000 1.9
+++ mailbox-list-index-sync.c 15 Mar 2007 23:30:35 -0000 1.10
@@ -493,7 +493,7 @@
struct mailbox_list_record *new_recs;
struct mailbox_list_sync_record *sync_recs;
unsigned int src, dest, orig, count, nondeleted_count;
- unsigned int name_space_needed, deleted_space;
+ unsigned int space_needed, deleted_space;
uint32_t base_offset, name_pos, size;
void *base;
@@ -502,15 +502,14 @@
/* count how much space we need and how much we wasted for deleted
records */
- nondeleted_count = 0; name_space_needed = 0; deleted_space = 0;
+ nondeleted_count = 0; space_needed = 0; deleted_space = 0;
sync_recs = array_get_modifiable(&sync_dir->records, &count);
for (src = 0; src < count; src++) {
if (sync_recs[src].seen || partial) {
nondeleted_count++;
if (sync_recs[src].created) {
/* new record */
- name_space_needed +=
- strlen(sync_recs[src].name) + 1;
+ space_needed += strlen(sync_recs[src].name) + 1;
}
} else {
deleted_space += sizeof(*new_recs) +
@@ -519,9 +518,8 @@
}
/* @UNSAFE */
- name_space_needed += sizeof(*dir) +
- nondeleted_count * sizeof(*new_recs);
- if (mailbox_list_index_sync_alloc_space(ctx, name_space_needed,
+ space_needed += sizeof(*dir) + nondeleted_count * sizeof(*new_recs);
+ if (mailbox_list_index_sync_alloc_space(ctx, space_needed,
&base, &base_offset) < 0)
return -1;
/* NOTE: any pointers to the index file may have been invalidated
@@ -541,6 +539,7 @@
new_dir = base;
new_dir->count = nondeleted_count;
+ new_dir->dir_size = space_needed;
new_recs = MAILBOX_LIST_RECORDS_MODIFIABLE(new_dir);
name_pos = (const char *)(new_recs + nondeleted_count) -
@@ -587,7 +586,7 @@
dest++;
}
i_assert(dest == nondeleted_count);
- i_assert(name_pos == name_space_needed);
+ i_assert(name_pos == space_needed);
if (index->mmap_disable) {
file_cache_write(index->file_cache, ctx->output_buf->data,
Index: mailbox-list-index.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mailbox-list-index.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- mailbox-list-index.c 15 Mar 2007 13:34:49 -0000 1.8
+++ mailbox-list-index.c 15 Mar 2007 23:30:35 -0000 1.9
@@ -186,6 +186,21 @@
return 1;
}
+static int mailbox_list_index_map_area(struct mailbox_list_index *index,
+ uoff_t offset, size_t size)
+{
+ if (offset < index->mmap_size && size <= index->mmap_size - offset)
+ return 1;
+
+ if (mailbox_list_index_map(index) <= 0)
+ return -1;
+
+ if (offset < index->mmap_size && size <= index->mmap_size - offset)
+ return 1;
+ /* outside the file */
+ return 0;
+}
+
static void
mailbox_list_index_init_header(struct mailbox_list_index_header *hdr,
uint32_t uid_validity)
@@ -405,6 +420,7 @@
struct mailbox_list_index *index = view->index;
const struct mailbox_list_dir_record *dir;
uint32_t next_offset, view_sync_offset, cur_offset = *offset;
+ int ret;
i_assert(index->mmap_size > 0);
@@ -414,10 +430,15 @@
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 {
- if (cur_offset >= index->mmap_size - sizeof(*dir)) {
+ ret = mailbox_list_index_map_area(index, cur_offset,
+ sizeof(*dir));
+ if (ret <= 0) {
+ if (ret < 0)
+ return -1;
return mailbox_list_index_set_corrupted(index,
"dir_offset points outside file");
}
@@ -432,6 +453,11 @@
return mailbox_list_index_set_corrupted(index,
"next_offset points backwards");
}
+ if (dir->dir_size < sizeof(*dir) +
+ dir->count * sizeof(struct mailbox_list_record)) {
+ 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. */
@@ -440,14 +466,21 @@
cur_offset = next_offset;
} while (cur_offset != 0);
- cur_offset = (const char *)dir - (const char *)index->const_mmap_base;
- if (dir->count > INT_MAX/sizeof(struct mailbox_list_record) ||
- dir->count * sizeof(struct mailbox_list_record) >
- index->mmap_size - cur_offset) {
+ if (dir->count > INT_MAX/sizeof(struct mailbox_list_record)) {
mailbox_list_index_set_corrupted(index, "dir count too large");
return -1;
}
+ cur_offset = (const char *)dir - (const char *)index->const_mmap_base;
+
+ ret = mailbox_list_index_map_area(index, cur_offset, dir->dir_size);
+ if (ret <= 0) {
+ if (ret < 0)
+ return -1;
+ return mailbox_list_index_set_corrupted(index,
+ "dir points outside file");
+ }
+
*offset = cur_offset;
*dir_r = dir;
return 0;
@@ -482,6 +515,23 @@
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,
@@ -492,8 +542,8 @@
const char *p, *hier_name;
int ret;
- if ((dir_offset == index->mmap_size || index->mmap_size == 0) &&
- dir_offset == sizeof(*index->hdr)) {
+ if (dir_offset == sizeof(*index->hdr) &&
+ !mailbox_list_index_offset_exists(view, dir_offset)) {
/* root doesn't exist in the file yet */
return 0;
}
@@ -517,6 +567,10 @@
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);
}
@@ -604,7 +658,10 @@
mail_index_offset_to_uint32(rec->dir_offset);
}
}
- if (!ctx->failed && offset != 0) {
+
+ if (!mailbox_list_index_offset_exists(view, offset)) {
+ /* root doesn't exist / offset isn't visible */
+ } else if (!ctx->failed && offset != 0) {
if (mailbox_list_index_get_dir(view, &offset,
&ctx->cur.dir) < 0)
ctx->failed = TRUE;
@@ -668,6 +725,12 @@
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);
More information about the dovecot-cvs
mailing list