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

Re: [PATCH v2 13/17] remove_dir_recurse(): handle disappearing files and directories

From
Michael Haggerty <mhagger@alum.mit.edu>
Date
Jan 7, 2014, 10:07 UTC
Message-ID
<52CBD1D5.5080701@alum.mit.edu>
In-Reply-To
<xmqqy52tht2l.fsf@gitster.dls.corp.google.com>
On 01/06/2014 07:18 PM, Junio C Hamano wrote:
Show 29 quoted lines
> Michael Haggerty <mhagger@alum.mit.edu> writes:
> 
>> If a file or directory that we are trying to remove disappears (e.g.,
>> because another process has pruned it), do not consider it an error.
>>
>> Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
>> ---
>>  dir.c | 22 ++++++++++++++++------
>>  1 file changed, 16 insertions(+), 6 deletions(-)
>>
>> diff --git a/dir.c b/dir.c
>> index 11e1520..716b613 100644
>> --- a/dir.c
>> +++ b/dir.c
>> @@ -1476,7 +1476,9 @@ static int remove_dir_recurse(struct strbuf *path, int flag, int *kept_up)
>>  	flag &= ~REMOVE_DIR_KEEP_TOPLEVEL;
>>  	dir = opendir(path->buf);
>>  	if (!dir) {
>> -		if (errno == EACCES && !keep_toplevel)
>> +		if (errno == ENOENT)
>> +			return keep_toplevel ? -1 : 0;
> 
> If we were told that "foo/bar must go, but do not bother removing
> foo/", is it an error if foo itself did not exist?  I think this
> step does not change the behaviour from the original (we used to say
> "oh, we were told to keep_toplevel, and the top-level cannot be read
> for whatever reason, so it is an error"), but because this series is
> giving us a finer grained error diagnosis, we may want to think
> about it further, perhaps as a follow-up.

Indeed, this is a design choice that I should have explained. I implemented it this way to keep the behavior the same as the old code in this situation, and because I thought that if the caller explicitly asks for the toplevel path to be kept, and that path doesn't even exist at the entrance to the function, then something is screwy and it is better to return an error than to keep going.

It would even be possible to argue that if keep_toplevel is set but path is missing, then this function should call safe_create_leading_directories(path).

Changing this behavior would require an audit to see which behavior would be most useful to the callers. I think that is out of the scope of this patch series.

Show 14 quoted lines
> I also wonder why the keep-toplevel logic is in this "recurse" part
> of the callchain. If everything in "foo/bar/" can be removed but
> "foo/bar/" is unreadable, it is OK, when opendir("foo/bar") failed
> with EACCESS, to attempt to rmdir("foo/bar") whether we were told
> not to attempt removing "foo/", no?
> 
>> +		else if (errno == EACCES && !keep_toplevel)
> 
> That is, I am wondering why this part just checks !keep_toplevel,
> not
> 
> 	(!keep_toplevel || has_dir_separator(path->buf))
> 
> or something.

I'm not sure I understand your point. Please note that the REMOVE_DIR_KEEP_TOPLEVEL bit is cleared from flags before this function recurses. So in recursive invocations, keep_toplevel will always be false, and the rmdir(path->buf) codepath will be permitted. Does that answer your question?

Michael
-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
Previous: Junio C HamanoNext: Junio C Hamano
Message 22 of 29 in “Fix some mkdir/rmdir races”
  1. 00/17 Fix some mkdir/rmdir racesMichael Haggerty, Jan 6, 2014
  2. 01/17 safe_create_leading_directories(): fix format of "if" chainingMichael Haggerty, Jan 6, 2014
  3. 02/17 safe_create_leading_directories(): reduce scope of local variableMichael Haggerty, Jan 6, 2014
  4. 03/17 safe_create_leading_directories(): add explicit "slash" pointerMichael Haggerty, Jan 6, 2014
  5. Junio C HamanoJan 6, 2014
  6. Michael HaggertyJan 7, 2014
  7. Junio C HamanoJan 7, 2014
  8. Sebastian SchuberthJan 19, 2014
  9. 04/17 safe_create_leading_directories(): rename local variableMichael Haggerty, Jan 6, 2014
  10. 05/17 safe_create_leading_directories(): split on first of multiple slashesMichael Haggerty, Jan 6, 2014
  11. 06/17 safe_create_leading_directories(): always restore slash at end of loopMichael Haggerty, Jan 6, 2014
  12. 07/17 safe_create_leading_directories(): introduce enum for return valuesMichael Haggerty, Jan 6, 2014
  13. 08/17 cmd_init_db(): when creating directories, handle errors conservativelyMichael Haggerty, Jan 6, 2014
  14. 09/17 safe_create_leading_directories(): add new error value SCLD_VANISHEDMichael Haggerty, Jan 6, 2014
  15. 10/17 lock_ref_sha1_basic(): on SCLD_VANISHED, retryMichael Haggerty, Jan 6, 2014
  16. Junio C HamanoJan 6, 2014
  17. Michael HaggertyJan 7, 2014
  18. 11/17 lock_ref_sha1_basic(): if locking fails with ENOENT, retryMichael Haggerty, Jan 6, 2014
  19. 12/17 remove_dir_recurse(): tighten condition for removing unreadable dirMichael Haggerty, Jan 6, 2014
  20. 13/17 remove_dir_recurse(): handle disappearing files and directoriesMichael Haggerty, Jan 6, 2014
  21. Junio C HamanoJan 6, 2014
  22. Michael HaggertyJan 7, 2014
  23. Junio C HamanoJan 7, 2014
  24. 14/17 rename_ref(): extract function rename_tmp_log()Michael Haggerty, Jan 6, 2014
  25. 15/17 rename_tmp_log(): handle a possible mkdir/rmdir raceMichael Haggerty, Jan 6, 2014
  26. 16/17 rename_tmp_log(): limit the number of remote_empty_directories() attemptsMichael Haggerty, Jan 6, 2014
  27. 17/17 rename_tmp_log(): on SCLD_VANISHED, retryMichael Haggerty, Jan 6, 2014
  28. Junio C HamanoJan 6, 2014
  29. Michael HaggertyJan 7, 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.