dovecot: If doing a lockless forced sync, track the UID we're tr...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Dec 1 10:39:16 EET 2007
details: http://hg.dovecot.org/dovecot/rev/82420ed23379
changeset: 6886:82420ed23379
user: Timo Sirainen <tss at iki.fi>
date: Sat Dec 01 10:39:12 2007 +0200
description:
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.
diffstat:
4 files changed, 56 insertions(+), 20 deletions(-)
src/lib-storage/index/maildir/maildir-sync.c | 45 ++++++++++++++++++-----
src/lib-storage/index/maildir/maildir-sync.h | 2 -
src/lib-storage/index/maildir/maildir-uidlist.c | 27 +++++++++----
src/lib-storage/index/maildir/maildir-util.c | 2 -
diffs (194 lines):
diff -r a22b1a72ea89 -r 82420ed23379 src/lib-storage/index/maildir/maildir-sync.c
--- 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_get_changes(stru
}
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 @@ static int maildir_sync_context(struct m
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 @@ static int maildir_sync_context(struct m
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 @@ static int maildir_sync_context(struct m
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 @@ maildir_storage_sync_init(struct mailbox
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);
}
}
diff -r a22b1a72ea89 -r 82420ed23379 src/lib-storage/index/maildir/maildir-sync.h
--- 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 @@ int maildir_sync_is_synced(struct maildi
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,
diff -r a22b1a72ea89 -r 82420ed23379 src/lib-storage/index/maildir/maildir-uidlist.c
--- 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 @@ maildir_uidlist_lookup(struct maildir_ui
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 @@ int maildir_uidlist_sync_init(struct mai
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 @@ maildir_uidlist_sync_next_partial(struct
/* 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) {
diff -r a22b1a72ea89 -r 82420ed23379 src/lib-storage/index/maildir/maildir-util.c
--- 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 @@ int maildir_file_do(struct maildir_mailb
/* 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);
More information about the dovecot-cvs
mailing list