/* Index has been fsck'd, but mail_index_reset_fscked() hasn't been
called yet. */
bool fscked:1;
+ /* mail_index_open() has created new index files */
+ bool initial_created:1;
+
};
extern struct mail_index_module_register mail_index_module_register;
index->map->hdr.indexid = index->indexid;
}
index->initial_create = FALSE;
+ index->initial_created = TRUE;
}
if (ret >= 0) {
ret = index->map != NULL ? 1 : mail_index_try_open(index);
flags |= MAIL_INDEX_OPEN_FLAG_CREATE;
ret = mail_index_open(index, flags);
i_assert(ret != 0);
- return ret < 0 ? -1 : 0;
+ return ret < 0 ? -1 : (index->initial_created ? 1 : 0);
}
void mail_index_close_file(struct mail_index *index)
{
struct test_mail_cache_ctx ctx;
- test_mail_cache_init(test_mail_index_open(), &ctx);
+ test_mail_cache_init(test_mail_index_open(FALSE), &ctx);
test_assert(mail_cache_purge(ctx.cache, (uint32_t)-1, "test") == 0);
test_mail_cache_deinit(&ctx);
}
test_begin("mail cache fields read-write");
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
mail_cache_register_fields(ctx.cache, &cache_field, 1,
unsafe_data_stack_pool);
test_assert(mail_cache_purge(ctx.cache, (uint32_t)-1, "test") == 0);
i_set_failure_prefix("index2: ");
/* read from cache via 2nd index */
- test_mail_cache_init(test_mail_index_open(), &ctx);
+ test_mail_cache_init(test_mail_index_open(FALSE), &ctx);
cache_view = mail_cache_view_open(ctx.cache, ctx.view);
test_assert(mail_cache_lookup_field(cache_view, str, 1,
int status;
test_begin("mail cache read during purge");
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
test_mail_cache_add_mail(&ctx, ctx.cache_field.idx, "foo1");
/* lock the index for cache purge */
i_set_failure_prefix("index2: ");
/* add to cache via 2nd index */
- test_mail_cache_init(test_mail_index_open(), &ctx);
+ test_mail_cache_init(test_mail_index_open(FALSE), &ctx);
test_mail_cache_add_field(&ctx, 1, ctx.cache_field2.idx, "bar2");
test_mail_cache_deinit(&ctx);
}
int status;
test_begin("mail cache write during purge");
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
test_mail_cache_add_mail(&ctx, ctx.cache_field.idx, "foo1");
/* lock the index for cache purge */
int status;
test_begin("mail cache purge while cache locked");
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
test_mail_cache_add_mail(&ctx, ctx.cache_field.idx, "foo1");
/* lock the cache */
struct mail_index_transaction *trans;
uint32_t seq;
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
mail_index_set_optimization_settings(ctx.index, &optimization_set);
/* Add mails */
struct test_mail_cache_ctx ctx;
struct stat st;
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
mail_index_set_optimization_settings(ctx.index, &optimization_set);
test_mail_cache_add_mail(&ctx, ctx.cache_field.idx, "foo1");
test_mail_cache_add_mail(&ctx, ctx.cache_field.idx, "foo2");
struct test_mail_cache_ctx ctx;
struct stat st;
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
mail_index_set_optimization_settings(ctx.index, &optimization_set);
/* add two mails with some cache field and expunge the first mail */
struct test_mail_cache_ctx ctx;
struct mail_cache_view *cache_view;
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
test_mail_cache_add_mail(&ctx, ctx.cache_field.idx, "foo1");
test_mail_cache_purge();
struct mail_cache_view *cache_view;
const char *temp_cache_path;
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
test_mail_cache_add_mail(&ctx, ctx.cache_field.idx, "foo1");
/* make a copy of the first cache file */
struct mail_index_transaction *trans;
unsigned int i;
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
mail_index_set_optimization_settings(ctx.index, &optimization_set);
/* add two mails with all of the cache fields */
struct test_mail_cache_ctx ctx;
test_begin("mail cache purge already done");
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
test_mail_cache_add_mail(&ctx, ctx.cache_field.idx, "foo1");
test_mail_cache_purge();
struct mail_cache_view *cache_view;
test_begin("mail cache purge bitmask");
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
mail_index_set_optimization_settings(ctx.index, &optimization_set);
ioloop_time = 1000000;
test_mail_cache_add_mail(&ctx, UINT_MAX, NULL);
struct test_mail_cache_ctx ctx;
uint32_t seq;
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
mail_index_set_optimization_settings(ctx.index, &optimization_set);
for (seq = 1; seq <= 100; seq++) {
struct test_mail_cache_ctx ctx;
uint32_t seq;
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
mail_index_set_optimization_settings(ctx.index, &optimization_set);
for (seq = 1; seq <= 100; seq++) {
string_t *str = t_str_new(16);
test_begin("mail cache uncommitted lookups");
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
mail_cache_register_fields(ctx.cache, cache_fields,
N_ELEMENTS(cache_fields),
unsafe_data_stack_pool);
struct mail_cache_transaction_ctx *cache_trans;
string_t *str = t_str_new(16);
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
mail_index_set_optimization_settings(ctx.index, &optimization_set);
/* Add the first cache field. In a chain of cache records each one
string_t *str = t_str_new(16);
test_begin("mail cache record max size (4)");
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
mail_index_set_optimization_settings(ctx.index, &optimization_set);
test_mail_cache_add_mail(&ctx, UINT_MAX, NULL);
test_begin("mail cache add decisions");
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
memcpy(cache_fields, decision_cache_fields, sizeof(cache_fields));
mail_cache_register_fields(ctx.cache, cache_fields, TEST_FIELD_COUNT,
unsafe_data_stack_pool);
unsigned int i;
string_t *str = t_str_new(16);
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
/* create the initial mails and the cache file */
test_mail_cache_add_mail(&ctx, UINT_MAX, NULL);
test_mail_cache_add_mail(&ctx, UINT_MAX, NULL);
test_begin("mail cache add in-memory");
index = mail_index_alloc(NULL, NULL, "(in-memory)");
- test_assert(mail_index_open_or_create(index, MAIL_INDEX_OPEN_FLAG_CREATE) == 0);
+ test_assert(mail_index_open_or_create(index, MAIL_INDEX_OPEN_FLAG_CREATE) == 1);
test_mail_cache_init(index, &ctx);
mail_index_set_optimization_settings(ctx.index, &optimization_set);
cache_view = mail_cache_view_open(ctx.cache, ctx.view);
test_begin("mail cache size corruption");
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
test_mail_cache_add_mail(&ctx, ctx.cache_field.idx, "12345678");
cache_view = mail_cache_view_open(ctx.cache, ctx.view);
struct mail_cache_transaction_ctx *cache_trans;
test_begin("mail cache duplicate fields");
- test_mail_cache_init(test_mail_index_init(), &ctx);
+ test_mail_cache_init(test_mail_index_init(TRUE), &ctx);
mail_cache_register_fields(ctx.cache, cache_fields,
N_ELEMENTS(cache_fields),
unsafe_data_stack_pool);
uint32_t seq, uid;
test_begin("mail_transaction_log_file_get_modseq_next_offset()");
- index = test_mail_index_init();
+ index = test_mail_index_init(TRUE);
view = mail_index_view_open(index);
mail_index_modseq_enable(index);
const char *reason;
test_begin("mail index rotate");
- index = test_mail_index_init();
- index2 = test_mail_index_open();
+ index = test_mail_index_init(TRUE);
+ index2 = test_mail_index_open(FALSE);
view = mail_index_view_open(index);
/* First rotation of the index. The view will point to the old index. */
uint32_t seq, rec_ext_id, rec_ext = 0x12345678;
test_begin("mail index new extension");
- index = test_mail_index_init();
- index2 = test_mail_index_open();
+ index = test_mail_index_init(TRUE);
+ index2 = test_mail_index_open(FALSE);
view = mail_index_view_open(index);
rec_ext_id = mail_index_ext_register(index, "test-rec", 0,
#define TESTDIR_NAME ".dovecot.test"
-static inline struct mail_index *test_mail_index_open(void)
+static inline struct mail_index *test_mail_index_open(bool idx_initial_created)
{
struct mail_index *index;
index = mail_index_alloc(NULL, TESTDIR_NAME, "test.dovecot.index");
- test_assert(mail_index_open_or_create(index, MAIL_INDEX_OPEN_FLAG_CREATE) == 0);
+ test_assert(mail_index_open_or_create(index, MAIL_INDEX_OPEN_FLAG_CREATE) ==
+ (idx_initial_created ? 1 : 0));
return index;
}
-static inline struct mail_index *test_mail_index_init(void)
+static inline struct mail_index *test_mail_index_init(bool idx_initial_created)
{
const char *error;
ioloop_time = 1;
- return test_mail_index_open();
+ return test_mail_index_open(idx_initial_created);
}
static inline void test_mail_index_close(struct mail_index **index)
static struct mail_index *test_mail_index_open(void)
{
struct mail_index *index = mail_index_alloc(NULL, NULL, "test.dovecot.index");
- test_assert(mail_index_open_or_create(index, MAIL_INDEX_OPEN_FLAG_CREATE) == 0);
+ test_assert(mail_index_open_or_create(index, MAIL_INDEX_OPEN_FLAG_CREATE) == 1);
struct mail_index_view *view = mail_index_view_open(index);
struct mail_index_transaction *trans =
struct mailbox_list_iterate_context *iter;
const struct mailbox_info *info;
enum mailbox_list_index_flags flags;
+ enum mailbox_list_iter_flags iter_flags;
const char *patterns[2];
struct mailbox_list_index_node *node;
uint32_t seq;
/* clear EXISTS-flags, so after sync we know what can be expunged */
mailbox_list_index_node_clear_exists(sync_ctx->ilist->mailbox_tree);
+ iter_flags = MAILBOX_LIST_ITER_RAW_LIST |
+ MAILBOX_LIST_ITER_NO_AUTO_BOXES;
+ if (sync_ctx->ilist->index_created)
+ iter_flags |= MAILBOX_LIST_ITER_FORCE_RESYNC;
+
/* don't include autocreated mailboxes in index until they're
actually created. this index may be used by multiple users, so
we also want to ignore ACLs here. */
patterns[0] = "*"; patterns[1] = NULL;
iter = sync_ctx->ilist->module_ctx.super.
iter_init(sync_ctx->list, patterns,
- MAILBOX_LIST_ITER_RAW_LIST |
- MAILBOX_LIST_ITER_NO_AUTO_BOXES);
+ iter_flags);
sync_ctx->syncing_list = TRUE;
while ((info = sync_ctx->ilist->module_ctx.super.iter_next(iter)) != NULL) T_BEGIN {
/* successfully listed everything, expunge any unseen mailboxes */
sync_expunge_nonexistent(sync_ctx, sync_ctx->ilist->mailbox_tree);
+ sync_ctx->ilist->index_created = FALSE;
return 0;
}
const struct mail_storage_settings *set = list->mail_set;
enum mail_index_open_flags index_flags;
unsigned int lock_timeout;
+ int ret;
if (ilist->opened)
return 0;
mail_index_set_fsync_mode(ilist->index, set->parsed_fsync_mode, 0);
mail_index_set_lock_method(ilist->index, set->parsed_lock_method,
lock_timeout);
- if (mail_index_open_or_create(ilist->index, index_flags) < 0) {
+ if ((ret = mail_index_open_or_create(ilist->index, index_flags)) < 0) {
if (mail_index_move_to_memory(ilist->index) < 0) {
/* try opening once more. it should be created
directly into memory now, except if it fails with
}
}
}
+ if (ret == 1)
+ ilist->index_created = TRUE;
ilist->opened = TRUE;
return 0;
}
bool force_resynced:1;
bool force_resync_failed:1;
bool last_refresh_success:1;
+ bool index_created:1;
};
struct mailbox_list_index_iterate_context {