From: Timo Sirainen Date: Fri, 19 Dec 2008 07:37:13 +0000 (+0200) Subject: Maildir: Avoid rename() when source and dest are identical, stat() instead. X-Git-Tag: 1.2.beta1~167 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=42b78957155e3da3f6edae229123c78631d6fef5;p=thirdparty%2Fdovecot%2Fcore.git Maildir: Avoid rename() when source and dest are identical, stat() instead. --HG-- branch : HEAD --- diff --git a/src/lib-storage/index/maildir/maildir-sync-index.c b/src/lib-storage/index/maildir/maildir-sync-index.c index 1a502f74b7..b9cad06c7c 100644 --- a/src/lib-storage/index/maildir/maildir-sync-index.c +++ b/src/lib-storage/index/maildir/maildir-sync-index.c @@ -64,6 +64,7 @@ static int maildir_sync_flags(struct maildir_mailbox *mbox, const char *path, 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 maildir_mailbox *mbox, const char *path, 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)); + 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; } - 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); + if (box->v.sync_notify != NULL) { + box->v.sync_notify(box, ctx->uid, + index_sync_type_convert(sync_type)); } - return -1; + ctx->changed = TRUE; + return 1; } static int maildir_handle_uid_insertion(struct maildir_index_sync_context *ctx,