unsigned int initial_hdr_read:1;
unsigned int initial_sync:1;
unsigned int retry_rewind:1;
+ unsigned int locked_refresh:1;
};
struct maildir_uidlist_sync_ctx {
}
uidlist->lock_count++;
+ uidlist->locked_refresh = FALSE;
if (refresh) {
/* make sure we have the latest changes before
if (--uidlist->lock_count > 0)
return;
+ uidlist->locked_refresh = FALSE;
(void)file_dotlock_delete(&uidlist->dotlock);
}
if (ret >= 0) {
uidlist->initial_read = TRUE;
uidlist->initial_hdr_read = TRUE;
+ if (UIDLIST_IS_LOCKED(uidlist))
+ uidlist->locked_refresh = TRUE;
}
return ret;
}
rec->extensions = p_malloc(uidlist->record_pool, buf->used);
memcpy(rec->extensions, buf->data, buf->used);
- uidlist->recreate = TRUE;
+ if (rec->uid != (uint32_t)-1) {
+ /* message already exists in uidlist, need to recreate it */
+ uidlist->recreate = TRUE;
+ }
}
void maildir_uidlist_set_ext(struct maildir_uidlist *uidlist, uint32_t uid,
{
unsigned int min_rewrite_count;
- if (!ctx->uidlist->initial_read)
+ if (!ctx->uidlist->locked_refresh)
return FALSE;
+ if (ctx->uidlist->recreate)
+ return TRUE;
min_rewrite_count =
(ctx->uidlist->read_records_count + ctx->new_files_count) *
{
struct maildir_uidlist *uidlist = ctx->uidlist;
- if (uidlist->recreate ||
- ctx->finish_change_counter != uidlist->change_counter)
- return TRUE;
-
- if (!uidlist->initial_read)
+ if (!uidlist->locked_refresh)
return FALSE;
+ if (ctx->finish_change_counter != uidlist->change_counter)
+ return TRUE;
if (uidlist->fd == -1 || uidlist->version != UIDLIST_VERSION)
return TRUE;
if ((uoff_t)st.st_size != file_size) {
i_warning("%s: file size changed unexpectedly after write",
uidlist->path);
- } else {
+ } else if (uidlist->locked_refresh) {
uidlist->fd_size = st.st_size;
uidlist->last_read_offset = st.st_size;
maildir_uidlist_update_hdr(uidlist, &st);
unsigned int idx;
i_assert(ctx->partial);
+ i_assert(ctx->uidlist->locked_refresh);
rec = hash_table_lookup(ctx->uidlist->files, filename);
i_assert(rec != NULL);
/* mbox=NULL means we're coming from dbox rebuilding code.
the dbox is already locked, so allow uidlist recreation */
i_assert(ctx->locked || !ctx->changed || ctx->uidlist->mbox == NULL);
- if ((ctx->changed || ctx->uidlist->recreate ||
- maildir_uidlist_want_compress(ctx)) &&
+ if ((ctx->changed || maildir_uidlist_want_compress(ctx)) &&
!ctx->failed && (ctx->locked || ctx->uidlist->mbox == NULL)) {
T_BEGIN {
if (maildir_uidlist_sync_update(ctx) < 0)