dovecot-2.0: sdbox: Commit expunges to index first before unlink...

dovecot at dovecot.org dovecot at dovecot.org
Tue Apr 12 18:38:55 EEST 2011


details:   http://hg.dovecot.org/dovecot-2.0/rev/edf79127fccd
changeset: 12736:edf79127fccd
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Apr 12 18:38:00 2011 +0300
description:
sdbox: Commit expunges to index first before unlinking the files.

diffstat:

 src/lib-storage/index/dbox-common/dbox-file.c  |   2 -
 src/lib-storage/index/dbox-single/sdbox-sync.c |  76 ++++++++++++++-----------
 src/lib-storage/index/dbox-single/sdbox-sync.h |   1 +
 3 files changed, 44 insertions(+), 35 deletions(-)

diffs (150 lines):

diff -r 2269cea521b6 -r edf79127fccd src/lib-storage/index/dbox-common/dbox-file.c
--- a/src/lib-storage/index/dbox-common/dbox-file.c	Tue Apr 12 17:55:26 2011 +0300
+++ b/src/lib-storage/index/dbox-common/dbox-file.c	Tue Apr 12 18:38:00 2011 +0300
@@ -744,8 +744,6 @@
 		}
 		if (file->alt_path == NULL || alt) {
 			/* not found */
-			i_warning("dbox: File unexpectedly lost: %s",
-				  file->primary_path);
 			return 0;
 		}
 
diff -r 2269cea521b6 -r edf79127fccd src/lib-storage/index/dbox-single/sdbox-sync.c
--- a/src/lib-storage/index/dbox-single/sdbox-sync.c	Tue Apr 12 17:55:26 2011 +0300
+++ b/src/lib-storage/index/dbox-single/sdbox-sync.c	Tue Apr 12 18:38:00 2011 +0300
@@ -23,50 +23,26 @@
 	}
 }
 
-static void dbox_sync_file_expunge(struct sdbox_sync_context *ctx,
-				   struct dbox_file *file, uint32_t seq)
-{
-	struct sdbox_file *sfile = (struct sdbox_file *)file;
-	struct mailbox *box = &ctx->mbox->box;
-	int ret;
-
-	if (mail_index_transaction_is_expunged(ctx->trans, seq)) {
-		/* already expunged within this transaction */
-		return;
-	}
-
-	if (file->storage->attachment_dir != NULL)
-		ret = sdbox_file_unlink_with_attachments(sfile);
-	else
-		ret = dbox_file_unlink(file);
-	if (ret < 0) {
-		/* some non-ENOENT error trying to unlink the file */
-		return;
-	}
-
-	/* file was either unlinked by us or someone else */
-	mail_index_expunge(ctx->trans, seq);
-	if (box->v.sync_notify != NULL)
-		box->v.sync_notify(box, sfile->uid, MAILBOX_SYNC_TYPE_EXPUNGE);
-}
-
 static void sdbox_sync_file(struct sdbox_sync_context *ctx,
 			    uint32_t seq, uint32_t uid,
 			    enum sdbox_sync_entry_type type)
 {
 	struct dbox_file *file;
 
-	file = sdbox_file_init(ctx->mbox, uid);
 	switch (type) {
 	case SDBOX_SYNC_ENTRY_TYPE_EXPUNGE:
-		dbox_sync_file_expunge(ctx, file, seq);
+		if (!mail_index_transaction_is_expunged(ctx->trans, seq)) {
+			mail_index_expunge(ctx->trans, seq);
+			array_append(&ctx->expunged_uids, &uid, 1);
+		}
 		break;
 	case SDBOX_SYNC_ENTRY_TYPE_MOVE_FROM_ALT:
 	case SDBOX_SYNC_ENTRY_TYPE_MOVE_TO_ALT:
+		file = sdbox_file_init(ctx->mbox, uid);
 		dbox_sync_file_move_if_needed(file, type);
+		dbox_file_unref(&file);
 		break;
 	}
-	dbox_file_unref(&file);
 }
 
 static void sdbox_sync_add(struct sdbox_sync_context *ctx,
@@ -128,10 +104,40 @@
 
 	while (mail_index_sync_next(ctx->index_sync_ctx, &sync_rec))
 		sdbox_sync_add(ctx, &sync_rec);
+	return 1;
+}
 
-	if (box->v.sync_notify != NULL)
-		box->v.sync_notify(box, 0, 0);
-	return 1;
+static void dbox_sync_file_expunge(struct sdbox_sync_context *ctx,
+				   uint32_t uid)
+{
+	struct mailbox *box = &ctx->mbox->box;
+	struct dbox_file *file;
+	struct sdbox_file *sfile;
+	int ret;
+
+	file = sdbox_file_init(ctx->mbox, uid);
+	sfile = (struct sdbox_file *)file;
+	if (file->storage->attachment_dir != NULL)
+		ret = sdbox_file_unlink_with_attachments(sfile);
+	else
+		ret = dbox_file_unlink(file);
+
+	/* do sync_notify only when the file was unlinked by us */
+	if (ret > 0 && box->v.sync_notify != NULL)
+		box->v.sync_notify(box, uid, MAILBOX_SYNC_TYPE_EXPUNGE);
+	dbox_file_unref(&file);
+}
+
+static void dbox_sync_expunge_files(struct sdbox_sync_context *ctx)
+{
+	const uint32_t *uidp;
+
+	/* NOTE: Index is no longer locked. Multiple processes may be unlinking
+	   the files at the same time. */
+	array_foreach(&ctx->expunged_uids, uidp)
+		dbox_sync_file_expunge(ctx, *uidp);
+	if (ctx->mbox->box.v.sync_notify != NULL)
+		ctx->mbox->box.v.sync_notify(&ctx->mbox->box, 0, 0);
 }
 
 static int
@@ -170,6 +176,7 @@
 	ctx = i_new(struct sdbox_sync_context, 1);
 	ctx->mbox = mbox;
 	ctx->flags = flags;
+	i_array_init(&ctx->expunged_uids, 32);
 
 	sync_flags = index_storage_get_sync_flags(&mbox->box);
 	if (!rebuild && (flags & SDBOX_SYNC_FLAG_FORCE) == 0)
@@ -238,11 +245,14 @@
 		if (mail_index_sync_commit(&ctx->index_sync_ctx) < 0) {
 			mail_storage_set_index_error(&ctx->mbox->box);
 			ret = -1;
+		} else {
+			dbox_sync_expunge_files(ctx);
 		}
 	} else {
 		mail_index_sync_rollback(&ctx->index_sync_ctx);
 	}
 
+	array_free(&ctx->expunged_uids);
 	i_free(ctx);
 	return ret;
 }
diff -r 2269cea521b6 -r edf79127fccd src/lib-storage/index/dbox-single/sdbox-sync.h
--- a/src/lib-storage/index/dbox-single/sdbox-sync.h	Tue Apr 12 17:55:26 2011 +0300
+++ b/src/lib-storage/index/dbox-single/sdbox-sync.h	Tue Apr 12 18:38:00 2011 +0300
@@ -22,6 +22,7 @@
 	struct mail_index_view *sync_view;
 	struct mail_index_transaction *trans;
 	enum sdbox_sync_flags flags;
+	ARRAY_TYPE(uint32_t) expunged_uids;
 };
 
 int sdbox_sync_begin(struct sdbox_mailbox *mbox, enum sdbox_sync_flags flags,


More information about the dovecot-cvs mailing list