dovecot-1.2: Maildir: Avoid rename() when source and dest are id...

dovecot at dovecot.org dovecot at dovecot.org
Fri Dec 19 09:37:17 EET 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/d077e608a2d6
changeset: 8576:d077e608a2d6
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Dec 19 09:37:13 2008 +0200
description:
Maildir: Avoid rename() when source and dest are identical, stat() instead.

diffstat:

1 file changed, 29 insertions(+), 16 deletions(-)
src/lib-storage/index/maildir/maildir-sync-index.c |   45 ++++++++++++--------

diffs (62 lines):

diff -r 52417406a50c -r d077e608a2d6 src/lib-storage/index/maildir/maildir-sync-index.c
--- a/src/lib-storage/index/maildir/maildir-sync-index.c	Fri Dec 19 09:31:39 2008 +0200
+++ b/src/lib-storage/index/maildir/maildir-sync-index.c	Fri Dec 19 09:37:13 2008 +0200
@@ -64,6 +64,7 @@ static int maildir_sync_flags(struct mai
 			      struct maildir_index_sync_context *ctx)
 {
 	struct mailbox *box = &mbox->ibox.box;
+	struct stat st;
 	const char *dir, *fname, *newfname, *newpath;
 	enum mail_index_sync_type sync_type;
 	uint8_t flags8;
@@ -87,22 +88,34 @@ static int maildir_sync_flags(struct mai
 	newfname = maildir_filename_set_flags(ctx->keywords_sync_ctx, fname,
 					      ctx->flags, &ctx->keywords);
 	newpath = t_strconcat(dir, newfname, NULL);
-	if (rename(path, newpath) == 0) {
-		if (box->v.sync_notify != NULL) {
-			box->v.sync_notify(box, ctx->uid,
-					   index_sync_type_convert(sync_type));
-		}
-		ctx->changed = TRUE;
-		return 1;
-	}
-	if (errno == ENOENT)
-		return 0;
-
-	if (!ENOSPACE(errno) && errno != EACCES) {
-		mail_storage_set_critical(box->storage,
-			"rename(%s, %s) failed: %m", path, newpath);
-	}
-	return -1;
+	if (strcmp(path, newpath) == 0) {
+		/* just make sure that the file still exists. avoid rename()
+		   here because it's slow on HFS. */
+		if (stat(path, &st) < 0) {
+			if (errno == ENOENT)
+				return 0;
+			mail_storage_set_critical(box->storage,
+				"stat(%s) failed: %m", path);
+			return -1;
+		}
+	} else {
+		if (rename(path, newpath) < 0) {
+			if (errno == ENOENT)
+				return 0;
+			if (!ENOSPACE(errno) && errno != EACCES) {
+				mail_storage_set_critical(box->storage,
+					"rename(%s, %s) failed: %m",
+					path, newpath);
+			}
+			return -1;
+		}
+	}
+	if (box->v.sync_notify != NULL) {
+		box->v.sync_notify(box, ctx->uid,
+				   index_sync_type_convert(sync_type));
+	}
+	ctx->changed = TRUE;
+	return 1;
 }
 
 static int maildir_handle_uid_insertion(struct maildir_index_sync_context *ctx,


More information about the dovecot-cvs mailing list