From: Junio C Hamano <gitster@pobox.com>
To: Michael Haggerty <mhagger@alum.mit.edu>
Cc: git@vger.kernel.org, Karl Moskowski <kmoskowski@me.com>,
Jeff King <peff@peff.net>, Mike Hommey <mh@glandium.org>,
David Turner <dturner@twopensource.com>
Subject: Re: [PATCH 05/20] rename_tmp_log(): use raceproof_create_file()
Date: Wed, 17 Feb 2016 12:53:32 -0800 [thread overview]
Message-ID: <xmqqmvqzhxdf.fsf@gitster.mtv.corp.google.com> (raw)
In-Reply-To: <a19192cb3219de9304af7d9b97be45a5e6f0895f.1455626201.git.mhagger@alum.mit.edu> (Michael Haggerty's message of "Tue, 16 Feb 2016 14:22:18 +0100")
Michael Haggerty <mhagger@alum.mit.edu> writes:
> Besides shortening the code, this saves an unnecessary call to
> safe_create_leading_directories_const() in almost all cases.
>
> Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
> ---
> refs/files-backend.c | 76 ++++++++++++++++++++++------------------------------
> 1 file changed, 32 insertions(+), 44 deletions(-)
>
> diff --git a/refs/files-backend.c b/refs/files-backend.c
> index a549942..e5f964c 100644
> --- a/refs/files-backend.c
> +++ b/refs/files-backend.c
> @@ -2400,55 +2400,43 @@ out:
> */
> #define TMP_RENAMED_LOG "logs/refs/.tmp-renamed-log"
>
> +static int rename_tmp_log_callback(const char *path, void *cb)
> +{
> + int *true_errno = cb;
> +
> + if (rename(git_path(TMP_RENAMED_LOG), path)) {
> + /*
> + * rename(a, b) when b is an existing directory ought
> + * to result in ISDIR, but Solaris 5.8 gives ENOTDIR.
> + * Sheesh. Record the true errno for error reporting,
> + * but report EISDIR to raceproof_create_file() so
> + * that it knows to retry.
> + */
> + *true_errno = errno;
> + if (errno==ENOTDIR)
> + errno = EISDIR;
Style: SP on both sides of a binary operator.
More importantly, is ENOTDIR expected only on a buggy platform?
[ENOTDIR]
A component of either path prefix names an existing file that is
neither a directory nor a symbolic link to a directory; or the old
argument names a directory and the new argument names a
non-directory file; or the old argument contains at least one non-
<slash> character and ends with one or more trailing <slash>
characters and the last pathname component names an existing file
that is neither a directory nor a symbolic link to a directory; or
the old argument names an existing non-directory file and the new
argument names a nonexistent file, contains at least one non-
<slash> character, and ends with one or more trailing <slash>
characters; or the new argument names an existing non-directory
file, contains at least one non- <slash> character, and ends with
one or more trailing <slash> characters.
i.e. when a leading component of "path" or TMP_RENAMED_LOG is an
existing non-directory, we could get ENOTDIR on a valid system.
If another instance of Git created a file A/B when this process is
trying to rename the temporary thing to its final location A/B/C,
isn't that the errno we would see here?
[EISDIR]
The new argument points to a directory and the old argument
points to a file that is not a directory.
Puzzled...
> + return -1;
> + } else {
> + return 0;
> + }
> +}
> +
> static int rename_tmp_log(const char *newrefname)
> {
> - int attempts_remaining = 4;
> - struct strbuf path = STRBUF_INIT;
> - int ret = -1;
> + char *path = git_pathdup("logs/%s", newrefname);
> + int true_errno;
> + int ret;
>
> - retry:
> - strbuf_reset(&path);
> - strbuf_git_path(&path, "logs/%s", newrefname);
> - switch (safe_create_leading_directories_const(path.buf)) {
> - case SCLD_OK:
> - break; /* success */
> - case SCLD_VANISHED:
> - if (--attempts_remaining > 0)
> - goto retry;
> - /* fall through */
> - default:
> - error("unable to create directory for %s", newrefname);
> - goto out;
> - }
> -
> - if (rename(git_path(TMP_RENAMED_LOG), path.buf)) {
> - if ((errno==EISDIR || errno==ENOTDIR) && --attempts_remaining > 0) {
> - /*
> - * rename(a, b) when b is an existing
> - * directory ought to result in ISDIR, but
> - * Solaris 5.8 gives ENOTDIR. Sheesh.
> - */
> - if (remove_empty_directories(&path)) {
> - error("Directory not empty: logs/%s", newrefname);
> - goto out;
> - }
> - goto retry;
> - } else if (errno == ENOENT && --attempts_remaining > 0) {
> - /*
> - * Maybe another process just deleted one of
> - * the directories in the path to newrefname.
> - * Try again from the beginning.
> - */
> - goto retry;
> - } else {
> + ret = raceproof_create_file(path, rename_tmp_log_callback, &true_errno);
> + if (ret) {
> + if (true_errno==EISDIR)
> + error("Directory not empty: %s", path);
> + else
> error("unable to move logfile "TMP_RENAMED_LOG" to logs/%s: %s",
> - newrefname, strerror(errno));
> - goto out;
> - }
> + newrefname, strerror(true_errno));
> }
> - ret = 0;
> -out:
> - strbuf_release(&path);
> +
> + free(path);
> return ret;
> }
next prev parent reply other threads:[~2016-02-17 20:53 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-16 13:22 [PATCH 00/20] Delete directories left empty after ref deletion Michael Haggerty
2016-02-16 13:22 ` [PATCH 01/20] safe_create_leading_directories_const(): preserve errno Michael Haggerty
2016-02-16 23:45 ` Jeff King
2016-02-16 13:22 ` [PATCH 02/20] safe_create_leading_directories(): set errno on SCLD_EXISTS Michael Haggerty
2016-02-17 19:23 ` Junio C Hamano
2016-02-18 15:33 ` Michael Haggerty
2016-02-16 13:22 ` [PATCH 03/20] raceproof_create_file(): new function Michael Haggerty
2016-02-17 19:38 ` Junio C Hamano
2016-02-16 13:22 ` [PATCH 04/20] lock_ref_sha1_basic(): use raceproof_create_file() Michael Haggerty
2016-02-17 20:44 ` Junio C Hamano
2016-02-16 13:22 ` [PATCH 05/20] rename_tmp_log(): " Michael Haggerty
2016-02-17 20:53 ` Junio C Hamano [this message]
2016-02-19 16:07 ` Michael Haggerty
2016-02-19 17:15 ` Junio C Hamano
2016-02-16 13:22 ` [PATCH 06/20] rename_tmp_log(): improve error reporting Michael Haggerty
2016-02-18 22:14 ` Junio C Hamano
2016-02-16 13:22 ` [PATCH 07/20] log_ref_setup(): separate code for create vs non-create Michael Haggerty
2016-02-16 13:22 ` [PATCH 08/20] log_ref_setup(): improve robustness against races Michael Haggerty
2016-02-18 22:17 ` Junio C Hamano
2016-02-16 13:22 ` [PATCH 09/20] log_ref_setup(): pass the open file descriptor back to the caller Michael Haggerty
2016-02-18 22:21 ` Junio C Hamano
2016-02-16 13:22 ` [PATCH 10/20] log_ref_write_1(): don't depend on logfile Michael Haggerty
2016-02-16 13:22 ` [PATCH 11/20] log_ref_setup(): manage the name of the reflog file internally Michael Haggerty
2016-02-16 13:22 ` [PATCH 12/20] log_ref_write_1(): inline function Michael Haggerty
2016-02-18 22:23 ` Junio C Hamano
2016-02-16 13:22 ` [PATCH 13/20] try_remove_empty_parents(): rename parameter "name" -> "refname" Michael Haggerty
2016-02-16 13:22 ` [PATCH 14/20] try_remove_empty_parents(): don't trash argument contents Michael Haggerty
2016-02-16 13:22 ` [PATCH 15/20] try_remove_empty_parents(): don't accommodate consecutive slashes Michael Haggerty
2016-02-16 13:22 ` [PATCH 16/20] t5505: use "for-each-ref" to test for the non-existence of references Michael Haggerty
2016-02-16 13:22 ` [PATCH 17/20] delete_ref_loose(): derive loose reference path from lock Michael Haggerty
2016-02-16 13:22 ` [PATCH 18/20] delete_ref_loose(): inline function Michael Haggerty
2016-02-16 13:22 ` [PATCH 19/20] try_remove_empty_parents(): teach to remove parents of reflogs, too Michael Haggerty
2016-02-16 13:22 ` [PATCH 20/20] ref_transaction_commit(): clean up empty directories Michael Haggerty
2016-02-17 0:08 ` [PATCH 00/20] Delete directories left empty after ref deletion Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqqmvqzhxdf.fsf@gitster.mtv.corp.google.com \
--to=gitster@pobox.com \
--cc=dturner@twopensource.com \
--cc=git@vger.kernel.org \
--cc=kmoskowski@me.com \
--cc=mh@glandium.org \
--cc=mhagger@alum.mit.edu \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.