Mercurial > dovecot > original-hg > dovecot-1.2
changeset 6886:82420ed23379 HEAD
If doing a lockless forced sync, track the UID we're trying to find. If we
didn't find it, do a locked sync to find out if it's expunged.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 01 Dec 2007 10:39:12 +0200 |
parents | a22b1a72ea89 |
children | 19a6aeeb8f4f |
files | src/lib-storage/index/maildir/maildir-sync.c src/lib-storage/index/maildir/maildir-sync.h src/lib-storage/index/maildir/maildir-uidlist.c src/lib-storage/index/maildir/maildir-util.c |
diffstat | 4 files changed, 56 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/maildir/maildir-sync.c Sat Dec 01 10:31:02 2007 +0200 +++ b/src/lib-storage/index/maildir/maildir-sync.c Sat Dec 01 10:39:12 2007 +0200 @@ -687,9 +687,10 @@ } static int maildir_sync_context(struct maildir_sync_context *ctx, bool forced, - bool *lost_files_r) + uint32_t *find_uid, bool *lost_files_r) { enum maildir_uidlist_sync_flags sync_flags; + enum maildir_uidlist_rec_flag flags; bool new_changed, cur_changed; int ret; @@ -748,14 +749,14 @@ problem rarely happens except under high amount of modifications. */ - if (!cur_changed || forced) { + if (!cur_changed) { ctx->partial = TRUE; sync_flags = MAILDIR_UIDLIST_SYNC_PARTIAL; - if (forced) - sync_flags |= MAILDIR_UIDLIST_SYNC_FORCE; } else { ctx->partial = FALSE; sync_flags = 0; + if (forced) + sync_flags |= MAILDIR_UIDLIST_SYNC_FORCE; if ((ctx->flags & MAILBOX_SYNC_FLAG_FAST) != 0) sync_flags |= MAILDIR_UIDLIST_SYNC_TRYLOCK; } @@ -767,6 +768,8 @@ return ret; } ctx->locked = maildir_uidlist_is_locked(ctx->mbox->uidlist); + if (!ctx->locked) + ctx->partial = TRUE; if (!ctx->mbox->syncing_commit && ctx->locked) { if (maildir_sync_index_begin(ctx->mbox, ctx, @@ -823,18 +826,40 @@ i_assert(maildir_uidlist_is_locked(ctx->mbox->uidlist)); } + if (find_uid != NULL && *find_uid != 0) { + if (maildir_uidlist_lookup(ctx->mbox->uidlist, *find_uid, + &flags) == NULL) { + /* UID is expunged */ + *find_uid = 0; + } else if ((flags & MAILDIR_UIDLIST_REC_FLAG_NONSYNCED) == 0) { + /* we didn't find it, possibly expunged? */ + *find_uid = 0; + } + } + return maildir_uidlist_sync_deinit(&ctx->uidlist_sync_ctx); } -int maildir_storage_sync_force(struct maildir_mailbox *mbox) +int maildir_storage_sync_force(struct maildir_mailbox *mbox, uint32_t uid) { struct maildir_sync_context *ctx; bool lost_files; int ret; - ctx = maildir_sync_context_new(mbox, 0); - ret = maildir_sync_context(ctx, TRUE, &lost_files); + t_push(); + ctx = maildir_sync_context_new(mbox, MAILBOX_SYNC_FLAG_FAST); + ret = maildir_sync_context(ctx, TRUE, &uid, &lost_files); maildir_sync_deinit(ctx); + t_pop(); + + if (uid != 0) { + /* maybe it's expunged. check again. */ + t_push(); + ctx = maildir_sync_context_new(mbox, 0); + ret = maildir_sync_context(ctx, TRUE, NULL, &lost_files); + maildir_sync_deinit(ctx); + t_pop(); + } return ret; } @@ -854,16 +879,18 @@ ioloop_time) { mbox->ibox.sync_last_check = ioloop_time; + t_push(); ctx = maildir_sync_context_new(mbox, flags); - ret = maildir_sync_context(ctx, FALSE, &lost_files); + ret = maildir_sync_context(ctx, FALSE, NULL, &lost_files); maildir_sync_deinit(ctx); + t_pop(); i_assert(!maildir_uidlist_is_locked(mbox->uidlist) || mbox->ibox.keep_locked); if (lost_files) { /* lost some files from new/, see if thery're in cur/ */ - ret = maildir_storage_sync_force(mbox); + ret = maildir_storage_sync_force(mbox, 0); } }
--- a/src/lib-storage/index/maildir/maildir-sync.h Sat Dec 01 10:31:02 2007 +0200 +++ b/src/lib-storage/index/maildir/maildir-sync.h Sat Dec 01 10:39:12 2007 +0200 @@ -22,7 +22,7 @@ struct mailbox_sync_context * maildir_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags); -int maildir_storage_sync_force(struct maildir_mailbox *mbox); +int maildir_storage_sync_force(struct maildir_mailbox *mbox, uint32_t uid); int maildir_sync_index_begin(struct maildir_mailbox *mbox, struct maildir_sync_context *maildir_sync_ctx,
--- a/src/lib-storage/index/maildir/maildir-uidlist.c Sat Dec 01 10:31:02 2007 +0200 +++ b/src/lib-storage/index/maildir/maildir-uidlist.c Sat Dec 01 10:39:12 2007 +0200 @@ -749,7 +749,7 @@ return NULL; /* the uidlist doesn't exist. */ - if (maildir_storage_sync_force(uidlist->mbox) < 0) + if (maildir_storage_sync_force(uidlist->mbox, uid) < 0) return NULL; /* try again */ @@ -1066,24 +1066,35 @@ struct maildir_uidlist_sync_ctx **sync_ctx_r) { struct maildir_uidlist_sync_ctx *ctx; + bool locked; int ret; - if ((sync_flags & (MAILDIR_UIDLIST_SYNC_TRYLOCK | - MAILDIR_UIDLIST_SYNC_FORCE)) == 0) { + if ((sync_flags & MAILDIR_UIDLIST_SYNC_TRYLOCK) == 0) { if ((ret = maildir_uidlist_lock(uidlist)) <= 0) return ret; } else { if ((ret = maildir_uidlist_try_lock(uidlist)) < 0) return -1; - if (ret == 0 && (sync_flags & MAILDIR_UIDLIST_SYNC_FORCE) == 0) - return 0; + if (ret == 0) { + /* couldn't lock it */ + if ((sync_flags & MAILDIR_UIDLIST_SYNC_FORCE) == 0) + return 0; + /* forcing the lock */ + } + } + locked = ret > 0; + + if (!locked) { + if (maildir_uidlist_refresh(uidlist) < 0) + return -1; } *sync_ctx_r = ctx = i_new(struct maildir_uidlist_sync_ctx, 1); ctx->uidlist = uidlist; ctx->sync_flags = sync_flags; - ctx->partial = (sync_flags & MAILDIR_UIDLIST_SYNC_PARTIAL) != 0; - ctx->locked = ret > 0; + ctx->partial = !locked || + (sync_flags & MAILDIR_UIDLIST_SYNC_PARTIAL) != 0; + ctx->locked = locked; ctx->first_unwritten_pos = (unsigned int)-1; ctx->first_nouid_pos = (unsigned int)-1; @@ -1115,8 +1126,6 @@ /* we'll update uidlist directly */ rec = hash_lookup(uidlist->files, filename); - i_assert(rec != NULL || UIDLIST_IS_LOCKED(uidlist)); - if (rec == NULL) { /* doesn't exist in uidlist */ if (!ctx->locked) {
--- a/src/lib-storage/index/maildir/maildir-util.c Sat Dec 01 10:31:02 2007 +0200 +++ b/src/lib-storage/index/maildir/maildir-util.c Sat Dec 01 10:39:12 2007 +0200 @@ -72,7 +72,7 @@ /* file is either renamed or deleted. sync the maildir and see which one. if file appears to be renamed constantly, don't try to open it more than 10 times. */ - if (maildir_storage_sync_force(mbox) < 0) + if (maildir_storage_sync_force(mbox, uid) < 0) return -1; ret = maildir_file_do_try(mbox, uid, callback, context);