From: Michael Haggerty <mhagger@alum.mit.edu>
To: Junio C Hamano <gitster@pobox.com>, Jeff King <peff@peff.net>
Cc: git@vger.kernel.org
Subject: Re: [PATCH 02/22] try_merge_strategy(): remove redundant lock_file allocation
Date: Thu, 03 Apr 2014 14:43:01 +0200 [thread overview]
Message-ID: <533D5755.7030609@alum.mit.edu> (raw)
In-Reply-To: <xmqqy4znwu4g.fsf@gitster.dls.corp.google.com>
On 04/02/2014 06:53 PM, Junio C Hamano wrote:
> Jeff King <peff@peff.net> writes:
>
>> On Tue, Apr 01, 2014 at 05:58:10PM +0200, Michael Haggerty wrote:
>>
>>> By the time the "if" block is entered, the lock_file instance from the
>>> main function block is no longer in use, so re-use that one instead of
>>> allocating a second one.
>>>
>>> Note that the "lock" variable in the "if" block used to shadow the
>>> "lock" variable at function scope, so the only change needed is to
>>> remove the inner definition.
>>
>> I wonder if this would also be simpler if "lock" were simply declared as
>> a static variable, and we drop the allocation entirely. I suppose that
>> does create more cognitive load, though, in that it is only correct if
>> the function is not recursive. On the other hand, the current code makes
>> a reader unfamiliar with "struct lock" wonder if there is a free(lock)
>> missing.
>
> Another thing that makes a reader wonder if this is a valid rewrite
> is if it is safe to reuse a lock_file structure, especially because
> the original gives a piece of memory _cleared_ with xcalloc(). The
> second invocation of hold_locked_index() is now done on a dirty
> piece of memory, and the reader needs to drill down the callchain to
> see if that is safe (and if not, hold_locked_index() and probably
> the underlying lock_file() needs to memset() it to NULs).
It's good that you and Peff asked questions about this sort of thing.
We reuse lock_file structures *all over the place*; for example, just
search for "static struct lock_file". It has to be safe...
...and yet it isn't. Look in the definition of lock_file() (before my
changes):
static int lock_file(struct lock_file *lk, const char *path, int flags)
{
...
strcpy(lk->filename, path);
if (!(flags & LOCK_NODEREF))
resolve_symlink(lk->filename, max_path_len);
strcat(lk->filename, ".lock");
Remember that a reused lock_file structure is already in lock_file_list,
and there is already a signal handler registered that will call
remove_lock_file(), which looks like:
static void remove_lock_file(void)
{
pid_t me = getpid();
while (lock_file_list) {
if (lock_file_list->owner == me &&
lock_file_list->filename[0]) {
if (lock_file_list->fd >= 0)
close(lock_file_list->fd);
unlink_or_warn(lock_file_list->filename);
}
lock_file_list = lock_file_list->next;
}
}
So, if the process gets a signal during the call to resolve_symlink(),
the atexit() cleanup routine will delete the valuable file (the one
being locked)!
It definitely looks like this area needs more work.
Michael
--
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
next prev parent reply other threads:[~2014-04-03 12:43 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-04-01 15:58 [PATCH 00/22] Lockfile refactoring and pre-activation Michael Haggerty
2014-04-01 15:58 ` [PATCH 01/22] t3204: test deleting references when lock files already exist Michael Haggerty
2014-04-01 19:53 ` Jeff King
2014-04-02 10:28 ` Michael Haggerty
2014-04-01 15:58 ` [PATCH 02/22] try_merge_strategy(): remove redundant lock_file allocation Michael Haggerty
2014-04-01 19:56 ` Jeff King
2014-04-02 10:53 ` Michael Haggerty
2014-04-02 16:53 ` Junio C Hamano
2014-04-03 12:43 ` Michael Haggerty [this message]
2014-04-01 15:58 ` [PATCH 03/22] rollback_lock_file(): do not clear filename redundantly Michael Haggerty
2014-04-01 15:58 ` [PATCH 04/22] rollback_lock_file(): set fd to -1 Michael Haggerty
2014-04-01 19:59 ` Jeff King
2014-04-02 16:58 ` Junio C Hamano
2014-04-06 21:45 ` Michael Haggerty
2014-04-07 16:37 ` Junio C Hamano
2014-04-01 15:58 ` [PATCH 05/22] lockfile: unlock file if lockfile permissions cannot be adjusted Michael Haggerty
2014-04-01 20:02 ` Jeff King
2014-04-01 20:05 ` Jeff King
2014-04-02 6:47 ` Torsten Bögershausen
2014-04-06 22:02 ` Michael Haggerty
2014-04-01 15:58 ` [PATCH 06/22] hold_lock_file_for_append(): release lock on errors Michael Haggerty
2014-04-01 15:58 ` [PATCH 07/22] lock_file(): always add lock_file object to lock_file_list Michael Haggerty
2014-04-01 20:16 ` Jeff King
2014-04-02 17:01 ` Junio C Hamano
2014-04-06 21:54 ` Michael Haggerty
2014-04-07 9:36 ` Jeff King
2014-04-01 15:58 ` [PATCH 08/22] struct lock_file: replace on_list field with flags field Michael Haggerty
2014-04-01 15:58 ` [PATCH 09/22] api-lockfile: expand the documentation Michael Haggerty
2014-04-01 20:19 ` Jeff King
2014-04-02 11:36 ` Michael Haggerty
2014-04-01 15:58 ` [PATCH 10/22] lockfile.c: document the various states of lock_file objects Michael Haggerty
2014-04-01 15:58 ` [PATCH 11/22] lockfile: define a constant LOCK_SUFFIX_LEN Michael Haggerty
2014-04-02 17:27 ` Junio C Hamano
2014-04-01 15:58 ` [PATCH 12/22] delete_ref_loose(): don't muck around in the lock_file's filename Michael Haggerty
2014-04-01 20:21 ` Jeff King
2014-04-02 11:50 ` Michael Haggerty
2014-04-02 6:52 ` Torsten Bögershausen
2014-04-02 6:55 ` Jeff King
2014-04-01 15:58 ` [PATCH 13/22] config: change write_error() to take a (struct lock_file *) argument Michael Haggerty
2014-04-02 6:58 ` Torsten Bögershausen
2014-04-06 22:04 ` Michael Haggerty
2014-04-02 17:29 ` Junio C Hamano
2014-04-01 15:58 ` [PATCH 14/22] lockfile: use strbufs when handling (most) paths Michael Haggerty
2014-04-01 20:28 ` Jeff King
2014-04-02 17:16 ` Junio C Hamano
2014-04-01 15:58 ` [PATCH 15/22] resolve_symlink(): use a strbuf internally Michael Haggerty
2014-04-01 15:58 ` [PATCH 16/22] commit_lock_file(): don't work with a fixed-length buffer Michael Haggerty
2014-04-01 15:58 ` [PATCH 17/22] lock_file(): exit early if lockfile cannot be opened Michael Haggerty
2014-04-01 15:58 ` [PATCH 18/22] lockfile: also keep track of the filename of the file being locked Michael Haggerty
2014-04-02 17:19 ` Junio C Hamano
2014-04-06 22:05 ` Michael Haggerty
2014-04-01 15:58 ` [PATCH 19/22] struct lock_file: rename lock_filename field to staging_filename Michael Haggerty
2014-04-01 15:58 ` [PATCH 20/22] remove_lock_file(): call rollback_lock_file() Michael Haggerty
2014-04-01 15:58 ` [PATCH 21/22] lockfile: extract a function reset_lock_file() Michael Haggerty
2014-04-02 7:06 ` Eric Sunshine
2014-04-02 13:37 ` Michael Haggerty
2014-04-01 15:58 ` [PATCH 22/22] lockfile: allow new file contents to be written while retaining lock Michael Haggerty
2014-04-01 20:39 ` Jeff King
2014-04-02 7:20 ` Eric Sunshine
2014-04-02 17:26 ` Junio C Hamano
2014-04-01 20:44 ` [PATCH 00/22] Lockfile refactoring and pre-activation Jeff King
2014-04-03 11:42 ` Michael Haggerty
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=533D5755.7030609@alum.mit.edu \
--to=mhagger@alum.mit.edu \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--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 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 NNTP newsgroup(s).