[dovecot-cvs] dovecot/src/lib-storage/index/dbox dbox-save.c, 1.16, 1.17 dbox-sync.c, 1.19, 1.20 dbox-uidlist.c, 1.34, 1.35
cras at dovecot.org
cras at dovecot.org
Sun Jul 23 18:38:01 EEST 2006
Update of /var/lib/cvs/dovecot/src/lib-storage/index/dbox
In directory talvi:/tmp/cvs-serv10616
Modified Files:
dbox-save.c dbox-sync.c dbox-uidlist.c
Log Message:
Fixes for pop3_lock_session=yes. Wasn't as easy as I thought. :)
Index: dbox-save.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/dbox/dbox-save.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- dbox-save.c 28 Jun 2006 13:10:50 -0000 1.16
+++ dbox-save.c 23 Jul 2006 15:37:56 -0000 1.17
@@ -326,19 +326,7 @@
i_assert(ctx->finished);
- /* we want the index file to be locked from here until the appends
- have been written to transaction log. this is so that the
- transaction log gets locked before uidlist, not after */
- if (mail_index_sync_begin(ctx->mbox->ibox.index, &ctx->index_sync_ctx,
- &view, (uint32_t)-1, (uoff_t)-1,
- FALSE, FALSE) < 0) {
- ctx->failed = TRUE;
- dbox_transaction_save_rollback(ctx);
- return -1;
- }
-
- /* uidlist gets locked here. do it after starting index syncing to
- avoid deadlocks */
+ /* uidlist locking is done before index locking. */
if (dbox_uidlist_append_get_first_uid(ctx->append_ctx,
&uid, &old_mtime) < 0) {
ctx->failed = TRUE;
@@ -370,6 +358,15 @@
}
}
+ /* lock index lock before dropping uidlist lock in _append_commit() */
+ if (mail_index_sync_begin(ctx->mbox->ibox.index, &ctx->index_sync_ctx,
+ &view, (uint32_t)-1, (uoff_t)-1,
+ FALSE, FALSE) < 0) {
+ ctx->failed = TRUE;
+ dbox_transaction_save_rollback(ctx);
+ return -1;
+ }
+
if (dbox_uidlist_append_commit(ctx->append_ctx, &new_mtime) < 0) {
mail_index_sync_rollback(&ctx->index_sync_ctx);
i_free(ctx);
Index: dbox-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/dbox/dbox-sync.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- dbox-sync.c 28 Jun 2006 13:10:50 -0000 1.19
+++ dbox-sync.c 23 Jul 2006 15:37:56 -0000 1.20
@@ -451,102 +451,139 @@
return ret;
}
-int dbox_sync(struct dbox_mailbox *mbox, bool force)
+static int dbox_sync_init(struct dbox_mailbox *mbox,
+ struct dbox_sync_context *ctx, bool *force)
{
- struct dbox_sync_context ctx;
const struct mail_index_header *hdr;
- uint32_t seq, uid_validity, next_uid;
- uoff_t offset;
time_t mtime;
int ret;
- memset(&ctx, 0, sizeof(ctx));
- ctx.mbox = mbox;
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->mbox = mbox;
- /* always start index syncing before uidlist, so we don't get
- deadlocks */
- ret = mail_index_sync_begin(mbox->ibox.index, &ctx.index_sync_ctx,
- &ctx.sync_view, (uint32_t)-1, (uoff_t)-1,
+ /* uidlist locking is done before index locking. */
+ if (dbox_uidlist_sync_init(mbox->uidlist, &ctx->uidlist_sync_ctx,
+ &mtime) < 0)
+ return -1;
+
+ ret = mail_index_sync_begin(mbox->ibox.index, &ctx->index_sync_ctx,
+ &ctx->sync_view, (uint32_t)-1, (uoff_t)-1,
!mbox->ibox.keep_recent, TRUE);
if (ret <= 0) {
if (ret < 0)
mail_storage_set_index_error(&mbox->ibox);
+ dbox_uidlist_sync_rollback(ctx->uidlist_sync_ctx);
return ret;
}
- if (dbox_uidlist_sync_init(mbox->uidlist, &ctx.uidlist_sync_ctx,
- &mtime) < 0) {
- mail_index_sync_rollback(&ctx.index_sync_ctx);
- return -1;
- }
- ctx.trans = mail_index_transaction_begin(ctx.sync_view, FALSE, TRUE);
+ ctx->trans = mail_index_transaction_begin(ctx->sync_view, FALSE, TRUE);
- hdr = mail_index_get_header(ctx.sync_view);
+ hdr = mail_index_get_header(ctx->sync_view);
if ((uint32_t)mtime != hdr->sync_stamp) {
/* indexes aren't synced. we'll do a full sync. */
- force = TRUE;
+ *force = TRUE;
}
+ return 1;
+}
+
+static int dbox_sync_finish(struct dbox_sync_context *ctx, bool force)
+{
+ const struct mail_index_header *hdr;
+ uint32_t seq, uid_validity, next_uid;
+ uoff_t offset;
+ time_t mtime;
+ int ret;
if (force)
- ret = dbox_sync_full(&ctx);
+ ret = dbox_sync_full(ctx);
else
- ret = dbox_sync_index(&ctx);
+ ret = dbox_sync_index(ctx);
if (ret < 0) {
- mail_index_sync_rollback(&ctx.index_sync_ctx);
- dbox_uidlist_sync_rollback(ctx.uidlist_sync_ctx);
+ mail_index_sync_rollback(&ctx->index_sync_ctx);
+ dbox_uidlist_sync_rollback(ctx->uidlist_sync_ctx);
return -1;
}
- uid_validity = dbox_uidlist_sync_get_uid_validity(ctx.uidlist_sync_ctx);
- next_uid = dbox_uidlist_sync_get_next_uid(ctx.uidlist_sync_ctx);
+ uid_validity = dbox_uidlist_sync_get_uid_validity(ctx->uidlist_sync_ctx);
+ next_uid = dbox_uidlist_sync_get_next_uid(ctx->uidlist_sync_ctx);
- hdr = mail_index_get_header(ctx.sync_view);
+ hdr = mail_index_get_header(ctx->sync_view);
if (hdr->uid_validity != uid_validity) {
- mail_index_update_header(ctx.trans,
+ mail_index_update_header(ctx->trans,
offsetof(struct mail_index_header, uid_validity),
&uid_validity, sizeof(uid_validity), TRUE);
}
if (hdr->next_uid != next_uid) {
i_assert(next_uid > hdr->next_uid ||
hdr->uid_validity != uid_validity);
- mail_index_update_header(ctx.trans,
+ mail_index_update_header(ctx->trans,
offsetof(struct mail_index_header, next_uid),
&next_uid, sizeof(next_uid), FALSE);
}
- if (dbox_uidlist_sync_commit(ctx.uidlist_sync_ctx, &mtime) < 0) {
- mail_index_sync_rollback(&ctx.index_sync_ctx);
+ if (dbox_uidlist_sync_commit(ctx->uidlist_sync_ctx, &mtime) < 0) {
+ mail_index_sync_rollback(&ctx->index_sync_ctx);
return -1;
}
if ((uint32_t)mtime != hdr->sync_stamp) {
uint32_t sync_stamp = mtime;
- mail_index_update_header(ctx.trans,
+ mail_index_update_header(ctx->trans,
offsetof(struct mail_index_header, sync_stamp),
&sync_stamp, sizeof(sync_stamp), TRUE);
}
- if (mail_index_transaction_commit(&ctx.trans, &seq, &offset) < 0) {
- mail_storage_set_index_error(&mbox->ibox);
- mail_index_sync_rollback(&ctx.index_sync_ctx);
+ if (mail_index_transaction_commit(&ctx->trans, &seq, &offset) < 0) {
+ mail_storage_set_index_error(&ctx->mbox->ibox);
+ mail_index_sync_rollback(&ctx->index_sync_ctx);
return -1;
}
if (force) {
- mail_index_sync_rollback(&ctx.index_sync_ctx);
- /* now that indexes are ok, sync changes from the index */
- return dbox_sync(mbox, FALSE);
+ mail_index_sync_rollback(&ctx->index_sync_ctx);
} else {
- if (mail_index_sync_commit(&ctx.index_sync_ctx) < 0) {
- mail_storage_set_index_error(&mbox->ibox);
+ if (mail_index_sync_commit(&ctx->index_sync_ctx) < 0) {
+ mail_storage_set_index_error(&ctx->mbox->ibox);
return -1;
}
}
return 0;
}
+int dbox_sync(struct dbox_mailbox *mbox, bool force)
+{
+ struct dbox_sync_context ctx;
+ int ret;
+
+ if ((ret = dbox_sync_init(mbox, &ctx, &force)) <= 0)
+ return ret;
+
+ if ((ret = dbox_sync_finish(&ctx, force)) < 0)
+ return ret;
+
+ if (force) {
+ /* now that indexes are ok, sync changes from the index */
+ force = FALSE;
+ if ((ret = dbox_sync_init(mbox, &ctx, &force)) <= 0)
+ return ret;
+
+ if (force) {
+ mail_storage_set_critical(STORAGE(mbox->storage),
+ "dbox_sync_full(%s) didn't work",
+ mbox->path);
+
+ mail_index_sync_rollback(&ctx.index_sync_ctx);
+ dbox_uidlist_sync_rollback(ctx.uidlist_sync_ctx);
+ return -1;
+ }
+ return dbox_sync_finish(&ctx, FALSE);
+ } else {
+ return 0;
+ }
+}
+
struct mailbox_sync_context *
dbox_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
{
Index: dbox-uidlist.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/dbox/dbox-uidlist.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -d -r1.34 -r1.35
--- dbox-uidlist.c 23 Jul 2006 14:20:59 -0000 1.34
+++ dbox-uidlist.c 23 Jul 2006 15:37:56 -0000 1.35
@@ -105,6 +105,8 @@
MEMBER(use_excl_lock) FALSE
};
+static int dbox_uidlist_full_rewrite(struct dbox_uidlist *uidlist);
+
struct dbox_uidlist *dbox_uidlist_init(struct dbox_mailbox *mbox)
{
struct dbox_uidlist *uidlist;
@@ -334,6 +336,11 @@
struct stat st;
int ret;
+ if (uidlist->lock_count > 0 && uidlist->need_full_rewrite) {
+ i_assert(uidlist->mbox->ibox.keep_locked);
+ return 1;
+ }
+
if (uidlist->fd != -1) {
if (stat(uidlist->path, &st) < 0) {
if (errno != ENOENT) {
@@ -475,6 +482,14 @@
return;
}
+ if (uidlist->need_full_rewrite) {
+ i_assert(uidlist->mbox->ibox.keep_locked);
+
+ (void)dbox_uidlist_full_rewrite(uidlist);
+ if (uidlist->lock_fd == -1)
+ return;
+ }
+
(void)file_dotlock_delete(&uidlist->dotlock);
uidlist->lock_fd = -1;
}
@@ -555,6 +570,12 @@
i_assert(uidlist->lock_fd != -1);
+ if (uidlist->lock_count > 1) {
+ i_assert(uidlist->mbox->ibox.keep_locked);
+ uidlist->need_full_rewrite = TRUE;
+ return 0;
+ }
+
output = o_stream_create_file(uidlist->lock_fd, default_pool, 0, FALSE);
t_push();
@@ -645,6 +666,7 @@
/* now, finish the uidlist update by renaming the lock file to
uidlist */
uidlist->lock_fd = -1;
+ uidlist->lock_count--;
if (file_dotlock_replace(&uidlist->dotlock, 0) < 0)
return -1;
More information about the dovecot-cvs
mailing list