[dovecot-cvs] dovecot/src/lib-index mail-index-sync-private.h, 1.29.2.2, 1.29.2.3 mail-index-sync-update.c, 1.96.2.9, 1.96.2.10 mail-index-view-sync.c, 1.52.2.6, 1.52.2.7
tss at dovecot.org
tss at dovecot.org
Tue Jan 23 16:10:57 UTC 2007
Update of /var/lib/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv14708
Modified Files:
Tag: branch_1_0
mail-index-sync-private.h mail-index-sync-update.c
mail-index-view-sync.c
Log Message:
Some mmap_disable=no fixes. Some debug additions. Some generic index fixes.
Index: mail-index-sync-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync-private.h,v
retrieving revision 1.29.2.2
retrieving revision 1.29.2.3
diff -u -d -r1.29.2.2 -r1.29.2.3
--- mail-index-sync-private.h 17 Jan 2007 23:33:26 -0000 1.29.2.2
+++ mail-index-sync-private.h 23 Jan 2007 16:10:55 -0000 1.29.2.3
@@ -52,6 +52,7 @@
unsigned int expunge_handlers_used:1;
unsigned int cur_ext_ignore:1;
unsigned int unreliable_flags:1;
+ unsigned int sync_only_external:1;
};
extern struct mail_transaction_map_functions mail_index_map_sync_funcs;
Index: mail-index-sync-update.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync-update.c,v
retrieving revision 1.96.2.9
retrieving revision 1.96.2.10
diff -u -d -r1.96.2.9 -r1.96.2.10
--- mail-index-sync-update.c 23 Jan 2007 13:29:43 -0000 1.96.2.9
+++ mail-index-sync-update.c 23 Jan 2007 16:10:55 -0000 1.96.2.10
@@ -12,13 +12,63 @@
#include "mail-transaction-log-private.h"
#include "mail-transaction-util.h"
+static void
+mail_index_sync_update_log_offset(struct mail_index_sync_map_ctx *ctx,
+ struct mail_index_map *map)
+{
+ uint32_t prev_seq;
+ uoff_t prev_offset;
+
+ mail_transaction_log_view_get_prev_pos(ctx->view->log_view,
+ &prev_seq, &prev_offset);
+
+ if (!ctx->sync_only_external)
+ map->hdr.log_file_int_offset = prev_offset;
+ else if (map->hdr.log_file_seq != prev_seq && map == ctx->view->map) {
+ /* log sequence changed. update internal offset to
+ beginning of the new file. */
+ i_assert(map->hdr.log_file_int_offset ==
+ ctx->view->index->log->head->hdr.prev_file_offset);
+ map->hdr.log_file_int_offset =
+ ctx->view->index->log->head->hdr.hdr_size;
+ }
+ map->hdr.log_file_seq = prev_seq;
+ map->hdr.log_file_ext_offset = prev_offset;
+}
+
+static int
+mail_index_map_msync(struct mail_index *index, struct mail_index_map *map)
+{
+ unsigned int base_size;
+
+ if (MAIL_INDEX_MAP_IS_IN_MEMORY(map))
+ return 0;
+
+ base_size = I_MIN(map->hdr.base_header_size, sizeof(map->hdr));
+ map->mmap_used_size = index->hdr->header_size +
+ map->records_count * map->hdr.record_size;
+
+ memcpy(map->mmap_base, &map->hdr, base_size);
+ memcpy(PTR_OFFSET(map->mmap_base, base_size),
+ CONST_PTR_OFFSET(map->hdr_base, base_size),
+ map->hdr.header_size - base_size);
+ if (msync(map->mmap_base, map->mmap_used_size, MS_SYNC) < 0) {
+ mail_index_set_syscall_error(index, "msync()");
+ return -1;
+ }
+ return 0;
+}
+
void mail_index_sync_replace_map(struct mail_index_sync_map_ctx *ctx,
struct mail_index_map *map)
{
struct mail_index_view *view = ctx->view;
+ struct mail_index_map *old_map = view->map;
i_assert(view->map != map);
+ old_map->refcount++;
+
/* if map still exists after this, it's only in views. */
view->map->write_to_disk = FALSE;
/* keywords aren't parsed for the new map yet */
@@ -28,9 +78,8 @@
view->map = map;
if ((ctx->type & (MAIL_INDEX_SYNC_HANDLER_FILE |
- MAIL_INDEX_SYNC_HANDLER_HEAD)) != 0) {
- i_assert(view->index->map != map);
-
+ MAIL_INDEX_SYNC_HANDLER_HEAD)) != 0 &&
+ view->index->map != map) {
mail_index_unmap(view->index, &view->index->map);
view->index->map = map;
view->index->hdr = &map->hdr;
@@ -42,6 +91,15 @@
}
}
+ if (!MAIL_INDEX_MAP_IS_IN_MEMORY(old_map)) {
+ /* other processes may still have the same file mapped,
+ and since we could have already updated the records, make
+ sure we leave the header in a valid state as well */
+ mail_index_sync_update_log_offset(ctx, old_map);
+ (void)mail_index_map_msync(view->index, old_map);
+ }
+ mail_index_unmap(view->index, &old_map);
+
i_assert(view->hdr.messages_count == map->hdr.messages_count);
}
@@ -698,8 +756,7 @@
const struct mail_transaction_header *thdr;
const void *data;
unsigned int count, old_lock_id;
- uint32_t seq, i, first_append_uid;
- uoff_t offset;
+ uint32_t i, first_append_uid;
int ret;
bool had_dirty, skipped, check_ext_offsets;
@@ -773,10 +830,9 @@
break;
}
if (map != index->map) {
- map = index->map;
- mail_index_unmap(view->index, &view->map);
- view->map = map;
- view->map->refcount++;
+ index->map->refcount++;
+ mail_index_sync_replace_map(&sync_map_ctx,
+ index->map);
}
}
@@ -789,8 +845,10 @@
make sure we don't accidentally try to use it. */
map = NULL;
}
- map = view->map;
- mail_index_sync_map_deinit(&sync_map_ctx);
+
+ if (ret == 0)
+ mail_index_sync_update_log_offset(&sync_map_ctx, view->map);
+ mail_index_sync_map_deinit(&sync_map_ctx);
index->sync_update = FALSE;
@@ -799,22 +857,8 @@
return -1;
}
+ map = view->map;
i_assert(map->records_count == map->hdr.messages_count);
-
- mail_transaction_log_get_head(index->log, &seq, &offset);
-
- if (!sync_only_external)
- map->hdr.log_file_int_offset = offset;
- else if (map->hdr.log_file_seq != seq) {
- /* log sequence changed. update internal offset to
- beginning of the new file. */
- i_assert(map->hdr.log_file_int_offset ==
- index->log->head->hdr.prev_file_offset);
- map->hdr.log_file_int_offset = index->log->head->hdr.hdr_size;
- }
- map->hdr.log_file_seq = seq;
- map->hdr.log_file_ext_offset = offset;
-
i_assert(map->hdr_copy_buf->used <= map->hdr.header_size);
if (first_append_uid != 0)
@@ -835,22 +879,8 @@
}
}
- if (!MAIL_INDEX_MAP_IS_IN_MEMORY(map)) {
- unsigned int base_size;
-
- base_size = I_MIN(map->hdr.base_header_size, sizeof(map->hdr));
- map->mmap_used_size = index->hdr->header_size +
- map->records_count * map->hdr.record_size;
-
- memcpy(map->mmap_base, &map->hdr, base_size);
- memcpy(PTR_OFFSET(map->mmap_base, base_size),
- CONST_PTR_OFFSET(map->hdr_base, base_size),
- map->hdr.header_size - base_size);
- if (msync(map->mmap_base, map->mmap_used_size, MS_SYNC) < 0) {
- mail_index_set_syscall_error(index, "msync()");
- ret = -1;
- }
- }
+ if (mail_index_map_msync(index, map) < 0)
+ ret = -1;
i_assert(view->map == index->map);
view->hdr = map->hdr;
Index: mail-index-view-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-view-sync.c,v
retrieving revision 1.52.2.6
retrieving revision 1.52.2.7
diff -u -d -r1.52.2.6 -r1.52.2.7
--- mail-index-view-sync.c 17 Jan 2007 18:47:43 -0000 1.52.2.6
+++ mail-index-view-sync.c 23 Jan 2007 16:10:55 -0000 1.52.2.7
@@ -196,6 +196,42 @@
MAIL_TRANSACTION_FLAG_UPDATE | MAIL_TRANSACTION_KEYWORD_UPDATE | \
MAIL_TRANSACTION_KEYWORD_RESET)
+#ifdef DEBUG
+static void mail_index_view_check(struct mail_index_view *view)
+{
+ unsigned int i, del = 0, recent = 0, seen = 0;
+
+ i_assert(view->hdr.deleted_messages_count ==
+ view->map->hdr.deleted_messages_count);
+ i_assert(view->hdr.recent_messages_count ==
+ view->map->hdr.recent_messages_count);
+ i_assert(view->hdr.seen_messages_count ==
+ view->map->hdr.seen_messages_count);
+
+ for (i = 0; i < view->map->records_count; i++) {
+ const struct mail_index_record *rec;
+
+ rec = MAIL_INDEX_MAP_IDX(view->map, i);
+
+ if (rec->flags & MAIL_DELETED) {
+ i_assert(rec->uid >= view->hdr.first_deleted_uid_lowwater);
+ del++;
+ }
+ if (rec->flags & MAIL_RECENT) {
+ i_assert(rec->uid >= view->hdr.first_recent_uid_lowwater);
+ recent++;
+ }
+ if (rec->flags & MAIL_SEEN)
+ seen++;
+ else
+ i_assert(rec->uid >= view->hdr.first_unseen_uid_lowwater);
+ }
+ i_assert(del == view->hdr.deleted_messages_count);
+ i_assert(recent == view->hdr.recent_messages_count);
+ i_assert(seen == view->hdr.seen_messages_count);
+}
+#endif
+
int mail_index_view_sync_begin(struct mail_index_view *view,
enum mail_index_sync_type sync_mask,
struct mail_index_view_sync_ctx **ctx_r)
@@ -279,8 +315,12 @@
update flag counters. note that map->hdr may contain
old information if another process updated the
index file since. */
- hdr = view->map->mmap_base != NULL ?
- view->map->mmap_base : &view->map->hdr;
+ if (view->map->mmap_base == NULL)
+ hdr = &view->map->hdr;
+ else {
+ hdr = view->map->mmap_base;
+ view->map->hdr = *hdr;
+ }
ctx->sync_map_ctx.unreliable_flags =
!(hdr->log_file_seq == view->log_file_seq &&
hdr->log_file_int_offset ==
@@ -292,6 +332,11 @@
i_assert(view->map->records_count >=
view->hdr.messages_count);
view->map->records_count = view->hdr.messages_count;
+
+#ifdef DEBUG
+ if (!ctx->sync_map_ctx.unreliable_flags)
+ mail_index_view_check(view);
+#endif
}
map = mail_index_map_clone(view->map,
@@ -348,7 +393,7 @@
uint32_t seq;
uoff_t offset;
int ret;
- bool skipped;
+ bool skipped, synced_to_map;
for (;;) {
/* Get the next transaction from log. */
@@ -382,13 +427,6 @@
}
/* skip everything we've already synced */
- if (offset < view->hdr.log_file_ext_offset &&
- seq == view->hdr.log_file_seq &&
- (ctx->hdr->type & MAIL_TRANSACTION_EXTERNAL) != 0) {
- /* view->log_file_offset contains the minimum of
- int/ext offsets. */
- continue;
- }
if (view_sync_pos_find(&view->syncs_done, seq, offset))
continue;
@@ -401,9 +439,15 @@
offset);
}
+ /* view->log_file_offset contains the minimum of
+ int/ext offsets. */
+ synced_to_map = offset < view->hdr.log_file_ext_offset &&
+ seq == view->hdr.log_file_seq &&
+ (ctx->hdr->type & MAIL_TRANSACTION_EXTERNAL) != 0;
+
/* Apply transaction to view's mapping if needed (meaning we
didn't just re-map the view to head mapping). */
- if (ctx->sync_map_update) {
+ if (ctx->sync_map_update && !synced_to_map) {
i_assert((ctx->hdr->type &
MAIL_TRANSACTION_EXPUNGE) == 0);
@@ -598,6 +642,11 @@
}
view->hdr = view->map->hdr;
+#ifdef DEBUG
+ if (!view->broken_counters)
+ mail_index_view_check(view);
+#endif
+
/* set log view to empty range so unneeded memory gets freed */
(void)mail_transaction_log_view_set(view->log_view,
view->log_file_seq,
More information about the dovecot-cvs
mailing list