dovecot-1.1: fdatasync() the new/ and/or cur/ directory after ma...

dovecot at dovecot.org dovecot at dovecot.org
Sun Feb 17 15:14:07 EET 2008


details:   http://hg.dovecot.org/dovecot-1.1/rev/0444707aa95c
changeset: 7267:0444707aa95c
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Feb 17 15:14:46 2008 +0200
description:
fdatasync() the new/ and/or cur/ directory after mails are renamed.

diffstat:

1 file changed, 46 insertions(+), 1 deletion(-)
src/lib-storage/index/maildir/maildir-save.c |   47 +++++++++++++++++++++++++-

diffs (85 lines):

diff -r c1e18e979ac3 -r 0444707aa95c src/lib-storage/index/maildir/maildir-save.c
--- a/src/lib-storage/index/maildir/maildir-save.c	Sun Feb 17 14:38:18 2008 +0200
+++ b/src/lib-storage/index/maildir/maildir-save.c	Sun Feb 17 15:14:46 2008 +0200
@@ -571,6 +571,42 @@ maildir_transaction_unlink_copied_files(
 	ctx->files = pos;
 }
 
+static int fdatasync_path(const char *path)
+{
+	int fd, ret = 0;
+
+	/* Directories need to be opened as read-only.
+	   fsync() doesn't appear to care about it. */
+	fd = open(path, O_RDONLY);
+	if (fd == -1) {
+		i_error("open(%s) failed: %m", path);
+		return -1;
+	}
+	if (fdatasync(fd) < 0) {
+		i_error("fdatasync(%s) failed: %m", path);
+		ret = -1;
+	}
+	(void)close(fd);
+	return ret;
+}
+
+static int maildir_transaction_fsync_dirs(struct maildir_save_context *ctx,
+					  bool new_changed, bool cur_changed)
+{
+	if (ctx->mbox->ibox.fsync_disable)
+		return 0;
+
+	if (new_changed) {
+		if (fdatasync_path(ctx->newdir) < 0)
+			return -1;
+	}
+	if (cur_changed) {
+		if (fdatasync_path(ctx->curdir) < 0)
+			return -1;
+	}
+	return 0;
+}
+
 int maildir_transaction_save_commit_pre(struct maildir_save_context *ctx)
 {
 	struct maildir_transaction_context *t =
@@ -578,7 +614,7 @@ int maildir_transaction_save_commit_pre(
 	struct maildir_filename *mf;
 	uint32_t seq, uid, first_uid, next_uid;
 	enum maildir_uidlist_rec_flag flags;
-	bool newdir, sync_commit = FALSE;
+	bool newdir, new_changed, cur_changed, sync_commit = FALSE;
 	int ret;
 
 	i_assert(ctx->output == NULL);
@@ -661,6 +697,7 @@ int maildir_transaction_save_commit_pre(
 	/* move them into new/ and/or cur/ */
 	ret = 0;
 	ctx->moving = TRUE;
+	new_changed = cur_changed = FALSE;
 	for (mf = ctx->files; mf != NULL; mf = mf->next) {
 		T_BEGIN {
 			const char *dest;
@@ -675,6 +712,10 @@ int maildir_transaction_save_commit_pre(
 			if ((mf->flags & MAILDIR_SAVE_FLAG_HARDLINK) != 0)
 				ret = 0;
 			else {
+				if (newdir)
+					new_changed = TRUE;
+				else
+					cur_changed = TRUE;
 				ret = maildir_file_move(ctx, mf->basename,
 							dest, newdir);
 			}
@@ -683,6 +724,10 @@ int maildir_transaction_save_commit_pre(
 			break;
 	}
 
+	if (ret == 0) {
+		ret = maildir_transaction_fsync_dirs(ctx, new_changed,
+						     cur_changed);
+	}
 	if (ret == 0 && ctx->uidlist_sync_ctx != NULL) {
 		/* everything was moved successfully. update our internal
 		   state. */


More information about the dovecot-cvs mailing list