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.From bae32db8fead1134e4ce5804f61ec094cf2cad0b Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email protected]>
Date: Mon, 6 Oct 2025 13:31:48 -0700
Subject: [PATCH 1/2] =?UTF-8?q?rm:=20make=20=E2=80=98rm=20-d=20DIR?=
=?UTF-8?q?=E2=80=99=20more=20like=20=E2=80=98rmdir=20DIR=E2=80=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* src/remove.c (rm_fts): When not recursive,
arrange for ‘rm -d DIR’ to behave more like ‘rmdir DIR’.
This works better for Ceph snapshot directories.
Problem reported by Yannick Le Pennec (bug#78245).
---
NEWS | 4 ++++
src/remove.c | 18 ++++++++----------
2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/NEWS b/NEWS
index 428262deb..d5946ced9 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,10 @@ GNU coreutils NEWS -*- outline -*-
for all length adjustable algorithms (blake2b, sha2, sha3).
[bug introduced in coreutils-9.2]
+ 'rm -d DIR' no longer fails on Ceph snapshot directories.
+ Although these directories are nonempty, 'rmdir DIR' succeeds on them.
+ [bug introduced in coreutils-8.16]
+
'tail' outputs the correct number of lines again for non-small -n values.
Previously it may have output too few lines.
[bug introduced in coreutils-9.8]
diff --git a/src/remove.c b/src/remove.c
index 079b00fc1..f50276efd 100644
--- a/src/remove.c
+++ b/src/remove.c
@@ -446,18 +446,16 @@ rm_fts (FTS *fts, FTSENT *ent, struct rm_options const *x)
switch (ent->fts_info)
{
case FTS_D: /* preorder directory */
- if (! x->recursive
- && !(x->remove_empty_directories
- && get_dir_status (fts, ent, &dir_status) != 0))
+ if (!x->recursive)
{
- /* This is the first (pre-order) encounter with a directory
- that we cannot delete.
- Not recursive, and it's not an empty directory (if we're removing
- them) so arrange to skip contents. */
- int err = x->remove_empty_directories ? ENOTEMPTY : EISDIR;
- error (0, err, _("cannot remove %s"), quoteaf (ent->fts_path));
+ /* Not recursive, so skip contents, and fail now unless
+ removing empty directories. */
+ fts_set (fts, ent, FTS_SKIP);
+ if (x->remove_empty_directories)
+ return RM_OK;
+ error (0, EISDIR, _("cannot remove %s"), quoteaf (ent->fts_path));
mark_ancestor_dirs (ent);
- fts_skip_tree (fts, ent);
+ ignore_value (fts_read (fts));
return RM_ERROR;
}
--
2.48.1
From 311c04c0596a61761790b1c0a5fa99ec59796e14 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email protected]>
Date: Mon, 6 Oct 2025 13:36:40 -0700
Subject: [PATCH 2/2] rm: remove redundant mark_ancestor_dirs call
* src/remove.c (rm_fts): Remove unnecessary call. Since this code
is executed only when not recursive, there are no ancestors to mark.
---
src/remove.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/remove.c b/src/remove.c
index f50276efd..86226b1d3 100644
--- a/src/remove.c
+++ b/src/remove.c
@@ -454,7 +454,6 @@ rm_fts (FTS *fts, FTSENT *ent, struct rm_options const *x)
if (x->remove_empty_directories)
return RM_OK;
error (0, EISDIR, _("cannot remove %s"), quoteaf (ent->fts_path));
- mark_ancestor_dirs (ent);
ignore_value (fts_read (fts));
return RM_ERROR;
}
--
2.48.1