Git development
 help / color / mirror / Atom feed
From: Justin Tobler <jltobler@gmail.com>
To: Patrick Steinhardt <ps@pks.im>
Cc: git@vger.kernel.org, Karthik Nayak <karthik.188@gmail.com>,
	 Jeff King <peff@peff.net>
Subject: Re: [PATCH v2 4/8] refs: unregister reference stores from "chdir_notify"
Date: Wed, 17 Jun 2026 13:02:23 -0500	[thread overview]
Message-ID: <ajLdIY_fxkKDTBaW@denethor> (raw)
In-Reply-To: <20260615-b4-pks-refs-avoid-chdir-notify-reparent-v2-4-f4854aa99859@pks.im>

On 26/06/15 03:56PM, Patrick Steinhardt wrote:
> When creating reference stores we register them with the "chdir_notify"
> subsystem. This is required because some of the paths we track may be
> relative paths, so we have to reparent them in case the current working
> directory changes.
> 
> But while we register the reference stores, we never unregister them.
> This can have multiple outcomes:
> 
>   - For a repository's main reference database we essentially keep the
>     pointer alive. We never free that database, either, and our leak
>     checker doesn't notice because it's still registered.
> 
>   - For submodule and worktree reference databases we do eventually free
>     them in `repo_clear()`, so we may keep pointers to free'd memory
>     registered. We never notice though as we don't tend to chdir around
>     in the middle of the process.
> 
> We never noticed either of these symptoms, but they are obviously bad.
> 
> Partially fix those issues by unregistering the reference stores when
> releasing them. The leak of the main reference database will be fixed in
> a subsequent commit.
> 
> Note that this requires us to use `chdir_notify_register()` instead of
> `chdir_notify_reparent()`, as there is no infrastructure to unregister the
> latter. It ultimately doesn't matter much though: in a subsequent commit
> we'll drop this infrastructure completely. We merely require this step
> here so that we can fix the memory leaks ahead of time.

Since this version of the series dropped the last patch which stopped
using `chdir_notify_reparent()`, does the log message here need to be
updated?

> Signed-off-by: Patrick Steinhardt <ps@pks.im>
> ---
>  refs/files-backend.c    | 22 +++++++++++++++++++---
>  refs/packed-backend.c   | 16 +++++++++++++++-
>  refs/reftable-backend.c | 16 +++++++++++++++-
>  3 files changed, 49 insertions(+), 5 deletions(-)
> 
> diff --git a/refs/files-backend.c b/refs/files-backend.c
> index a4c7858787..296981584b 100644
> --- a/refs/files-backend.c
> +++ b/refs/files-backend.c
> @@ -100,6 +100,23 @@ static void clear_loose_ref_cache(struct files_ref_store *refs)
>  	}
>  }
>  
> +static void files_ref_store_reparent(const char *name UNUSED,
> +				     const char *old_cwd,
> +				     const char *new_cwd,
> +				     void *payload)
> +{
> +	struct files_ref_store *refs = payload;
> +	char *tmp;
> +
> +	tmp = reparent_relative_path(old_cwd, new_cwd, refs->base.gitdir);
> +	free(refs->base.gitdir);
> +	refs->base.gitdir = tmp;
> +
> +	tmp = reparent_relative_path(old_cwd, new_cwd, refs->gitcommondir);
> +	free(refs->gitcommondir);
> +	refs->gitcommondir = tmp;
> +}

Ok, here is introduce a callback specific to the file ref store to
handle reparenting both the gitdir and commondir.

>  /*
>   * Create a new submodule ref cache and add it to the internal
>   * set of caches.
> @@ -128,9 +145,7 @@ static struct ref_store *files_ref_store_init(struct repository *repo,
>  
>  	repo_config_get_bool(repo, "core.prefersymlinkrefs", &refs->prefer_symlink_refs);
>  
> -	chdir_notify_reparent("files-backend $GIT_DIR", &refs->base.gitdir);
> -	chdir_notify_reparent("files-backend $GIT_COMMONDIR",
> -			      &refs->gitcommondir);
> +	chdir_notify_register(NULL, files_ref_store_reparent, refs);

We use the new callback here instead of relying on the generic callback
used by `chdir_notify_reparent()`.

>  	strbuf_release(&refdir);
>  
> @@ -182,6 +197,7 @@ static void files_ref_store_release(struct ref_store *ref_store)
>  	free(refs->gitcommondir);
>  	ref_store_release(refs->packed_ref_store);
>  	free(refs->packed_ref_store);
> +	chdir_notify_unregister(NULL, files_ref_store_reparent, refs);

This allows us to unregister the callback and avoid holding on
references which may have been free'd. Makes sense.

The rest of the patch does the exact same for the packed ref store and
reftable BE which look correct too.

-Justin

  reply	other threads:[~2026-06-17 18:02 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-10 14:57 [PATCH 0/9] refs: stop using `chdir_notify_reparent()` Patrick Steinhardt
2026-06-10 14:57 ` [PATCH 1/9] setup: inline `check_and_apply_repository_format()` Patrick Steinhardt
2026-06-10 14:57 ` [PATCH 2/9] setup: stop applying repository format twice Patrick Steinhardt
2026-06-12  9:00   ` Karthik Nayak
2026-06-15 12:36     ` Patrick Steinhardt
2026-06-10 14:57 ` [PATCH 3/9] setup: don't apply "GIT_REFERENCE_BACKEND" without a repository Patrick Steinhardt
2026-06-10 17:32   ` Junio C Hamano
2026-06-12  6:18     ` Patrick Steinhardt
2026-06-10 14:57 ` [PATCH 4/9] refs: unregister reference stores from "chdir_notify" Patrick Steinhardt
2026-06-12  9:18   ` Karthik Nayak
2026-06-15 12:36     ` Patrick Steinhardt
2026-06-10 14:57 ` [PATCH 5/9] chdir-notify: drop unused `chdir_notify_reparent()` Patrick Steinhardt
2026-06-10 14:57 ` [PATCH 6/9] repository: free main reference database Patrick Steinhardt
2026-06-12  9:20   ` Karthik Nayak
2026-06-10 14:57 ` [PATCH 7/9] refs: fix recursing `get_main_ref_store()` with "onbranch" config Patrick Steinhardt
2026-06-10 14:57 ` [PATCH 8/9] refs: drop local buffer in `refs_compute_filesystem_location()` Patrick Steinhardt
2026-06-10 14:57 ` [PATCH 9/9] refs: always use absolute paths for reference stores Patrick Steinhardt
2026-06-12  9:58   ` Karthik Nayak
2026-06-15 12:36     ` Patrick Steinhardt
2026-06-11  6:53 ` [PATCH 0/9] refs: stop using `chdir_notify_reparent()` Jeff King
2026-06-12  6:18   ` Patrick Steinhardt
2026-06-13 14:00     ` Jeff King
2026-06-15 12:36       ` Patrick Steinhardt
2026-06-15 13:56 ` [PATCH v2 0/8] " Patrick Steinhardt
2026-06-15 13:56   ` [PATCH v2 1/8] setup: inline `check_and_apply_repository_format()` Patrick Steinhardt
2026-06-15 13:56   ` [PATCH v2 2/8] setup: stop applying repository format twice Patrick Steinhardt
2026-06-17 17:22     ` Justin Tobler
2026-06-15 13:56   ` [PATCH v2 3/8] setup: don't apply "GIT_REFERENCE_BACKEND" without a repository Patrick Steinhardt
2026-06-17 17:43     ` Justin Tobler
2026-06-15 13:56   ` [PATCH v2 4/8] refs: unregister reference stores from "chdir_notify" Patrick Steinhardt
2026-06-17 18:02     ` Justin Tobler [this message]
2026-06-17 18:07       ` Justin Tobler
2026-06-15 13:56   ` [PATCH v2 5/8] chdir-notify: drop unused `chdir_notify_reparent()` Patrick Steinhardt
2026-06-15 13:56   ` [PATCH v2 6/8] repository: free main reference database Patrick Steinhardt
2026-06-17 18:09     ` Justin Tobler
2026-06-15 13:56   ` [PATCH v2 7/8] refs: fix recursing `get_main_ref_store()` with "onbranch" config Patrick Steinhardt
2026-06-17 18:41     ` Justin Tobler
2026-06-15 13:56   ` [PATCH v2 8/8] refs: drop local buffer in `refs_compute_filesystem_location()` Patrick Steinhardt

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=ajLdIY_fxkKDTBaW@denethor \
    --to=jltobler@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=karthik.188@gmail.com \
    --cc=peff@peff.net \
    --cc=ps@pks.im \
    /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