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

Re: [PATCH v5 23/35] lockfile: avoid transitory invalid states

From
Jonathan Nieder <jrnieder@gmail.com>
Date
Sep 16, 2014, 22:45 UTC
Message-ID
<20140916224523.GW29050@google.com>
In-Reply-To
<1410896036-12750-24-git-send-email-mhagger@alum.mit.edu>
Michael Haggerty wrote:
Show 8 quoted lines
> We could probably continue to use the filename field to encode the
> state by being careful to write characters 1..N-1 of the filename
> first, and then overwrite the NUL at filename[0] with the first
> character of the filename, but that would be awkward and error-prone.
> 
> So, instead of using the filename field to determine whether the
> lock_file object is active, add a new field "lock_file::active" for
> this purpose.
Nice.
[...]
Show 10 quoted lines
> --- a/cache.h
> +++ b/cache.h
> @@ -576,6 +576,7 @@ extern int refresh_index(struct index_state *, unsigned int flags, const struct
>  
>  struct lock_file {
>  	struct lock_file *next;
> +	volatile sig_atomic_t active;
>  	int fd;
>  	pid_t owner;
>  	char on_list;
[...]
> +++ b/lockfile.c
> @@ -27,16 +27,19 @@
[...]
Show 7 quoted lines
> @@ -189,9 +198,14 @@ static int lock_file(struct lock_file *lk, const char *path, int flags)
>  		atexit(remove_lock_file);
>  	}
>  
> +	if (lk->active)
> +		die("BUG: lock_file(\"%s\") called with an active lock_file object",
> +		    path);

The error message doesn't make it entirely obvious to me what went wrong.

Maybe something like
		die("BUG: cannot lock_file(\"%s\") on active struct lock_file",
		    path);

lock_file already assumed on_list was initialized to zero but it wasn't particularly obvious since everything else is blindly scribbled over. Probably worth mentioning in the API docs that the lock_file should be zeroed before calling hold_lock_file_...

[...]
Show 6 quoted lines
> @@ -326,6 +341,7 @@ int commit_lock_file(struct lock_file *lk)
>  	if (rename(lk->filename, result_file))
>  		goto rollback;
>  
> +	lk->active = 0;
>  	lk->filename[0] = 0;
Is it useful to set filename[0] any more?

It seems potentially fragile to set both, since new code can appear that only sets or checks one or the other. Would it make sense to rename the filename field to make sure no new callers relying on the filename[0] convention sneak in (with the new convention being that the filename doesn't get cleared, to avoid problems)?

Jonathan
Previous: Michael HaggertyNext: Michael Haggerty
Message 60 of 73 in “Lockfile correctness and refactoring”
  1. 00/35 Lockfile correctness and refactoringMichael Haggerty, Sep 16, 2014
  2. 01/35 unable_to_lock_die(): rename function from unable_to_lock_index_die()Michael Haggerty, Sep 16, 2014
  3. Jonathan NiederSep 16, 2014
  4. 02/35 api-lockfile: expand the documentationMichael Haggerty, Sep 16, 2014
  5. Jonathan NiederSep 16, 2014
  6. Michael HaggertySep 22, 2014
  7. 03/35 rollback_lock_file(): do not clear filename redundantlyMichael Haggerty, Sep 16, 2014
  8. Jonathan NiederSep 16, 2014
  9. 04/35 rollback_lock_file(): exit early if lock is not activeMichael Haggerty, Sep 16, 2014
  10. Jonathan NiederSep 16, 2014
  11. 05/35 rollback_lock_file(): set fd to -1Michael Haggerty, Sep 16, 2014
  12. Jonathan NiederSep 16, 2014
  13. Jonathan NiederSep 16, 2014
  14. Michael HaggertySep 17, 2014
  15. 06/35 lockfile: unlock file if lockfile permissions cannot be adjustedMichael Haggerty, Sep 16, 2014
  16. Jonathan NiederSep 16, 2014
  17. 07/35 hold_lock_file_for_append(): release lock on errorsMichael Haggerty, Sep 16, 2014
  18. Jonathan NiederSep 16, 2014
  19. Michael HaggertySep 17, 2014
  20. 08/35 lock_file(): always add lock_file object to lock_file_listMichael Haggerty, Sep 16, 2014
  21. Jonathan NiederSep 16, 2014
  22. Michael HaggertySep 17, 2014
  23. Torsten BögershausenSep 18, 2014
  24. Michael HaggertySep 18, 2014
  25. 09/35 lockfile.c: document the various states of lock_file objectsMichael Haggerty, Sep 16, 2014
  26. Jonathan NiederSep 16, 2014
  27. Michael HaggertySep 22, 2014
  28. Jonathan NiederSep 22, 2014
  29. 10/35 cache.h: define constants LOCK_SUFFIX and LOCK_SUFFIX_LENMichael Haggerty, Sep 16, 2014
  30. Jonathan NiederSep 16, 2014
  31. Michael HaggertySep 22, 2014
  32. 11/35 delete_ref_loose(): don't muck around in the lock_file's filenameMichael Haggerty, Sep 16, 2014
  33. Jonathan NiederSep 16, 2014
  34. 12/35 prepare_index(): declare return value to be (const char *)Michael Haggerty, Sep 16, 2014
  35. Jonathan NiederSep 16, 2014
  36. 13/35 write_packed_entry_fn(): convert cb_data into a (const int *)Michael Haggerty, Sep 16, 2014
  37. 14/35 lock_file(): exit early if lockfile cannot be openedMichael Haggerty, Sep 16, 2014
  38. Jonathan NiederSep 16, 2014
  39. 15/35 remove_lock_file(): call rollback_lock_file()Michael Haggerty, Sep 16, 2014
  40. Jonathan NiederSep 16, 2014
  41. 16/35 commit_lock_file(): inline temporary variableMichael Haggerty, Sep 16, 2014
  42. Jonathan NiederSep 16, 2014
  43. 17/35 commit_lock_file(): die() if called for unlocked lockfile objectMichael Haggerty, Sep 16, 2014
  44. Jonathan NiederSep 16, 2014
  45. 18/35 commit_lock_file(): if close fails, roll backMichael Haggerty, Sep 16, 2014
  46. Jonathan NiederSep 16, 2014
  47. Michael HaggertySep 23, 2014
  48. 19/35 commit_lock_file(): rollback lock file on failure to renameMichael Haggerty, Sep 16, 2014
  49. Jonathan NiederSep 16, 2014
  50. Michael HaggertySep 23, 2014
  51. 20/35 api-lockfile: document edge casesMichael Haggerty, Sep 16, 2014
  52. Jonathan NiederSep 16, 2014
  53. Michael HaggertySep 23, 2014
  54. 21/35 dump_marks(): remove a redundant call to rollback_lock_file()Michael Haggerty, Sep 16, 2014
  55. Jonathan NiederSep 16, 2014
  56. 22/35 git_config_set_multivar_in_file(): avoid call to rollback_lock_file()Michael Haggerty, Sep 16, 2014
  57. Jonathan NiederSep 16, 2014
  58. Michael HaggertySep 23, 2014
  59. 23/35 lockfile: avoid transitory invalid statesMichael Haggerty, Sep 16, 2014
  60. Jonathan NiederSep 16, 2014
  61. Michael HaggertySep 23, 2014
  62. 24/35 struct lock_file: declare some fields volatileMichael Haggerty, Sep 16, 2014
  63. 25/35 try_merge_strategy(): remove redundant lock_file allocationMichael Haggerty, Sep 16, 2014
  64. 26/35 try_merge_strategy(): use a statically-allocated lock_file objectMichael Haggerty, Sep 16, 2014
  65. 27/35 commit_lock_file(): use a strbuf to manage temporary spaceMichael Haggerty, Sep 16, 2014
  66. 28/35 Change lock_file::filename into a strbufMichael Haggerty, Sep 16, 2014
  67. 29/35 resolve_symlink(): use a strbuf for internal scratch spaceMichael Haggerty, Sep 16, 2014
  68. 30/35 resolve_symlink(): take a strbuf parameterMichael Haggerty, Sep 16, 2014
  69. 31/35 trim_last_path_component(): replace last_path_elm()Michael Haggerty, Sep 16, 2014
  70. 32/35 Extract a function commit_lock_file_to()Michael Haggerty, Sep 16, 2014
  71. 33/35 Rename LOCK_NODEREF to LOCK_NO_DEREFMichael Haggerty, Sep 16, 2014
  72. 34/35 lockfile.c: rename static functionsMichael Haggerty, Sep 16, 2014
  73. 35/35 get_locked_file_path(): new functionMichael Haggerty, Sep 16, 2014

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.