bug#78245: rm -d fails to remove non-empty directory
Paul Eggert <[email protected]>
| Newsgroups | gmane.comp.gnu.core-utils.bugs |
|---|---|
| Organization | UCLA Computer Science Department |
| Message-ID | <[email protected]> |
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, 2.6 KB)
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
0002-rm-remove-redundant-mark_ancestor_dirs-call.patch
(text/x-patch, 877 B)
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