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

Re: [PATCH v2 3/4] packfile: recover object lookups racing a concurrent repack

From
Jeff King <peff@peff.net>
Date
Aug 29, 2026, 11:32 UTC
Message-ID
<20260829113257.GC40814@coredump.intra.peff.net>
In-Reply-To
<CABPp-BEmReAR-f-aweM=f=5QhRPxG1K-KLTsbyRt2aDQD_QnVA@mail.gmail.com>
On Thu, Aug 27, 2026 at 03:23:30PM -0700, Elijah Newren wrote:
Show 10 quoted lines
> It's far more likely that I am the one being dense.  My rough line of thinking:
> 
> * We see "packfile ... index unavailable" in our logging
> * There's only one thing that remove packfiles
> * Investigate the mechanism
> * Look for other affected callers (e.g. mktree --batch)
> * Consider corrective measures
> 
> Steps 1-4 above are probably fine, and step 5 may have been where I
> went off the rails.  My thinking there, wrong or right, was:

I think we should consider the log message independently from whether we eventually return a value (whether QUICK or not). It seems like the log message is often unnecessarily scary, because we either recover via SECOND_READ, or we are in QUICK mode and the false negative is OK. So the message is informative at best, and probably just noise in those cases.

But it perhaps _is_ helpful when a non-QUICK lookup ends up returning failure. We'll end up with some other error() message, but it may be useful context to know that we _thought_ we had the object available and then the rug was pulled out from under us. But we don't have a good way of queuing up an error that is shown conditionally.

So I dunno. We could consider moving that message into trace/trace2, making it more of a "debug" message. And then people digging into a problem can turn on traces. But I have a feeling that is not very helpful, since it is mostly a racy situation (so you can't just easily replay your failure with tracing turned on).

> * It makes sense that we don't want to reprepare most of the time
> * ...but _if_ we know of the existence of some specific packfile in
> this process and that packfile has since disappeared by the time we go
> to open or read it, is that a special case?  Should it be?

So now we can consider the actual return value, aside from the logged message. For non-QUICK requests, I think this case is uninteresting (we already do a reprepare and follow-up read). For mktree, I think the core of the problem is using QUICK when it should not.

I think the current behavior of QUICK is _correct_, in the sense that false negatives are OK. But can we make it better? Possibly. To me the argument for this patch's direction is something like:

  The point of QUICK was to avoid lots of reprepare effort when we are
  looking up objects that we might reasonably not have. This has
  historically been about things like fetch speculatively looking for
  stuff the other side mentioned. But there we are mostly concerned
  about objects we _never_ had, and avoiding tons of reprepare work that
  will almost certainly not help us. But in some races, we might learn
  that we _did_ have the object at one point (because we opened its idx,
  or a midx) but the lookup still failed (because the pack couldn't be
  accessed).
  We can cheaply notice this case by differentiating true idx misses
  from failure to access the pack contents. And these items _are_ worth
  a reprepare, because they were almost certainly caused by a repacking
  race (or a true repo corruption or object pruning, but that is rare
  enough not to worry about for optimization purposes).
  So even though QUICK is not _wrong_ to say "we do not have that
  object", it is a good tradeoff to spend a little bit of time calling
  reprepare in order to produce fewer false negative "no such object"
  responses (because tools like fetch then have a chance to optimize
  their own task more as a result).

Maybe that argument was somewhere in your original commit message. I admit I got lost about half-way through. ;)

But I think the key thing is separating:
  - is the logging confusing or useful? What should we do about it?
  - is mktree racily broken because of QUICK? I think so.
  - even though QUICK is not wrong to skip the second read for this
    case, it might be a good tradeoff for it to detect and try harder
    here (i.e., the argument above).

Which sounds like three patches to me, each of which can be motivated and argued on its own.

Show 10 quoted lines
> > So I don't see QUICK itself here violating any contract (even if it
> > _could_ find the object in some cases with just a little more work, as
> > in the case that we were discussing for v1).
> 
> I'll drop this patch and instead send a small mktree change that stops
> passing OBJECT_INFO_QUICK (keeping SKIP_FETCH_OBJECT), so mktree
> recovers via the normal reprepare like every other non-QUICK reader.
> That removes the packfile.c changes entirely, so both the
> reload-under-QUICK hack and the .idx/.pack raciness you noted in
> pack_index_is_missing() go away with them.

I am also happy with this direction. Then we can consider the other questions separately (or not at all if nobody cares enough).

-Peff
Previous: Elijah NewrenNext: Elijah Newren via GitGitGadget
Message 30 of 49 in “Objects treated as missing despite being present, due to race with geometric repacking”
  1. 0/2 Objects treated as missing despite being present, due to race with geometric repackingElijah Newren via GitGitGadget, Aug 18, 2026
  2. 1/2 replay: fail gracefully when a merge input is unreadableElijah Newren via GitGitGadget, Aug 18, 2026
  3. Junio C HamanoAug 19, 2026
  4. Elijah NewrenAug 21, 2026
  5. Junio C HamanoAug 21, 2026
  6. 2/2 packfile: recover when a multi-pack-index names a removed packElijah Newren via GitGitGadget, Aug 18, 2026
  7. Junio C HamanoAug 19, 2026
  8. Patrick SteinhardtAug 20, 2026
  9. Elijah NewrenAug 21, 2026
  10. Jeff KingAug 24, 2026
  11. Patrick SteinhardtAug 24, 2026
  12. Jeff KingAug 24, 2026
  13. Jeff KingAug 24, 2026
  14. Jeff KingAug 24, 2026
  15. Elijah NewrenAug 25, 2026
  16. Jeff KingAug 24, 2026
  17. Patrick SteinhardtAug 24, 2026
  18. Jeff KingAug 24, 2026
  19. Elijah NewrenAug 25, 2026
  20. Derrick StoleeAug 24, 2026
  21. Elijah NewrenAug 25, 2026
  22. Derrick StoleeAug 24, 2026
  23. 0/4 Objects treated as missing despite being present, due to race with geometric repackingElijah Newren via GitGitGadget, Aug 25, 2026
  24. 1/4 replay: fail gracefully when a merge input is unreadableElijah Newren via GitGitGadget, Aug 25, 2026
  25. 2/4 mktree: plug per-tree leak in --batch modeElijah Newren via GitGitGadget, Aug 25, 2026
  26. Jeff KingAug 27, 2026
  27. 3/4 packfile: recover object lookups racing a concurrent repackElijah Newren via GitGitGadget, Aug 25, 2026
  28. Jeff KingAug 27, 2026
  29. Elijah NewrenAug 27, 2026
  30. Jeff KingAug 29, 2026
  31. 4/4 packfile: recover when a multi-pack-index names a removed packElijah Newren via GitGitGadget, Aug 25, 2026
  32. Jeff KingAug 27, 2026
  33. Elijah NewrenAug 28, 2026
  34. Jeff KingAug 29, 2026
  35. 0/4 Objects treated as missing despite being present, due to race with geometric repackingElijah Newren via GitGitGadget, Aug 29, 2026
  36. 1/4 replay: fail gracefully when a merge input is unreadableElijah Newren via GitGitGadget, Aug 29, 2026
  37. 2/4 mktree: plug per-tree leak in --batch modeElijah Newren via GitGitGadget, Aug 29, 2026
  38. 3/4 mktree: do not use OBJECT_INFO_QUICK when checking objectsElijah Newren via GitGitGadget, Aug 29, 2026
  39. Jeff KingAug 29, 2026
  40. 4/4 packfile: recover when a multi-pack-index names a removed packElijah Newren via GitGitGadget, Aug 29, 2026
  41. Jeff KingAug 29, 2026
  42. Junio C HamanoAug 30, 2026
  43. Patrick SteinhardtAug 31, 2026
  44. Jeff KingAug 31, 2026
  45. Derrick StoleeSep 1, 2026
  46. Junio C HamanoSep 1, 2026
  47. Derrick StoleeSep 1, 2026
  48. Elijah NewrenSep 1, 2026
  49. Derrick StoleeSep 1, 2026

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.