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