git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Johannes Schindelin <johannes.schindelin@gmx.de>
Cc: git@vger.kernel.org, Jeff Hostetler <jeffhost@microsoft.com>
Subject: Re: [PATCH] read-cache: close index.lock in do_write_index
Date: Wed, 26 Apr 2017 20:21:59 -0700	[thread overview]
Message-ID: <xmqq1ssepmaw.fsf@gitster.mtv.corp.google.com> (raw)
In-Reply-To: <e1b4f9c377ceee296112fa07bd06492a1de1be67.1493237111.git.johannes.schindelin@gmx.de> (Johannes Schindelin's message of "Wed, 26 Apr 2017 22:05:23 +0200 (CEST)")

Johannes Schindelin <johannes.schindelin@gmx.de> writes:

> From: Jeff Hostetler <jeffhost@microsoft.com>
>
> Teach do_write_index() to close the index.lock file
> before getting the mtime and updating the istate.timestamp
> fields.
>
> On Windows, a file's mtime is not updated until the file is
> closed.  On Linux, the mtime is set after the last flush.
>
> Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
> Published-As: https://github.com/dscho/git/releases/tag/do-write-index-mtime-v1
> Fetch-It-Via: git fetch https://github.com/dscho/git do-write-index-mtime-v1
>
>  read-cache.c | 13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/read-cache.c b/read-cache.c
> index 008b335844c..b0276fd5510 100644
> --- a/read-cache.c
> +++ b/read-cache.c
> @@ -2051,9 +2051,10 @@ void update_index_if_able(struct index_state *istate, struct lock_file *lockfile
>  		rollback_lock_file(lockfile);
>  }
>  
> -static int do_write_index(struct index_state *istate, int newfd,
> +static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
>  			  int strip_extensions)
>  {
> +	int newfd = tempfile->fd;
>  	git_SHA_CTX c;
>  	struct cache_header hdr;
>  	int i, err, removed, extended, hdr_version;
> @@ -2162,7 +2163,11 @@ static int do_write_index(struct index_state *istate, int newfd,
>  			return -1;
>  	}
>  
> -	if (ce_flush(&c, newfd, istate->sha1) || fstat(newfd, &st))
> +	if (ce_flush(&c, newfd, istate->sha1))
> +		return -1;
> +	if (close_tempfile(tempfile))
> +		return error(_("could not close '%s'"), tempfile->filename.buf);
> +	if (lstat(tempfile->filename.buf, &st))
>  		return -1;


stat/lstat with path may be slower than fstat on an open file
descriptor, and I think that is the reason why we do it this way,
but the performance difference would probably be unmeasurable and
does not matter in practice.

As we are not using the fact that we still have the file descriptor
open when we do the stat for any purpose (e.g. like locking other
processes out), this move to "close first and then stat" is a good
workaround for the problem.  I wonder if we have been seeing false
"racy git" problem more often due to this issue on Windows than
other platforms.

When code uses lstat, it gives a signal to the readers of the code
that the code is prepared to see a symlink and when it is a symlink
it wants to grab the property of the link itself, not the target of
the link.  I do not think the temporary index can be a symbolic
link, and even if that were the case, we do want the mtime of the
link target, so it is a wrong signal to give to the readers.  Hence,
it would be better to use stat() here from the readability's point
of view.  Of course, when the path is always a regular file, lstat()
vs stat() technically does not give any different result, so this
comment is purely about the maintainability, not about correctness.

Other than that, looks good to me.

>  	istate->timestamp.sec = (unsigned int)st.st_mtime;
>  	istate->timestamp.nsec = ST_MTIME_NSEC(st);
> @@ -2185,7 +2190,7 @@ static int commit_locked_index(struct lock_file *lk)
>  static int do_write_locked_index(struct index_state *istate, struct lock_file *lock,
>  				 unsigned flags)
>  {
> -	int ret = do_write_index(istate, get_lock_file_fd(lock), 0);
> +	int ret = do_write_index(istate, &lock->tempfile, 0);
>  	if (ret)
>  		return ret;
>  	assert((flags & (COMMIT_LOCK | CLOSE_LOCK)) !=
> @@ -2282,7 +2287,7 @@ static int write_shared_index(struct index_state *istate,
>  		return do_write_locked_index(istate, lock, flags);
>  	}
>  	move_cache_to_base_index(istate);
> -	ret = do_write_index(si->base, fd, 1);
> +	ret = do_write_index(si->base, &temporary_sharedindex, 1);
>  	if (ret) {
>  		delete_tempfile(&temporary_sharedindex);
>  		return ret;
>
> base-commit: e2cb6ab84c94f147f1259260961513b40c36108a

  parent reply	other threads:[~2017-04-27  3:22 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-26 20:05 [PATCH] read-cache: close index.lock in do_write_index Johannes Schindelin
2017-04-27  3:13 ` Jeff King
2017-04-27 16:51   ` Jeff Hostetler
2017-04-27  3:21 ` Junio C Hamano [this message]
2017-04-27 16:45   ` Jeff Hostetler

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

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xmqq1ssepmaw.fsf@gitster.mtv.corp.google.com \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=jeffhost@microsoft.com \
    --cc=johannes.schindelin@gmx.de \
    /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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).