dovecot-2.0-sslstream: lib-index: Added support for undeleting a...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Feb 13 03:00:56 EET 2010
details: http://hg.dovecot.org/dovecot-2.0-sslstream/rev/22354f505277
changeset: 10675:22354f505277
user: Timo Sirainen <tss at iki.fi>
date: Tue Feb 09 04:08:31 2010 +0200
description:
lib-index: Added support for undeleting a deleted index.
diffstat:
12 files changed, 87 insertions(+), 26 deletions(-)
src/doveadm/doveadm-dump-log.c | 4 +++
src/lib-index/mail-index-sync-update.c | 9 ++++---
src/lib-index/mail-index-sync.c | 29 +++++++++++++++++++-----
src/lib-index/mail-index-transaction-export.c | 9 ++++++-
src/lib-index/mail-index-transaction-private.h | 4 ++-
src/lib-index/mail-index-transaction-update.c | 10 ++++++++
src/lib-index/mail-index-transaction.c | 23 ++++++++++++++-----
src/lib-index/mail-index.c | 2 -
src/lib-index/mail-index.h | 2 +
src/lib-index/mail-transaction-log-file.c | 14 +++++++----
src/lib-index/mail-transaction-log-private.h | 6 ++--
src/lib-index/mail-transaction-log.h | 1
diffs (truncated from 322 to 300 lines):
diff -r 6552652a9504 -r 22354f505277 src/doveadm/doveadm-dump-log.c
--- a/src/doveadm/doveadm-dump-log.c Tue Feb 09 02:04:00 2010 +0200
+++ b/src/doveadm/doveadm-dump-log.c Tue Feb 09 04:08:31 2010 +0200
@@ -111,6 +111,9 @@ static const char *log_record_type(unsig
break;
case MAIL_TRANSACTION_INDEX_DELETED:
name = "index-deleted";
+ break;
+ case MAIL_TRANSACTION_INDEX_UNDELETED:
+ name = "index-undeleted";
break;
default:
name = t_strdup_printf("unknown: %x", type);
@@ -415,6 +418,7 @@ static void log_record_print(const struc
break;
}
case MAIL_TRANSACTION_INDEX_DELETED:
+ case MAIL_TRANSACTION_INDEX_UNDELETED:
break;
default:
break;
diff -r 6552652a9504 -r 22354f505277 src/lib-index/mail-index-sync-update.c
--- a/src/lib-index/mail-index-sync-update.c Tue Feb 09 02:04:00 2010 +0200
+++ b/src/lib-index/mail-index-sync-update.c Tue Feb 09 04:08:31 2010 +0200
@@ -819,10 +819,11 @@ int mail_index_sync_record(struct mail_i
/* next sync finishes the deletion */
ctx->view->index->index_delete_requested = TRUE;
} else {
- /* transaction log syncing should have already
- set this */
- i_assert(ctx->view->index->index_deleted);
- }
+ /* transaction log reading handles this */
+ }
+ break;
+ case MAIL_TRANSACTION_INDEX_UNDELETED:
+ ctx->view->index->index_delete_requested = FALSE;
break;
default:
mail_index_sync_set_corrupted(ctx,
diff -r 6552652a9504 -r 22354f505277 src/lib-index/mail-index-sync.c
--- a/src/lib-index/mail-index-sync.c Tue Feb 09 02:04:00 2010 +0200
+++ b/src/lib-index/mail-index-sync.c Tue Feb 09 04:08:31 2010 +0200
@@ -389,6 +389,13 @@ mail_index_sync_begin_init(struct mail_i
return 0;
}
+ if (index->index_deleted) {
+ /* index is already deleted. we can't sync. */
+ if (locked)
+ mail_transaction_log_sync_unlock(index->log);
+ return -1;
+ }
+
if (!locked) {
/* it looks like we have something to sync. lock the file and
check again. */
@@ -482,11 +489,6 @@ int mail_index_sync_begin_to(struct mail
index->syncing = TRUE;
- if (index->index_delete_requested) {
- /* finish this sync by marking the index deleted */
- mail_index_set_deleted(ctx->ext_trans);
- }
-
*ctx_r = ctx;
*view_r = ctx->view;
*trans_r = ctx->ext_trans;
@@ -536,6 +538,8 @@ static bool mail_index_sync_view_have_an
case MAIL_TRANSACTION_FLAG_UPDATE:
case MAIL_TRANSACTION_KEYWORD_UPDATE:
case MAIL_TRANSACTION_KEYWORD_RESET:
+ case MAIL_TRANSACTION_INDEX_DELETED:
+ case MAIL_TRANSACTION_INDEX_UNDELETED:
return TRUE;
default:
break;
@@ -770,8 +774,14 @@ int mail_index_sync_commit(struct mail_i
struct mail_index_sync_ctx *ctx = *_ctx;
struct mail_index *index = ctx->index;
uint32_t next_uid;
- bool want_rotate;
+ bool want_rotate, index_undeleted;
int ret = 0;
+
+ index_undeleted = ctx->ext_trans->index_undeleted;
+ if (index->index_delete_requested && !index_undeleted) {
+ /* finish this sync by marking the index deleted */
+ mail_index_set_deleted(ctx->ext_trans);
+ }
mail_index_sync_update_mailbox_offset(ctx);
if (mail_cache_need_compress(index->cache)) {
@@ -795,6 +805,13 @@ int mail_index_sync_commit(struct mail_i
mail_index_sync_end(&ctx);
return -1;
}
+
+ if (index_undeleted) {
+ index->index_deleted = FALSE;
+ index->index_delete_requested = FALSE;
+ }
+ if (index->index_delete_requested)
+ index->index_deleted = TRUE;
/* refresh the mapping with newly committed external transactions
and the synced expunges. sync using file handler here so that the
diff -r 6552652a9504 -r 22354f505277 src/lib-index/mail-index-transaction-export.c
--- a/src/lib-index/mail-index-transaction-export.c Tue Feb 09 02:04:00 2010 +0200
+++ b/src/lib-index/mail-index-transaction-export.c Tue Feb 09 04:08:31 2010 +0200
@@ -394,12 +394,19 @@ void mail_index_transaction_export(struc
void mail_index_transaction_export(struct mail_index_transaction *t,
struct mail_transaction_log_append_ctx *append_ctx)
{
+ static uint8_t null4[4] = { 0, 0, 0, 0 };
enum mail_index_sync_type change_mask = 0;
struct mail_index_export_context ctx;
memset(&ctx, 0, sizeof(ctx));
ctx.trans = t;
ctx.append_ctx = append_ctx;
+
+ if (t->index_undeleted) {
+ i_assert(!t->index_deleted);
+ mail_transaction_log_append_add(ctx.append_ctx,
+ MAIL_TRANSACTION_INDEX_UNDELETED, &null4, 4);
+ }
/* send all extension introductions and resizes before appends
to avoid resize overhead as much as possible */
@@ -456,7 +463,7 @@ void mail_index_transaction_export(struc
}
if (t->index_deleted) {
- static uint8_t null4[4] = { 0, 0, 0, 0 };
+ i_assert(!t->index_undeleted);
mail_transaction_log_append_add(ctx.append_ctx,
MAIL_TRANSACTION_INDEX_DELETED,
&null4, 4);
diff -r 6552652a9504 -r 22354f505277 src/lib-index/mail-index-transaction-private.h
--- a/src/lib-index/mail-index-transaction-private.h Tue Feb 09 02:04:00 2010 +0200
+++ b/src/lib-index/mail-index-transaction-private.h Tue Feb 09 04:08:31 2010 +0200
@@ -86,6 +86,7 @@ struct mail_index_transaction {
unsigned int post_hdr_changed:1;
unsigned int reset:1;
unsigned int index_deleted:1;
+ unsigned int index_undeleted:1;
/* non-extension updates. flag updates don't change this because
they may be added and removed, so be sure to check that the updates
array is non-empty also. */
@@ -96,7 +97,8 @@ struct mail_index_transaction {
#define MAIL_INDEX_TRANSACTION_HAS_CHANGES(t) \
((t)->log_updates || (t)->log_ext_updates || \
- (array_is_created(&(t)->updates) && array_count(&(t)->updates) > 0))
+ (array_is_created(&(t)->updates) && array_count(&(t)->updates) > 0) || \
+ (t)->index_deleted || (t)->index_undeleted)
extern void (*hook_mail_index_transaction_created)
(struct mail_index_transaction *t);
diff -r 6552652a9504 -r 22354f505277 src/lib-index/mail-index-transaction-update.c
--- a/src/lib-index/mail-index-transaction-update.c Tue Feb 09 02:04:00 2010 +0200
+++ b/src/lib-index/mail-index-transaction-update.c Tue Feb 09 04:08:31 2010 +0200
@@ -98,6 +98,7 @@ void mail_index_transaction_reset_v(stru
t->post_hdr_changed = FALSE;
t->reset = FALSE;
t->index_deleted = FALSE;
+ t->index_undeleted = FALSE;
t->log_updates = FALSE;
t->log_ext_updates = FALSE;
}
@@ -1172,7 +1173,16 @@ void mail_index_reset(struct mail_index_
void mail_index_set_deleted(struct mail_index_transaction *t)
{
+ i_assert(!t->index_undeleted);
+
t->index_deleted = TRUE;
+}
+
+void mail_index_set_undeleted(struct mail_index_transaction *t)
+{
+ i_assert(!t->index_deleted);
+
+ t->index_undeleted = TRUE;
}
void mail_index_transaction_set_max_modseq(struct mail_index_transaction *t,
diff -r 6552652a9504 -r 22354f505277 src/lib-index/mail-index-transaction.c
--- a/src/lib-index/mail-index-transaction.c Tue Feb 09 02:04:00 2010 +0200
+++ b/src/lib-index/mail-index-transaction.c Tue Feb 09 04:08:31 2010 +0200
@@ -208,20 +208,33 @@ int mail_index_transaction_commit_full(s
struct mail_index_transaction_commit_result *result_r)
{
struct mail_index_transaction *t = *_t;
+ struct mail_index *index = t->view->index;
+ bool index_undeleted = t->index_undeleted;
if (mail_index_view_is_inconsistent(t->view)) {
mail_index_transaction_rollback(_t);
return -1;
}
- if (t->view->index->index_deleted) {
- /* no further changes allowed */
- mail_index_transaction_rollback(_t);
- return -1;
+ if (!index_undeleted) {
+ if (t->view->index->index_deleted ||
+ (t->view->index->index_delete_requested &&
+ !t->view->index->syncing)) {
+ /* no further changes allowed */
+ mail_index_transaction_rollback(_t);
+ return -1;
+ }
}
*_t = NULL;
memset(result_r, 0, sizeof(*result_r));
- return t->v.commit(t, result_r);
+ if (t->v.commit(t, result_r) < 0)
+ return -1;
+
+ if (index_undeleted) {
+ index->index_deleted = FALSE;
+ index->index_delete_requested = FALSE;
+ }
+ return 0;
}
void mail_index_transaction_rollback(struct mail_index_transaction **_t)
diff -r 6552652a9504 -r 22354f505277 src/lib-index/mail-index.c
--- a/src/lib-index/mail-index.c Tue Feb 09 02:04:00 2010 +0200
+++ b/src/lib-index/mail-index.c Tue Feb 09 04:08:31 2010 +0200
@@ -748,7 +748,7 @@ void mail_index_mark_corrupted(struct ma
bool mail_index_is_deleted(struct mail_index *index)
{
- return index->index_deleted;
+ return index->index_delete_requested || index->index_deleted;
}
void mail_index_fchown(struct mail_index *index, int fd, const char *path)
diff -r 6552652a9504 -r 22354f505277 src/lib-index/mail-index.h
--- a/src/lib-index/mail-index.h Tue Feb 09 02:04:00 2010 +0200
+++ b/src/lib-index/mail-index.h Tue Feb 09 04:08:31 2010 +0200
@@ -449,6 +449,8 @@ void mail_index_reset(struct mail_index_
/* Mark index deleted. No further changes will be possible after the
transaction has been committed. */
void mail_index_set_deleted(struct mail_index_transaction *t);
+/* Mark a deleted index as undeleted. Afterwards index can be changed again. */
+void mail_index_set_undeleted(struct mail_index_transaction *t);
/* Returns TRUE if index has been set deleted. This gets set only after
index has been opened/refreshed and the transaction has been seen. */
bool mail_index_is_deleted(struct mail_index *index);
diff -r 6552652a9504 -r 22354f505277 src/lib-index/mail-transaction-log-file.c
--- a/src/lib-index/mail-transaction-log-file.c Tue Feb 09 02:04:00 2010 +0200
+++ b/src/lib-index/mail-transaction-log-file.c Tue Feb 09 04:08:31 2010 +0200
@@ -72,7 +72,6 @@ mail_transaction_log_file_alloc(struct m
file->log = log;
file->filepath = i_strdup(path);
file->fd = -1;
- file->index_deleted_offset = (uoff_t)-1;
return file;
}
@@ -1112,8 +1111,17 @@ log_file_track_sync(struct mail_transact
return ret < 0 ? -1 : 0;
break;
case MAIL_TRANSACTION_INDEX_DELETED:
+ if (file->sync_offset < file->index_undeleted_offset)
+ break;
file->log->index->index_deleted = TRUE;
file->index_deleted_offset = file->sync_offset + trans_size;
+ break;
+ case MAIL_TRANSACTION_INDEX_UNDELETED:
+ if (file->sync_offset < file->index_deleted_offset)
+ break;
+ file->log->index->index_deleted = FALSE;
+ file->log->index->index_delete_requested = FALSE;
+ file->index_undeleted_offset = file->sync_offset + trans_size;
break;
}
@@ -1139,10 +1147,6 @@ mail_transaction_log_file_sync(struct ma
data = buffer_get_data(file->buffer, &size);
while (file->sync_offset - file->buffer_offset + sizeof(*hdr) <= size) {
- if (unlikely(file->index_deleted_offset == file->sync_offset)) {
- /* ignore everything that comes after _INDEX_DELETED */
- break;
- }
hdr = CONST_PTR_OFFSET(data, file->sync_offset -
file->buffer_offset);
trans_size = mail_index_offset_to_uint32(hdr->size);
diff -r 6552652a9504 -r 22354f505277 src/lib-index/mail-transaction-log-private.h
--- a/src/lib-index/mail-transaction-log-private.h Tue Feb 09 02:04:00 2010 +0200
+++ b/src/lib-index/mail-transaction-log-private.h Tue Feb 09 04:08:31 2010 +0200
@@ -65,9 +65,9 @@ struct mail_transaction_log_file {
sync_offset is less than this. */
More information about the dovecot-cvs
mailing list