Subject: bug#18491: rm -r fails to delete entire hierarchy when path goes in and out of it

From: Bob Proulx <[email-masked]>
Date: Thu, 18 Sep 2014 15:28:01 -0600

Gian Ntzik wrote:
> It seems that using rm -r with a path that goes into a (non-empty)
> directory intended for removal (and back up e.g. using dot-dots) fails
> to remove the directory. The directory is rendered empty, but itself not
> removed.
> 
> For example,
> 
> $ mkdir -p /tmp/a/b/c
> $ mkdir -p /tmp/a/e
> $ rm -r /tmp/a/b/../../a
> rm: cannot remove ‘/tmp/a/b/../../a’: No such file or directory

I don't think this can reasonably be called a bug.  A depth first
removal is required.  a/b must be removed before a is removed.  But
the relative reference requires a/b to exist in order to obtain
b/.. in order to obtain b/../.. in order to obtain b/../../a but a/b
gets removed first since a depth first removal is required.

Trying to do anything to work around this seems wrong to me since it
will require keeping track of the state before and simulating to
create the desired state afterward and then applying a derived state
change to the file system.  That is much too complex for this simple
operation.

> Obviously, once the contents of /tmp/a have been removed, the path
> /tmp/a/b/../../a is no longer resolvable. However, the same applies for
> any sub-directory of /tmp/a. For example, once /tmp/a/b has been
> removed, /tmp/a/b/../../a/e is also no longer resolvable. It seems that
> rm -r takes care to avoid such issues during recursion but fails to do
> so at the very end.

I don't think it matters that a/e and a/b do actually get removed
revealing that in the implementation some ordering is happening.
Regardless of that I don't think it is reasonable to require that rm
remember the old path through a relative path that gets removed along
the way.

Bob