[dovecot-cvs] dovecot/src/lib-storage/index/maildir maildir-save.c, 1.70.2.3, 1.70.2.4

tss at dovecot.org tss at dovecot.org
Thu Dec 28 16:07:18 UTC 2006


Update of /var/lib/cvs/dovecot/src/lib-storage/index/maildir
In directory talvi:/tmp/cvs-serv31781

Modified Files:
      Tag: branch_1_0
	maildir-save.c 
Log Message:
Use rename() instead of link() + unlink() when moving a mail from tmp/ to new/.


Index: maildir-save.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/maildir/maildir-save.c,v
retrieving revision 1.70.2.3
retrieving revision 1.70.2.4
diff -u -d -r1.70.2.3 -r1.70.2.4
--- maildir-save.c	7 Nov 2006 21:22:06 -0000	1.70.2.3
+++ maildir-save.c	28 Dec 2006 16:07:15 -0000	1.70.2.4
@@ -58,6 +58,7 @@
 			     const char *tmpname, const char *destname,
 			     bool newdir)
 {
+	struct mail_storage *storage = STORAGE(ctx->mbox->storage);
 	const char *tmp_path, *new_path;
 	int ret;
 
@@ -72,23 +73,29 @@
 		t_strconcat(ctx->newdir, "/", destname, NULL) :
 		t_strconcat(ctx->curdir, "/", destname, NULL);
 
-	if (link(tmp_path, new_path) == 0)
+	/* maildir spec says we should use link() + unlink() here. however
+	   since our filename is guaranteed to be unique, rename() works just
+	   as well, except faster. even if the filename wasn't unique, the
+	   problem could still happen if the file was already moved from
+	   new/ to cur/, so link() doesn't really provide any safety anyway.
+
+	   Besides the small temporary performance benefits, this rename() is
+	   almost required with OSX's HFS+ filesystem, since it implements
+	   hard links in a pretty ugly way, which makes the performance crawl
+	   when a lot of hard links are used. */
+	if (rename(tmp_path, new_path) == 0)
 		ret = 0;
 	else {
 		ret = -1;
 		if (ENOSPACE(errno)) {
-			mail_storage_set_error(STORAGE(ctx->mbox->storage),
+			mail_storage_set_error(storage,
 					       "Not enough disk space");
 		} else {
-			mail_storage_set_critical(STORAGE(ctx->mbox->storage),
-				"link(%s, %s) failed: %m", tmp_path, new_path);
+			mail_storage_set_critical(storage,
+				"rename(%s, %s) failed: %m",
+				tmp_path, new_path);
 		}
 	}
-
-	if (unlink(tmp_path) < 0 && errno != ENOENT) {
-		mail_storage_set_critical(STORAGE(ctx->mbox->storage),
-			"unlink(%s) failed: %m", tmp_path);
-	}
 	t_pop();
 	return ret;
 }



More information about the dovecot-cvs mailing list