git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2 02/16] odb: move list of packfiles into `struct packfile_store`

From
Patrick Steinhardt <ps@pks.im>
Date
Sep 2, 2025, 08:50 UTC
Message-ID
<aLav4UAcfQjvNzMF@pks.im>
In-Reply-To
<aKz0/WNu/GRYh3/W@nand.local>
On Mon, Aug 25, 2025 at 07:42:53PM -0400, Taylor Blau wrote:
Show 14 quoted lines
> On Thu, Aug 21, 2025 at 09:39:00AM +0200, Patrick Steinhardt wrote:
> > The object database tracks the list of packfiles it currently knows
> > about. With the introduction of the `struct packfile_store` we have a
> > better place to host this list though.
> >
> > Move the list accordingly. Extract the logic from `odb_clear()` that
> > knows to close all such packfiles and move it into the new subsystem, as
> > well.
> 
> Not a comment on this patch itself, but as a meta-comment, I really
> appreciate you taking such an incremental approach here. The packfile
> machinery is quite fragile in my experience, so breaking it up into (what
> are so far) easily review-able chunks makes it much easier to build
> confidence in the correctness of these changes.

It certainly is fragile overall. I stared at code for way longer than I really want to admit in some cases.

Show 47 quoted lines
> > diff --git a/odb.c b/odb.c
> > index 34b70d0074..17a9135cbd 100644
> > --- a/odb.c
> > +++ b/odb.c
> > @@ -1038,16 +1038,7 @@ void odb_clear(struct object_database *o)
> >
> >  	INIT_LIST_HEAD(&o->packed_git_mru);
> >  	close_object_store(o);
> > -
> > -	/*
> > -	 * `close_object_store()` only closes the packfiles, but doesn't free
> > -	 * them. We thus have to do this manually.
> > -	 */
> > -	for (struct packed_git *p = o->packed_git, *next; p; p = next) {
> > -		next = p->next;
> > -		free(p);
> > -	}
> > -	o->packed_git = NULL;
> > +	packfile_store_free(o->packfiles);
> 
> Interesting. The movement of the for-loop here all looks correct to me.
> But I think the new packfile_store is creating a new awkardness here
> that we should consider.
> 
> In existing implementation, all of the ->next pointers here point to
> heap locations that have already been free()'d. But that's OK, since
> they aren't reachable at the moment that we do "o-packed_store = NULL".
> 
> Having a separate packfile_store changes that, since (from my reading of
> the code) o->packfiles will still be non-NULL even after calling
> odb_clear(), *and* those pointers will refer to free'd heap locations.
> 
> That seems like a potential footgun to me. I think that we could either:
> 
>  * Change packfile_store_free() to take in an object_database pointer,
>    and NULL out the ->packs pointer after free'ing all of the packfiles.
>    That would make it more similar to the existing behavior.
> 
>  * Leave packfile_store_free() as-is, document that it does NOT clear
>    out the top-level pointer, and so callers are encouraged to NULL it
>    out themselves after calling it. Likewise, we should change
>    odb_clear() to do:
> 
>        packfile_store_free(o->packfiles);
>        o->packfiles = NULL;
> 
> Let me know what you think.

Good point. I think it's unlikely to ever become a problem, but I don't see a reason why we shouldn't NULL out `o->packfiles`, either. So I'll do the second approach.

Show 15 quoted lines
> > diff --git a/packfile.c b/packfile.c
> > index 8fbf1cfc2d..6478e4cc30 100644
> > --- a/packfile.c
> > +++ b/packfile.c
> > @@ -278,7 +278,7 @@ static int unuse_one_window(struct packed_git *current)
> >
> >  	if (current)
> >  		scan_windows(current, &lru_p, &lru_w, &lru_l);
> > -	for (p = current->repo->objects->packed_git; p; p = p->next)
> > +	for (p = current->repo->objects->packfiles->packs; p; p = p->next)
> 
> Not a huge deal, but I do find "current->repo->objects->packfiles->packs"
> to be a bit unfortunate. I wonder if we should rename "packs" to "head"
> or "list_head" or similar since it's clear from
> "current->repo->objects->packfiles" that this is a list of packfiles.

I'd like to keep this part as-is for now if you don't mind. This is mostly because I've got a follow-up patch series that _does_ introduce `head` as part of making the `->next` pointer go away.

Show 13 quoted lines
> > @@ -2344,5 +2339,23 @@ struct packfile_store *packfile_store_new(struct object_database *odb)
> >
> >  void packfile_store_free(struct packfile_store *store)
> >  {
> > +	packfile_store_close(store);
> 
> Seeing a call to packfile_store_close() here was a little surprising to
> me. The code that you are moving has a comment that says:
> 
>    * `close_object_store()` only closes the packfiles, but doesn't free
>    * them. We thus have to do this manually.
> 
> , so I would have expected to preserve that behavior.

This behaviour is preserved though. Calling `packfile_store_close()` does not free the packfiles, it only closes them. And we continue to call `packfile_store_close()` in `close_object_store()`, so nothing changes.

The only change in behaviour is that we now also know to close packfiles when freeing the packfile store.

Show 8 quoted lines
> I *think* that
> this happens to be OK, since close_pack() is a noop if it is called more
> than once (though I had to double check through all of its leaf
> functions that that was indeed the case).
> 
> I would probably strike this from the new function, since the sole
> caller above already calls close_object_store() before calling
> packfile_store_free().

Calling `packfile_store_close()` is idempotent indeed, so it shouldn't be an issue to call this function twice. To me the question is whether there's ever a use case where you want to free the packfile store, but don't want to close the packfiles stored in it.

From all I've seen that is never the case, so I think it's sensible to ensure that we always close the packfile store before we free it to make things a tiny bit more self-contained.

Show 14 quoted lines
> > +void packfile_store_close(struct packfile_store *store)
> > +{
> > +	struct packed_git *p;
> > +
> > +	for (p = store->packs; p; p = p->next)
> > +		if (p->do_not_close)
> > +			BUG("want to close pack marked 'do-not-close'");
> > +		else
> > +			close_pack(p);
> > +}
> 
> And likewise this looks good to me. I do find the braceless for-loop a
> little hard to read, but it's (a) correct, and (b) consistent with the
> original implementation, so I don't feel strongly about changing it.

Agreed, it is a bit awkward. I feel like our coding style should be amended to say that we only do braceless bodies in case the body is a single statement.

> As a side-note, you could inline the declaration of "p" here into the
> for-loop, but I can understand not wanting to to make the diff more
> readable with --color-moved.
I wouldn't mind adapting this while at it, too.
Patrick
Previous: Taylor BlauNext: Taylor Blau
Message 50 of 181 in “packfile: carve out a new packfile store”
  1. 00/16 packfile: carve out a new packfile storePatrick Steinhardt, Aug 19, 2025
  2. 01/16 packfile: introduce a new `struct packfile_store`Patrick Steinhardt, Aug 19, 2025
  3. Karthik NayakAug 19, 2025
  4. Patrick SteinhardtAug 20, 2025
  5. Junio C HamanoAug 19, 2025
  6. Patrick SteinhardtAug 20, 2025
  7. 02/16 odb: move list of packfiles into `struct packfile_store`Patrick Steinhardt, Aug 19, 2025
  8. 03/16 odb: move initialization bit into `struct packfile_store`Patrick Steinhardt, Aug 19, 2025
  9. Karthik NayakAug 19, 2025
  10. Junio C HamanoAug 19, 2025
  11. Karthik NayakAug 20, 2025
  12. Junio C HamanoAug 22, 2025
  13. Documentation: note styling for bit fieldsKarthik Nayak, Aug 26, 2025
  14. Patrick SteinhardtAug 20, 2025
  15. Junio C HamanoAug 20, 2025
  16. 04/16 odb: move packfile map into `struct packfile_store`Patrick Steinhardt, Aug 19, 2025
  17. 05/16 odb: move MRU list of packfiles into `struct packfile_store`Patrick Steinhardt, Aug 19, 2025
  18. Karthik NayakAug 20, 2025
  19. Jeff KingAug 20, 2025
  20. Patrick SteinhardtAug 21, 2025
  21. 06/16 odb: move kept cache into `struct packfile_store`Patrick Steinhardt, Aug 19, 2025
  22. Junio C HamanoAug 19, 2025
  23. Patrick SteinhardtAug 20, 2025
  24. 07/16 packfile: reorder functions to avoid function declarationPatrick Steinhardt, Aug 19, 2025
  25. Junio C HamanoAug 19, 2025
  26. 08/16 packfile: refactor `prepare_packed_git()` to work on packfile storePatrick Steinhardt, Aug 19, 2025
  27. 09/16 packfile: split up responsibilities of `reprepare_packed_git()`Patrick Steinhardt, Aug 19, 2025
  28. Karthik NayakAug 20, 2025
  29. 10/16 packfile: refactor `install_packed_git()` to work on packfile storePatrick Steinhardt, Aug 19, 2025
  30. 11/16 packfile: always add packfiles to MRU when adding a packPatrick Steinhardt, Aug 19, 2025
  31. Karthik NayakAug 20, 2025
  32. 12/16 packfile: introduce function to load and add packfilesPatrick Steinhardt, Aug 19, 2025
  33. Karthik NayakAug 20, 2025
  34. Patrick SteinhardtAug 21, 2025
  35. 13/16 packfile: move `get_multi_pack_index()` into "midx.c"Patrick Steinhardt, Aug 19, 2025
  36. 14/16 packfile: remove `get_packed_git()`Patrick Steinhardt, Aug 19, 2025
  37. Karthik NayakAug 20, 2025
  38. Patrick SteinhardtAug 21, 2025
  39. Karthik NayakAug 20, 2025
  40. 15/16 packfile: refactor `get_all_packs()` to work on packfile storePatrick Steinhardt, Aug 19, 2025
  41. Karthik NayakAug 20, 2025
  42. Patrick SteinhardtAug 21, 2025
  43. 16/16 packfile: refactor `get_packed_git_mru()` to work on packfile storePatrick Steinhardt, Aug 19, 2025
  44. Junio C HamanoAug 19, 2025
  45. Karthik NayakAug 20, 2025
  46. 00/16 packfile: carve out a new packfile storePatrick Steinhardt, Aug 21, 2025
  47. 01/16 packfile: introduce a new `struct packfile_store`Patrick Steinhardt, Aug 21, 2025
  48. 02/16 odb: move list of packfiles into `struct packfile_store`Patrick Steinhardt, Aug 21, 2025
  49. Taylor BlauAug 25, 2025
  50. Patrick SteinhardtSep 2, 2025
  51. Taylor BlauSep 2, 2025
  52. Junio C HamanoSep 2, 2025
  53. Patrick SteinhardtSep 3, 2025
  54. Taylor BlauSep 11, 2025
  55. Patrick SteinhardtSep 15, 2025
  56. 03/16 odb: move initialization bit into `struct packfile_store`Patrick Steinhardt, Aug 21, 2025
  57. Taylor BlauAug 26, 2025
  58. 04/16 odb: move packfile map into `struct packfile_store`Patrick Steinhardt, Aug 21, 2025
  59. Taylor BlauAug 26, 2025
  60. 05/16 odb: move MRU list of packfiles into `struct packfile_store`Patrick Steinhardt, Aug 21, 2025
  61. 06/16 odb: move kept cache into `struct packfile_store`Patrick Steinhardt, Aug 21, 2025
  62. Taylor BlauAug 26, 2025
  63. Patrick SteinhardtSep 2, 2025
  64. 07/16 packfile: reorder functions to avoid function declarationPatrick Steinhardt, Aug 21, 2025
  65. Taylor BlauAug 26, 2025
  66. 08/16 packfile: refactor `prepare_packed_git()` to work on packfile storePatrick Steinhardt, Aug 21, 2025
  67. Taylor BlauAug 26, 2025
  68. 09/16 packfile: split up responsibilities of `reprepare_packed_git()`Patrick Steinhardt, Aug 21, 2025
  69. Taylor BlauAug 26, 2025
  70. Patrick SteinhardtSep 2, 2025
  71. 10/16 packfile: refactor `install_packed_git()` to work on packfile storePatrick Steinhardt, Aug 21, 2025
  72. Taylor BlauAug 26, 2025
  73. Patrick SteinhardtSep 2, 2025
  74. 11/16 packfile: always add packfiles to MRU when adding a packPatrick Steinhardt, Aug 21, 2025
  75. Taylor BlauAug 27, 2025
  76. Patrick SteinhardtSep 2, 2025
  77. 12/16 packfile: introduce function to load and add packfilesPatrick Steinhardt, Aug 21, 2025
  78. Taylor BlauAug 27, 2025
  79. 13/16 packfile: move `get_multi_pack_index()` into "midx.c"Patrick Steinhardt, Aug 21, 2025
  80. Taylor BlauAug 27, 2025
  81. 14/16 packfile: remove `get_packed_git()`Patrick Steinhardt, Aug 21, 2025
  82. Taylor BlauAug 27, 2025
  83. Patrick SteinhardtSep 2, 2025
  84. Taylor BlauSep 11, 2025
  85. Patrick SteinhardtSep 15, 2025
  86. 15/16 packfile: refactor `get_all_packs()` to work on packfile storePatrick Steinhardt, Aug 21, 2025
  87. Taylor BlauAug 27, 2025
  88. Patrick SteinhardtSep 2, 2025
  89. Taylor BlauSep 11, 2025
  90. Patrick SteinhardtSep 15, 2025
  91. 16/16 packfile: refactor `get_packed_git_mru()` to work on packfile storePatrick Steinhardt, Aug 21, 2025
  92. 00/15 packfile: carve out a new packfile storePatrick Steinhardt, Sep 2, 2025
  93. 01/15 packfile: introduce a new `struct packfile_store`Patrick Steinhardt, Sep 2, 2025
  94. Karthik NayakSep 9, 2025
  95. 02/15 odb: move list of packfiles into `struct packfile_store`Patrick Steinhardt, Sep 2, 2025
  96. Karthik NayakSep 9, 2025
  97. Patrick SteinhardtSep 9, 2025
  98. 03/15 odb: move initialization bit into `struct packfile_store`Patrick Steinhardt, Sep 2, 2025
  99. 04/15 odb: move packfile map into `struct packfile_store`Patrick Steinhardt, Sep 2, 2025
  100. Karthik NayakSep 9, 2025
  101. Patrick SteinhardtSep 9, 2025
  102. 05/15 odb: move MRU list of packfiles into `struct packfile_store`Patrick Steinhardt, Sep 2, 2025
  103. 06/15 odb: move kept cache into `struct packfile_store`Patrick Steinhardt, Sep 2, 2025
  104. 07/15 packfile: reorder functions to avoid function declarationPatrick Steinhardt, Sep 2, 2025
  105. 08/15 packfile: refactor `prepare_packed_git()` to work on packfile storePatrick Steinhardt, Sep 2, 2025
  106. 09/15 packfile: split up responsibilities of `reprepare_packed_git()`Patrick Steinhardt, Sep 2, 2025
  107. 10/15 packfile: refactor `install_packed_git()` to work on packfile storePatrick Steinhardt, Sep 2, 2025
  108. 11/15 packfile: introduce function to load and add packfilesPatrick Steinhardt, Sep 2, 2025
  109. 12/15 packfile: move `get_multi_pack_index()` into "midx.c"Patrick Steinhardt, Sep 2, 2025
  110. 13/15 packfile: remove `get_packed_git()`Patrick Steinhardt, Sep 2, 2025
  111. 14/15 packfile: refactor `get_all_packs()` to work on packfile storePatrick Steinhardt, Sep 2, 2025
  112. 15/15 packfile: refactor `get_packed_git_mru()` to work on packfile storePatrick Steinhardt, Sep 2, 2025
  113. Junio C HamanoSep 2, 2025
  114. Taylor BlauSep 11, 2025
  115. Karthik NayakSep 9, 2025
  116. 00/15 packfile: carve out a new packfile storePatrick Steinhardt, Sep 9, 2025
  117. 01/15 packfile: introduce a new `struct packfile_store`Patrick Steinhardt, Sep 9, 2025
  118. 02/15 odb: move list of packfiles into `struct packfile_store`Patrick Steinhardt, Sep 9, 2025
  119. 03/15 odb: move initialization bit into `struct packfile_store`Patrick Steinhardt, Sep 9, 2025
  120. 04/15 odb: move packfile map into `struct packfile_store`Patrick Steinhardt, Sep 9, 2025
  121. 05/15 odb: move MRU list of packfiles into `struct packfile_store`Patrick Steinhardt, Sep 9, 2025
  122. 06/15 odb: move kept cache into `struct packfile_store`Patrick Steinhardt, Sep 9, 2025
  123. 07/15 packfile: reorder functions to avoid function declarationPatrick Steinhardt, Sep 9, 2025
  124. 08/15 packfile: refactor `prepare_packed_git()` to work on packfile storePatrick Steinhardt, Sep 9, 2025
  125. 09/15 packfile: split up responsibilities of `reprepare_packed_git()`Patrick Steinhardt, Sep 9, 2025
  126. 10/15 packfile: refactor `install_packed_git()` to work on packfile storePatrick Steinhardt, Sep 9, 2025
  127. 11/15 packfile: introduce function to load and add packfilesPatrick Steinhardt, Sep 9, 2025
  128. 12/15 packfile: move `get_multi_pack_index()` into "midx.c"Patrick Steinhardt, Sep 9, 2025
  129. 13/15 packfile: remove `get_packed_git()`Patrick Steinhardt, Sep 9, 2025
  130. Taylor BlauSep 11, 2025
  131. 14/15 packfile: refactor `get_all_packs()` to work on packfile storePatrick Steinhardt, Sep 9, 2025
  132. 15/15 packfile: refactor `get_packed_git_mru()` to work on packfile storePatrick Steinhardt, Sep 9, 2025
  133. Karthik NayakSep 10, 2025
  134. Taylor BlauSep 11, 2025
  135. Taylor BlauSep 11, 2025
  136. Patrick SteinhardtSep 15, 2025
  137. 00/15 packfile: carve out a new packfile storePatrick Steinhardt, Sep 15, 2025
  138. 01/15 packfile: introduce a new `struct packfile_store`Patrick Steinhardt, Sep 15, 2025
  139. Justin ToblerSep 17, 2025
  140. Patrick SteinhardtSep 23, 2025
  141. Justin ToblerSep 24, 2025
  142. 02/15 odb: move list of packfiles into `struct packfile_store`Patrick Steinhardt, Sep 15, 2025
  143. 03/15 odb: move initialization bit into `struct packfile_store`Patrick Steinhardt, Sep 15, 2025
  144. 04/15 odb: move packfile map into `struct packfile_store`Patrick Steinhardt, Sep 15, 2025
  145. Justin ToblerSep 17, 2025
  146. Patrick SteinhardtSep 23, 2025
  147. 05/15 odb: move MRU list of packfiles into `struct packfile_store`Patrick Steinhardt, Sep 15, 2025
  148. Justin ToblerSep 17, 2025
  149. 06/15 odb: move kept cache into `struct packfile_store`Patrick Steinhardt, Sep 15, 2025
  150. 07/15 packfile: reorder functions to avoid function declarationPatrick Steinhardt, Sep 15, 2025
  151. 08/15 packfile: refactor `prepare_packed_git()` to work on packfile storePatrick Steinhardt, Sep 15, 2025
  152. 09/15 packfile: split up responsibilities of `reprepare_packed_git()`Patrick Steinhardt, Sep 15, 2025
  153. Justin ToblerSep 17, 2025
  154. Patrick SteinhardtSep 23, 2025
  155. 10/15 packfile: refactor `install_packed_git()` to work on packfile storePatrick Steinhardt, Sep 15, 2025
  156. 11/15 packfile: introduce function to load and add packfilesPatrick Steinhardt, Sep 15, 2025
  157. 12/15 packfile: move `get_multi_pack_index()` into "midx.c"Patrick Steinhardt, Sep 15, 2025
  158. 13/15 packfile: refactor `get_packed_git()` to work on packfile storePatrick Steinhardt, Sep 15, 2025
  159. 14/15 packfile: refactor `get_all_packs()` to work on packfile storePatrick Steinhardt, Sep 15, 2025
  160. 15/15 packfile: refactor `get_packed_git_mru()` to work on packfile storePatrick Steinhardt, Sep 15, 2025
  161. 00/15 packfile: carve out a new packfile storePatrick Steinhardt, Sep 23, 2025
  162. 01/15 packfile: introduce a new `struct packfile_store`Patrick Steinhardt, Sep 23, 2025
  163. 02/15 odb: move list of packfiles into `struct packfile_store`Patrick Steinhardt, Sep 23, 2025
  164. 03/15 odb: move initialization bit into `struct packfile_store`Patrick Steinhardt, Sep 23, 2025
  165. 04/15 odb: move packfile map into `struct packfile_store`Patrick Steinhardt, Sep 23, 2025
  166. 05/15 odb: move MRU list of packfiles into `struct packfile_store`Patrick Steinhardt, Sep 23, 2025
  167. 06/15 odb: move kept cache into `struct packfile_store`Patrick Steinhardt, Sep 23, 2025
  168. 07/15 packfile: reorder functions to avoid function declarationPatrick Steinhardt, Sep 23, 2025
  169. 08/15 packfile: refactor `prepare_packed_git()` to work on packfile storePatrick Steinhardt, Sep 23, 2025
  170. 09/15 packfile: split up responsibilities of `reprepare_packed_git()`Patrick Steinhardt, Sep 23, 2025
  171. 10/15 packfile: refactor `install_packed_git()` to work on packfile storePatrick Steinhardt, Sep 23, 2025
  172. 11/15 packfile: introduce function to load and add packfilesPatrick Steinhardt, Sep 23, 2025
  173. 12/15 packfile: move `get_multi_pack_index()` into "midx.c"Patrick Steinhardt, Sep 23, 2025
  174. 13/15 packfile: refactor `get_packed_git()` to work on packfile storePatrick Steinhardt, Sep 23, 2025
  175. 14/15 packfile: refactor `get_all_packs()` to work on packfile storePatrick Steinhardt, Sep 23, 2025
  176. 15/15 packfile: refactor `get_packed_git_mru()` to work on packfile storePatrick Steinhardt, Sep 23, 2025
  177. Justin ToblerSep 24, 2025
  178. Junio C HamanoSep 25, 2025
  179. Patrick SteinhardtSep 26, 2025
  180. Taylor BlauSep 28, 2025
  181. Patrick SteinhardtSep 29, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.