Mercurial > dovecot > core-2.2
changeset 10674:22354f505277 HEAD
lib-index: Added support for undeleting a deleted index.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 09 Feb 2010 04:08:31 +0200 |
parents | 6552652a9504 |
children | 9cefc944d82a |
files | src/doveadm/doveadm-dump-log.c src/lib-index/mail-index-sync-update.c src/lib-index/mail-index-sync.c src/lib-index/mail-index-transaction-export.c src/lib-index/mail-index-transaction-private.h src/lib-index/mail-index-transaction-update.c src/lib-index/mail-index-transaction.c src/lib-index/mail-index.c src/lib-index/mail-index.h src/lib-index/mail-transaction-log-file.c src/lib-index/mail-transaction-log-private.h src/lib-index/mail-transaction-log.h |
diffstat | 12 files changed, 86 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- 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 @@ -112,6 +112,9 @@ 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); break; @@ -415,6 +418,7 @@ break; } case MAIL_TRANSACTION_INDEX_DELETED: + case MAIL_TRANSACTION_INDEX_UNDELETED: break; default: break;
--- 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,11 +819,12 @@ /* 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, "Unknown transaction record type 0x%x",
--- 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 @@ 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 @@ 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 @@ 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,9 +774,15 @@ 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)) { /* if cache compression fails, we don't really care. @@ -796,6 +806,13 @@ 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 expunge handlers get called. */
--- 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,6 +394,7 @@ 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; @@ -401,6 +402,12 @@ 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 */ mail_transaction_log_append_ext_intros(&ctx); @@ -456,7 +463,7 @@ } 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);
--- 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 @@ 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 @@ #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);
--- 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 @@ 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,9 +1173,18 @@ 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, uint64_t max_modseq, ARRAY_TYPE(seq_range) *seqs)
--- 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 @@ 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)
--- 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 @@ 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)
--- 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 @@ /* 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);
--- 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 @@ file->log = log; file->filepath = i_strdup(path); file->fd = -1; - file->index_deleted_offset = (uoff_t)-1; return file; } @@ -1112,9 +1111,18 @@ 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; } if (file->max_tail_offset == file->sync_offset) { @@ -1139,10 +1147,6 @@ 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);
--- 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 @@ sync_offset is less than this. */ uoff_t saved_tail_sync_offset; - /* if we've seen _INDEX_DELETED transaction in this file, this is the - offset. otherwise (uoff_t)-1 */ - uoff_t index_deleted_offset; + /* if we've seen _INDEX_[UN9DELETED transaction in this file, + this is the offset. otherwise (uoff_t)-1 */ + uoff_t index_deleted_offset, index_undeleted_offset; struct modseq_cache modseq_cache[LOG_FILE_MODSEQ_CACHE_SIZE];
--- a/src/lib-index/mail-transaction-log.h Tue Feb 09 02:04:00 2010 +0200 +++ b/src/lib-index/mail-transaction-log.h Tue Feb 09 04:08:31 2010 +0200 @@ -43,6 +43,7 @@ MAIL_TRANSACTION_MODSEQ_UPDATE = 0x00008000, MAIL_TRANSACTION_EXT_HDR_UPDATE32 = 0x00010000, MAIL_TRANSACTION_INDEX_DELETED = 0x00020000, + MAIL_TRANSACTION_INDEX_UNDELETED = 0x00040000, MAIL_TRANSACTION_TYPE_MASK = 0x000fffff,