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

Re: [PATCH v2 29/33] refs: resolve symbolic refs first

From
Jeff King <peff@peff.net>
Date
May 13, 2016, 12:51 UTC
Message-ID
<20160513125155.GA24031@sigill.intra.peff.net>
In-Reply-To
<5735C990.8080502@alum.mit.edu>
On Fri, May 13, 2016 at 02:33:20PM +0200, Michael Haggerty wrote:
Show 7 quoted lines
> The problem in this case is a misguided call to
> verify_refname_available_dir() in the case that read_raw_ref() fails
> with ENOENT. In that case it is not possible for there to be a conflict
> with another loose reference, because (1) we already hold the lock, so
> the containing directory must exist, and (2) we got ENOENT, so there
> can't be a loose reference in a subdirectory named after the reference
> that we are trying to create.
Right, that makes perfect sense.
Show 6 quoted lines
> As Peff explained, the call of verify_refname_available_dir() was
> forcing the loose tags to be loaded, which is expensive in this test
> because there are 100000 of them being created one at a time. (If they
> were created in a single ref_transaction instead, the "available" tests
> would all be done together, before any changes are committed, so the
> loose ref cache would not have to be invalidated each time.)

Yeah, I noticed that, too, and had to wonder whether we should make "fetch" do a single ref transaction. I think the thing blocking that (besides the obvious refactoring needed in fetch) is that transactions are currently all-or-nothing. And fetch right now will do its best to update whatever refs it can.

Show 6 quoted lines
> Please note that there are still some calls of
> verify_refname_available_dir() against the loose reference cache in this
> function. If we wanted to give up a little bit on the quality of our
> error messages, I think we could make those paths faster, too. But they
> are all in failure paths, so I don't think that they are performance
> critical, so I won't make that change.

That's probably fine. I think the most pathological case becomes a fetch a fetch where every other incoming ref is bogus. So, "refs/tags/2/nope", "refs/tags/2-ok". And there are 100K of those (or whatever large number you choose).

The bogus refs cause us to load the loose ref cache, and the successful ones cause us to discard it. The result is still quadratic (it's just n/2 squared). I have a hard time believing anybody would run into this situation in practice, but I do wonder if somebody could cause denial-of-service mischief. Probably not any more than they could cause by other means (like sending a nasty diff case).

-Peff
Previous: Jeff KingNext: Torsten Bögershausen
Message 36 of 51 in “Yet more preparation for reference backends”
  1. 00/33 Yet more preparation for reference backendsMichael Haggerty, May 6, 2016
  2. 01/33 t1404: demonstrate a bug resolving referencesMichael Haggerty, May 6, 2016
  3. 02/33 commit_ref(): if there is an empty dir in the way, delete itMichael Haggerty, May 6, 2016
  4. 03/33 read_raw_ref(): don't get confused by an empty directoryMichael Haggerty, May 6, 2016
  5. 04/33 safe_create_leading_directories(): improve docstringMichael Haggerty, May 6, 2016
  6. 05/33 remove_dir_recursively(): add docstringMichael Haggerty, May 6, 2016
  7. 06/33 refname_is_safe(): use skip_prefix()Michael Haggerty, May 6, 2016
  8. 07/33 refname_is_safe(): don't allow the empty stringMichael Haggerty, May 6, 2016
  9. 08/33 refname_is_safe(): insist that the refname already be normalizedMichael Haggerty, May 6, 2016
  10. 09/33 commit_ref_update(): write error message to *err, not stderrMichael Haggerty, May 6, 2016
  11. 10/33 rename_ref(): remove unneeded local variableMichael Haggerty, May 6, 2016
  12. 11/33 ref_transaction_commit(): remove local variable nMichael Haggerty, May 6, 2016
  13. 12/33 read_raw_ref(): rename flags argument to typeMichael Haggerty, May 6, 2016
  14. 13/33 read_raw_ref(): clear *type at start of functionMichael Haggerty, May 6, 2016
  15. 14/33 read_raw_ref(): rename symref argument to referentMichael Haggerty, May 6, 2016
  16. 15/33 read_raw_ref(): improve docstringMichael Haggerty, May 6, 2016
  17. 16/33 read_raw_ref(): move docstring to header fileMichael Haggerty, May 6, 2016
  18. 17/33 lock_ref_sha1_basic(): remove unneeded local variableMichael Haggerty, May 6, 2016
  19. 18/33 refs: make error messages more consistentMichael Haggerty, May 6, 2016
  20. 19/33 ref_transaction_create(): disallow recursive pruningMichael Haggerty, May 6, 2016
  21. 20/33 ref_transaction_commit(): correctly report close_ref() failureMichael Haggerty, May 6, 2016
  22. 21/33 delete_branches(): use resolve_refdup()Michael Haggerty, May 6, 2016
  23. 22/33 refs: allow log-only updatesMichael Haggerty, May 6, 2016
  24. 23/33 refs: don't dereference on renameMichael Haggerty, May 6, 2016
  25. 24/33 verify_refname_available(): adjust constness in declarationMichael Haggerty, May 6, 2016
  26. 25/33 add_update(): initialize the whole ref_updateMichael Haggerty, May 6, 2016
  27. 26/33 lock_ref_for_update(): new functionMichael Haggerty, May 6, 2016
  28. 27/33 unlock_ref(): move definition higher in the fileMichael Haggerty, May 6, 2016
  29. 28/33 ref_transaction_update(): check refname_is_safe() at a minimumMichael Haggerty, May 6, 2016
  30. 29/33 refs: resolve symbolic refs firstMichael Haggerty, May 6, 2016
  31. Jeff KingMay 12, 2016
  32. Jeff KingMay 12, 2016
  33. Michael HaggertyMay 13, 2016
  34. 29/33 refs: resolve symbolic refs firstMichael Haggerty, May 13, 2016
  35. Jeff KingMay 13, 2016
  36. Jeff KingMay 13, 2016
  37. Torsten BögershausenMay 14, 2016
  38. 30/33 lock_ref_for_update(): don't re-read non-symbolic referencesMichael Haggerty, May 6, 2016
  39. 31/33 lock_ref_for_update(): don't resolve symrefsMichael Haggerty, May 6, 2016
  40. 32/33 commit_ref_update(): remove the flags parameterMichael Haggerty, May 6, 2016
  41. 33/33 lock_ref_sha1_basic(): only handle REF_NODEREF modeMichael Haggerty, May 6, 2016
  42. David TurnerMay 9, 2016
  43. Junio C HamanoMay 9, 2016
  44. Michael HaggertyMay 9, 2016
  45. Junio C HamanoMay 9, 2016
  46. Jeff KingMay 12, 2016
  47. Junio C HamanoMay 12, 2016
  48. Junio C HamanoMay 10, 2016
  49. Michael HaggertyJun 10, 2016
  50. Junio C HamanoJun 10, 2016
  51. [ADDENDUM v4] Yet more preparation for reference backendsMichael Haggerty, Jun 13, 2016

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.