GNU bug report logs - #78245
rm -d fails to remove non-empty directory

Previous Next

Package: coreutils;

Reported by: Yannick Le Pennec <yannick.lepennec <at> live.fr>

Date: Sun, 4 May 2025 17:15:02 UTC

Severity: normal

Done: Paul Eggert <eggert <at> cs.ucla.edu>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 78245 in the body.
You can then email your comments to 78245 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-coreutils <at> gnu.org:
bug#78245; Package coreutils. (Sun, 04 May 2025 17:15:03 GMT) Full text and rfc822 format available.

Acknowledgement sent to Yannick Le Pennec <yannick.lepennec <at> live.fr>:
New bug report received and forwarded. Copy sent to bug-coreutils <at> gnu.org. (Sun, 04 May 2025 17:15:03 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Yannick Le Pennec <yannick.lepennec <at> live.fr>
To: bug-coreutils <at> gnu.org
Subject: rm -d fails to remove non-empty directory
Date: Sun, 04 May 2025 12:35:52 +0200
Dear Maintainer,

On CephFS, creating a snapshot is done suchly:
  $ mkdir .snap/snapshot-name

This creates a directory which contains a view of the current directory
at the time the snapshot was created, and is therefore non-empty if the
current directory was non-empty at that time. Its contents are immutable.

Removing a snapshot is done suchly:
  $ rmdir .snap/snapshot-name

This works fine even if .snap/snapshot-name is non-empty, as rmdir calls
rmdir(2) directly without trying to be smart, and the Ceph filesystem
understands what rmdir on a snapshot directory means: remove the snapshot.

One would naturally expect rm -d to behave *exactly the same* as rmdir,
but this isn't the case, because rm -d first does a getdents on the
directory, observes it is non-empty, and refuses to perform the removal.

From what I understand, this is non-compliant behavior per XCU rm 2.a. and 4.
and XSH remove():

https://pubs.opengroup.org/onlinepubs/9799919799/utilities/rm.html

> 2. If file is of type directory, the following steps shall be taken:
>   a. If neither the -R option nor the -r option is specified, but -d
>   is specified, rm shall proceed with step 3 for the current file.

> 4. rm shall perform actions equivalent to the remove() function defined
>   in the System Interfaces volume of POSIX.1-2024 called with a
>   pathname of the current file used as the path argument.

https://pubs.opengroup.org/onlinepubs/9799919799/functions/remove.html

>   If path names a directory, remove(path) shall be equivalent to rmdir(path)

In short:
   rm -d .snap/snapshot-name
shall be equivalent to:
   remove(".snap/snapshot-name")
which in turn shall be equivalent to:
   rmdir(".snap/snapshot-name")

Moreover other coreutils rm implementations (such as uutils or voreutils)
do not exhibit this bug and correctly remove non-empty directories.

Regards,

Yannick Le Pennec




Information forwarded to bug-coreutils <at> gnu.org:
bug#78245; Package coreutils. (Sun, 04 May 2025 18:02:01 GMT) Full text and rfc822 format available.

Message #8 received at 78245 <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
To: Yannick Le Pennec <yannick.lepennec <at> live.fr>, 78245 <at> debbugs.gnu.org
Subject: Re: bug#78245: rm -d fails to remove non-empty directory
Date: Sun, 4 May 2025 19:01:12 +0100
On 04/05/2025 11:35, Yannick Le Pennec wrote:
> Dear Maintainer,
> 
> On CephFS, creating a snapshot is done suchly:
>    $ mkdir .snap/snapshot-name
> 
> This creates a directory which contains a view of the current directory
> at the time the snapshot was created, and is therefore non-empty if the
> current directory was non-empty at that time. Its contents are immutable.
> 
> Removing a snapshot is done suchly:
>    $ rmdir .snap/snapshot-name
> 
> This works fine even if .snap/snapshot-name is non-empty, as rmdir calls
> rmdir(2) directly without trying to be smart, and the Ceph filesystem
> understands what rmdir on a snapshot directory means: remove the snapshot.
> 
> One would naturally expect rm -d to behave *exactly the same* as rmdir,
> but this isn't the case, because rm -d first does a getdents on the
> directory, observes it is non-empty, and refuses to perform the removal.
> 
>  From what I understand, this is non-compliant behavior per XCU rm 2.a. and 4.
> and XSH remove():
> 
> https://pubs.opengroup.org/onlinepubs/9799919799/utilities/rm.html
> 
>> 2. If file is of type directory, the following steps shall be taken:
>>    a. If neither the -R option nor the -r option is specified, but -d
>>    is specified, rm shall proceed with step 3 for the current file.
> 
>> 4. rm shall perform actions equivalent to the remove() function defined
>>    in the System Interfaces volume of POSIX.1-2024 called with a
>>    pathname of the current file used as the path argument.
> 
> https://pubs.opengroup.org/onlinepubs/9799919799/functions/remove.html
> 
>>    If path names a directory, remove(path) shall be equivalent to rmdir(path)
> 
> In short:
>     rm -d .snap/snapshot-name
> shall be equivalent to:
>     remove(".snap/snapshot-name")
> which in turn shall be equivalent to:
>     rmdir(".snap/snapshot-name")
> 
> Moreover other coreutils rm implementations (such as uutils or voreutils)
> do not exhibit this bug and correctly remove non-empty directories.
> 
> Regards,
> 
> Yannick Le Pennec

For reference this was also reported at:
https://bugs.debian.org/1104300




Reply sent to Paul Eggert <eggert <at> cs.ucla.edu>:
You have taken responsibility. (Mon, 06 Oct 2025 20:40:02 GMT) Full text and rfc822 format available.

Notification sent to Yannick Le Pennec <yannick.lepennec <at> live.fr>:
bug acknowledged by developer. (Mon, 06 Oct 2025 20:40:03 GMT) Full text and rfc822 format available.

Message #13 received at 78245-done <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Pádraig Brady <P <at> draigBrady.com>
Cc: Yannick Le Pennec <yannick.lepennec <at> live.fr>, 78245-done <at> debbugs.gnu.org
Subject: Re: bug#78245: rm -d fails to remove non-empty directory
Date: Mon, 6 Oct 2025 13:39:48 -0700
[Message part 1 (text/plain, inline)]
On 2025-05-04 11:01, Pádraig Brady wrote:
> 
> For reference this was also reported at:
> https://bugs.debian.org/1104300

I installed the attached patches (the second one is merely a minor 
performance improvement) and am marking the bug as done on 
debugs.gnu.org. Thanks, Yannick, for reporting it.
[0001-rm-make-rm-d-DIR-more-like-rmdir-DIR.patch (text/x-patch, attachment)]
[0002-rm-remove-redundant-mark_ancestor_dirs-call.patch (text/x-patch, attachment)]

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Tue, 04 Nov 2025 12:24:08 GMT) Full text and rfc822 format available.

This bug report was last modified 12 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.