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