]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
rm: make ‘rm -d DIR’ more like ‘rmdir DIR’
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 6 Oct 2025 20:31:48 +0000 (13:31 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 6 Oct 2025 20:37:21 +0000 (13:37 -0700)
* 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
src/remove.c

diff --git a/NEWS b/NEWS
index 428262debf8b3f2e68708e3ab208f9aeda11620b..d5946ced93895ffba7d8260ebdde27ff52b920d1 100644 (file)
--- 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]
index 079b00fc10e4e73c998bd5a01bdd47281df45973..f50276efd78bbea9a14b59d37fc2a66424547867 100644 (file)
@@ -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;
         }