All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: Johannes Sixt <j6t@kdbg.org>
Cc: Junio C Hamano <gitster@pobox.com>,
	Johannes Schindelin <johannes.schindelin@gmx.de>,
	git@vger.kernel.org, Jeff King <peff@peff.net>,
	Jeff Hostetler <git@jeffhostetler.com>
Subject: Re: [PATCH] mingw: enable atomic O_APPEND
Date: Mon, 13 Aug 2018 23:22:10 +0200	[thread overview]
Message-ID: <87eff2rmgt.fsf@evledraar.gmail.com> (raw)
In-Reply-To: <84c749fd-23d2-0bc5-225b-74f8d31502b6@kdbg.org>


On Mon, Aug 13 2018, Johannes Sixt wrote:

> Am 13.08.2018 um 22:20 schrieb Junio C Hamano:
>> Johannes Sixt <j6t@kdbg.org> writes:
>>
>>> The Windows CRT implements O_APPEND "manually": on write() calls, the
>>> file pointer is set to EOF before the data is written. Clearly, this is
>>> not atomic. And in fact, this is the root cause of failures observed in
>>> t5552-skipping-fetch-negotiator.sh and t5503-tagfollow.sh, where
>>> different processes write to the same trace file simultanously; it also
>>> occurred in t5400-send-pack.sh, but there it was worked around in
>>> 71406ed4d6 ("t5400: avoid concurrent writes into a trace file",
>>> 2017-05-18).
>>>
>>> Fortunately, Windows does support atomic O_APPEND semantics using the
>>> file access mode FILE_APPEND_DATA. Provide an implementation that does.
>>>
>>> This implementation is minimal in such a way that it only implements
>>> the open modes that are actually used in the Git code base. Emulation
>>> for other modes can be added as necessary later. To become aware of
>>> the necessity early, the unusal error ENOSYS is reported if an
>>> unsupported mode is encountered.
>>>
>>> Diagnosed-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
>>> Helped-by: Jeff Hostetler <git@jeffhostetler.com>
>>> Signed-off-by: Johannes Sixt <j6t@kdbg.org>
>>> ---
>>>   compat/mingw.c | 41 +++++++++++++++++++++++++++++++++++++++--
>>>   1 file changed, 39 insertions(+), 2 deletions(-)
>>
>> Nice.
>>
>> I wonder how much more expensive using this implementation is
>> compared with the original "race susceptible" open(), when raciness
>> is known not to be an issue (e.g. there is higher level lock that
>> protects the appending).
>
> Certainly, the former way that uses two syscalls
> (SetFilePointer+WriteFile) is more costly than this new way with just
> one syscall (WriteFile). Of course, I don't know how atomic append
> would be implemented in the kernel, but I can't think of a reason why
> it should be slow on Windows, but fast on POSIX.
>
> (But I can't provide numbers to back up my gut feeling...)
>
> (And I also assume that you are not worried about the performance of
> open() itself.)
>
>> ...[define race_safe_append_open]... and replace
>> the call to open(... O_APPEND ...) in trace.c::get_trace_fd() with a
>> call to that wrapper.  That way, other codepaths that use O_APPEND
>> (namely, reflog and todo-list writers) can avoid the additional
>> cost, if any.
>>
>> Some may find it beneficial from code readability POV because that
>> approach marks the codepath that needs to have non-racy fd more
>> explicitly.
>
> O_APPEND is POSIX and means race-free append. If you mark some call
> sites with O_APPEND, then that must be the ones that need race-free
> append. Hence, you would have to go the other route: Mark those call
> sites that do _not_ need race-free append with some custom
> function/macro. (Or mark both with different helpers and avoid writing
> down O_APPEND.)

O_APPEND in POSIX is race-free only up to PIPE_MAX bytes written at a
time, which is e.g. 2^12 by default on linux, after that all bets are
off and the kernel is free to interleave different write calls.

I've written code (not for git.git) that implements such a
"write_non_racy" function in the past, and the first thing it needs to
do is to assert that the length of the buffer being written doesn't
exceed PIPE_MAX.

So there's still a use for a race_safe_append_open() wrapper function,
to O_APPEND and do the PIPE_MAX assertion. Otherwise you're calling a
"safe" function which isn't safe at all anymore.

I have no idea what the equivalent of that PIPE_MAX caveat is on
non-POSIX (e.g. Windows), but would be interested to find out.

  reply	other threads:[~2018-08-13 21:22 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-09 17:35 [PATCH 0/4] t5552: fix flakiness by introducing proper locking for GIT_TRACE Johannes Schindelin via GitGitGadget
2018-08-09 17:35 ` [PATCH 1/4] Introduce a function to lock/unlock file descriptors when appending Johannes Schindelin via GitGitGadget
2018-08-09 19:01   ` Junio C Hamano
2018-08-10 18:32     ` Johannes Schindelin
2018-08-09 17:35 ` [PATCH 2/4] mingw: implement lock_or_unlock_fd_for_appending() Johannes Schindelin via GitGitGadget
2018-08-09 17:35 ` [PATCH 3/4] trace: lock the trace file to avoid racy trace_write() calls Johannes Schindelin via GitGitGadget
2018-08-09 17:35 ` [PATCH 4/4] trace: verify that locking works Johannes Schindelin via GitGitGadget
2018-08-09 19:47 ` [PATCH 0/4] t5552: fix flakiness by introducing proper locking for GIT_TRACE Jeff King
2018-08-09 20:49   ` Junio C Hamano
2018-08-09 21:08     ` Junio C Hamano
2018-08-09 21:32       ` Jeff King
2018-08-10 14:09     ` Jeff King
2018-08-10 15:58       ` Junio C Hamano
2018-08-10 15:58       ` Junio C Hamano
2018-08-10 16:43       ` Johannes Schindelin
2018-08-10 17:15         ` Jeff King
2018-08-10 18:40           ` Junio C Hamano
2018-08-10 19:34           ` Johannes Schindelin
2018-08-10 16:15 ` Johannes Sixt
2018-08-10 16:51   ` Jeff Hostetler
2018-08-10 16:57     ` Jeff Hostetler
2018-08-10 17:08     ` Johannes Sixt
2018-08-10 18:34   ` Junio C Hamano
2018-08-10 18:56     ` Jeff King
2018-08-13 19:02     ` [PATCH] mingw: enable atomic O_APPEND Johannes Sixt
2018-08-13 20:20       ` Junio C Hamano
2018-08-13 21:05         ` Johannes Sixt
2018-08-13 21:22           ` Ævar Arnfjörð Bjarmason [this message]
2018-08-13 21:55             ` Junio C Hamano
2018-08-13 22:37             ` Jeff King
2018-08-14 13:47               ` Ævar Arnfjörð Bjarmason
2018-08-14 14:53                 ` Jeff King
2018-08-14 18:29               ` Johannes Sixt
2018-08-14 19:17                 ` Jeff King
2018-08-14 13:01       ` Jeff Hostetler
2018-08-14 14:38         ` Junio C Hamano
2018-08-10 19:47 ` [PATCH v2 0/4] t5552: fix flakiness by introducing proper locking for GIT_TRACE Johannes Schindelin via GitGitGadget
2018-08-10 19:47   ` [PATCH v2 1/4] Introduce a function to lock/unlock file descriptors when appending Johannes Schindelin via GitGitGadget
2018-08-10 20:05     ` Junio C Hamano
2018-08-10 21:31       ` Johannes Schindelin
2018-08-10 19:47   ` [PATCH v2 2/4] mingw: implement lock_or_unlock_fd_for_appending() Johannes Schindelin via GitGitGadget
2018-08-10 19:47   ` [PATCH v2 3/4] trace: lock the trace file to avoid racy trace_write() calls Johannes Schindelin via GitGitGadget
2018-08-10 19:47   ` [PATCH v2 4/4] trace: verify that locking works Johannes Schindelin via GitGitGadget

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=87eff2rmgt.fsf@evledraar.gmail.com \
    --to=avarab@gmail.com \
    --cc=git@jeffhostetler.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=j6t@kdbg.org \
    --cc=johannes.schindelin@gmx.de \
    --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.