dovecot: Added support for resetting index.
dovecot at dovecot.org
dovecot at dovecot.org
Sun Jul 1 01:05:51 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/a9df50952600
changeset: 5849:a9df50952600
user: Timo Sirainen <tss at iki.fi>
date: Sun Jul 01 01:05:26 2007 +0300
description:
Added support for resetting index.
diffstat:
13 files changed, 201 insertions(+), 81 deletions(-)
src/lib-index/mail-index-sync-update.c | 13 ++
src/lib-index/mail-index-sync.c | 3
src/lib-index/mail-index-transaction-private.h | 6 +
src/lib-index/mail-index-transaction.c | 9 +
src/lib-index/mail-index-view-sync.c | 68 +++++++++-----
src/lib-index/mail-index-write.c | 4
src/lib-index/mail-index.h | 3
src/lib-index/mail-transaction-log-append.c | 11 ++
src/lib-index/mail-transaction-log-file.c | 17 ++-
src/lib-index/mail-transaction-log-private.h | 5 -
src/lib-index/mail-transaction-log-view.c | 115 ++++++++++++++++--------
src/lib-index/mail-transaction-log.c | 14 +-
src/lib-index/mail-transaction-log.h | 14 +-
diffs (truncated from 621 to 300 lines):
diff -r 064aa8ff69c2 -r a9df50952600 src/lib-index/mail-index-sync-update.c
--- a/src/lib-index/mail-index-sync-update.c Sun Jul 01 01:04:57 2007 +0300
+++ b/src/lib-index/mail-index-sync-update.c Sun Jul 01 01:05:26 2007 +0300
@@ -697,7 +697,7 @@ int mail_index_sync_map(struct mail_inde
uint32_t prev_seq;
uoff_t start_offset, prev_offset;
int ret;
- bool had_dirty;
+ bool had_dirty, reset;
i_assert(index->map == map || type == MAIL_INDEX_SYNC_HANDLER_VIEW);
@@ -725,7 +725,7 @@ int mail_index_sync_map(struct mail_inde
view = mail_index_view_open_with_map(index, map);
ret = mail_transaction_log_view_set(view->log_view,
map->hdr.log_file_seq, start_offset,
- (uint32_t)-1, (uoff_t)-1);
+ (uint32_t)-1, (uoff_t)-1, &reset);
if (ret <= 0) {
if (force && ret == 0) {
/* the seq/offset is probably broken */
@@ -758,6 +758,15 @@ int mail_index_sync_map(struct mail_inde
}
mail_index_sync_map_init(&sync_map_ctx, view, type);
+ if (reset) {
+ /* Reset the entire index. Leave only indexid and
+ log_file_seq. */
+ mail_transaction_log_view_get_prev_pos(view->log_view,
+ &prev_seq, &prev_offset);
+ map = mail_index_map_alloc(index);
+ map->hdr.log_file_seq = prev_seq;
+ mail_index_sync_replace_map(&sync_map_ctx, map);
+ }
map = NULL;
/* FIXME: when transaction sync lock is removed, we'll need to handle
diff -r 064aa8ff69c2 -r a9df50952600 src/lib-index/mail-index-sync.c
--- a/src/lib-index/mail-index-sync.c Sun Jul 01 01:04:57 2007 +0300
+++ b/src/lib-index/mail-index-sync.c Sun Jul 01 01:05:26 2007 +0300
@@ -308,13 +308,14 @@ mail_index_sync_set_log_view(struct mail
{
uint32_t log_seq;
uoff_t log_offset;
+ bool reset;
int ret;
mail_transaction_log_get_head(view->index->log, &log_seq, &log_offset);
ret = mail_transaction_log_view_set(view->log_view,
start_file_seq, start_file_offset,
- log_seq, log_offset);
+ log_seq, log_offset, &reset);
if (ret <= 0) {
/* either corrupted or the file was deleted for
some reason. either way, we can't go forward */
diff -r 064aa8ff69c2 -r a9df50952600 src/lib-index/mail-index-transaction-private.h
--- a/src/lib-index/mail-index-transaction-private.h Sun Jul 01 01:04:57 2007 +0300
+++ b/src/lib-index/mail-index-transaction-private.h Sun Jul 01 01:05:26 2007 +0300
@@ -25,6 +25,8 @@ struct mail_index_transaction {
struct mail_index_transaction_vfuncs v;
struct mail_index_view *view;
+ /* NOTE: If you add anything new, remember to update
+ mail_index_transaction_reset() to reset it. */
ARRAY_DEFINE(appends, struct mail_index_record);
uint32_t first_new_seq, last_new_seq;
@@ -55,10 +57,12 @@ struct mail_index_transaction {
unsigned int sync_transaction:1;
unsigned int hide_transaction:1;
unsigned int no_appends:1;
+ unsigned int external:1;
+
unsigned int appends_nonsorted:1;
- unsigned int external:1;
unsigned int pre_hdr_changed:1;
unsigned int post_hdr_changed:1;
+ unsigned int reset:1;
unsigned int log_updates:1;
};
diff -r 064aa8ff69c2 -r a9df50952600 src/lib-index/mail-index-transaction.c
--- a/src/lib-index/mail-index-transaction.c Sun Jul 01 01:04:57 2007 +0300
+++ b/src/lib-index/mail-index-transaction.c Sun Jul 01 01:05:26 2007 +0300
@@ -77,6 +77,7 @@ void mail_index_transaction_reset(struct
t->appends_nonsorted = FALSE;
t->pre_hdr_changed = FALSE;
t->post_hdr_changed = FALSE;
+ t->reset = FALSE;
t->log_updates = FALSE;
}
@@ -1039,6 +1040,14 @@ void mail_index_update_keywords(struct m
t->log_updates = TRUE;
}
+void mail_index_reset(struct mail_index_transaction *t)
+{
+ mail_index_transaction_reset(t);
+
+ t->reset = TRUE;
+ t->log_updates = TRUE;
+}
+
struct mail_index_transaction_vfuncs trans_vfuncs = {
_mail_index_transaction_commit,
_mail_index_transaction_rollback
diff -r 064aa8ff69c2 -r a9df50952600 src/lib-index/mail-index-view-sync.c
--- a/src/lib-index/mail-index-view-sync.c Sun Jul 01 01:04:57 2007 +0300
+++ b/src/lib-index/mail-index-view-sync.c Sun Jul 01 01:05:26 2007 +0300
@@ -87,27 +87,53 @@ mail_transaction_log_sort_expunges(ARRAY
return 0;
}
-static int view_sync_set_log_view_range(struct mail_index_view *view)
+static int
+view_sync_set_log_view_range(struct mail_index_view *view, bool sync_expunges)
{
const struct mail_index_header *hdr = &view->index->map->hdr;
+ uint32_t start_seq, end_seq;
+ uoff_t start_offset, end_offset;
+ bool reset;
int ret;
- /* the view begins from the first non-synced transaction */
- ret = mail_transaction_log_view_set(view->log_view,
- view->log_file_expunge_seq,
- view->log_file_expunge_offset,
- hdr->log_file_seq,
- hdr->log_file_head_offset);
- if (ret <= 0) {
- if (ret == 0) {
- /* FIXME: use the new index to get needed changes */
+ start_seq = view->log_file_expunge_seq;
+ start_offset = view->log_file_expunge_offset;
+ end_seq = hdr->log_file_seq;
+ end_offset = hdr->log_file_head_offset;
+
+ for (;;) {
+ /* the view begins from the first non-synced transaction */
+ ret = mail_transaction_log_view_set(view->log_view,
+ start_seq, start_offset,
+ end_seq, end_offset,
+ &reset);
+ if (ret <= 0) {
+ if (ret < 0)
+ return -1;
+
+ /* FIXME: use the new index to get needed
+ changes */
mail_index_set_error(view->index,
"Transaction log got desynced for index %s",
view->index->filepath);
view->inconsistent = TRUE;
- }
- return -1;
- }
+ return -1;
+ }
+
+ if (!reset || sync_expunges)
+ break;
+
+ /* we can't do this. sync only up to reset. */
+ mail_transaction_log_view_get_prev_pos(view->log_view,
+ &end_seq, &end_offset);
+ end_seq--; end_offset = (uoff_t)-1;
+ if (end_seq < start_seq) {
+ /* we have only this reset log */
+ mail_transaction_log_view_clear(view->log_view);
+ break;
+ }
+ }
+
return 0;
}
@@ -121,7 +147,7 @@ view_sync_get_expunges(struct mail_index
unsigned int count;
int ret;
- if (view_sync_set_log_view_range(view) < 0)
+ if (view_sync_set_log_view_range(view, TRUE) < 0)
return -1;
/* get a list of expunge transactions. there may be some that we have
@@ -196,6 +222,7 @@ int mail_index_view_sync_begin(struct ma
struct mail_index_view_sync_ctx *ctx;
struct mail_index_map *map;
ARRAY_TYPE(seq_range) expunges = ARRAY_INIT;
+ bool sync_expunges;
i_assert(!view->syncing);
i_assert(view->transactions == 0);
@@ -203,13 +230,14 @@ int mail_index_view_sync_begin(struct ma
if (mail_index_view_lock_head(view) < 0)
return -1;
- if ((flags & MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES) == 0) {
+ sync_expunges = (flags & MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES) == 0;
+ if (sync_expunges) {
/* get list of all expunges first */
if (view_sync_get_expunges(view, &expunges) < 0)
return -1;
}
- if (view_sync_set_log_view_range(view) < 0) {
+ if (view_sync_set_log_view_range(view, sync_expunges) < 0) {
if (array_is_created(&expunges))
array_free(&expunges);
return -1;
@@ -222,7 +250,7 @@ int mail_index_view_sync_begin(struct ma
mail_index_sync_map_init(&ctx->sync_map_ctx, view,
MAIL_INDEX_SYNC_HANDLER_VIEW);
- if ((flags & MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES) == 0) {
+ if (sync_expunges) {
view->sync_new_map = view->index->map;
view->sync_new_map->refcount++;
@@ -590,11 +618,7 @@ void mail_index_view_sync_end(struct mai
#endif
/* set log view to empty range so unneeded memory gets freed */
- (void)mail_transaction_log_view_set(view->log_view,
- view->log_file_head_seq,
- view->log_file_head_offset,
- view->log_file_head_seq,
- view->log_file_head_offset);
+ mail_transaction_log_view_clear(view->log_view);
if (array_is_created(&ctx->expunges))
array_free(&ctx->expunges);
diff -r 064aa8ff69c2 -r a9df50952600 src/lib-index/mail-index-write.c
--- a/src/lib-index/mail-index-write.c Sun Jul 01 01:04:57 2007 +0300
+++ b/src/lib-index/mail-index-write.c Sun Jul 01 01:05:26 2007 +0300
@@ -214,5 +214,5 @@ void mail_index_write(struct mail_index
if (want_rotate &&
hdr->log_file_seq == index->log->head->hdr.file_seq &&
hdr->log_file_tail_offset == hdr->log_file_head_offset)
- (void)mail_transaction_log_rotate(index->log);
-}
+ (void)mail_transaction_log_rotate(index->log, FALSE);
+}
diff -r 064aa8ff69c2 -r a9df50952600 src/lib-index/mail-index.h
--- a/src/lib-index/mail-index.h Sun Jul 01 01:04:57 2007 +0300
+++ b/src/lib-index/mail-index.h Sun Jul 01 01:05:26 2007 +0300
@@ -323,6 +323,9 @@ void mail_index_update_flags_range(struc
uint32_t seq1, uint32_t seq2,
enum modify_type modify_type,
enum mail_flags flags);
+/* Reset the index before committing this transaction. This is usually done
+ only when UIDVALIDITY changes. */
+void mail_index_reset(struct mail_index_transaction *t);
/* Lookup a keyword, returns TRUE if found, FALSE if not. If autocreate is
TRUE, the keyword is automatically created and TRUE is always returned. */
diff -r 064aa8ff69c2 -r a9df50952600 src/lib-index/mail-transaction-log-append.c
--- a/src/lib-index/mail-transaction-log-append.c Sun Jul 01 01:04:57 2007 +0300
+++ b/src/lib-index/mail-transaction-log-append.c Sun Jul 01 01:05:26 2007 +0300
@@ -173,7 +173,8 @@ static void log_append_ext_intro(struct
uint32_t idx;
unsigned int count;
- if (!mail_index_map_get_ext_idx(t->view->map, ext_id, &idx)) {
+ if (t->reset ||
+ !mail_index_map_get_ext_idx(t->view->map, ext_id, &idx)) {
/* new extension */
idx = (uint32_t)-1;
}
@@ -410,6 +411,14 @@ mail_transaction_log_append_locked(struc
index = mail_index_view_get_index(view);
log = index->log;
+ if (t->reset) {
+ /* Reset the whole index, preserving only indexid. Begin by
+ rotating the log. We don't care if we skip some non-synced
+ transactions. */
+ if (mail_transaction_log_rotate(log, TRUE) < 0)
+ return -1;
+ }
+
if (!index->log_locked) {
/* update sync_offset */
if (mail_transaction_log_file_map(log->head,
diff -r 064aa8ff69c2 -r a9df50952600 src/lib-index/mail-transaction-log-file.c
--- a/src/lib-index/mail-transaction-log-file.c Sun Jul 01 01:04:57 2007 +0300
+++ b/src/lib-index/mail-transaction-log-file.c Sun Jul 01 01:05:26 2007 +0300
@@ -429,7 +429,8 @@ mail_transaction_log_file_is_dupe(struct
static int
mail_transaction_log_file_create2(struct mail_transaction_log_file *file,
- int new_fd, struct dotlock **dotlock)
+ int new_fd, bool reset,
+ struct dotlock **dotlock)
{
struct mail_index *index = file->log->index;
struct stat st;
@@ -443,7 +444,9 @@ mail_transaction_log_file_create2(struct
More information about the dovecot-cvs
mailing list