git: ac4b39441773 - stable/15 - rm(1): remove whiteouts when forcibly removing directories

From: Jason A. Harmening <jah_at_FreeBSD.org>
Date: Sun, 16 Nov 2025 03:52:07 UTC
The branch stable/15 has been updated by jah:

URL: https://cgit.FreeBSD.org/src/commit/?id=ac4b39441773bc0d43f9d1aff9b0f82d83a9a97e

commit ac4b39441773bc0d43f9d1aff9b0f82d83a9a97e
Author:     Jason A. Harmening <jah@FreeBSD.org>
AuthorDate: 2025-11-08 04:23:02 +0000
Commit:     Jason A. Harmening <jah@FreeBSD.org>
CommitDate: 2025-11-16 03:51:26 +0000

    rm(1): remove whiteouts when forcibly removing directories
    
    Commit 2ed053cde5 changed UFS' VOP_RMDIR() behavior to no longer
    ignore whiteouts when determining whether a directory is empty,
    unless explicitly requested by the caller.  However, this also
    necessitates a change to rm(1) to avoid breaking the expected
    behavior when forcibly removing directory hierarchies via `rm -fr`.
    I neglected to make this follow-on change despite discussing it
    in the review for the breaking commit (D45987).
    
    Finally address the breakage by making `rm -fr` imply FTS_WHITEOUT
    when rm(1) reads directory contents via fts_read(3).  While here,
    also fix a logic error which produces a spurious 'No error' warning
    message on stdout for each deleted whiteout.
    
    Reported by:    csjp
    Reviewed by:    csjp, kib, olce
    Differential Revision:  https://reviews.freebsd.org/D53640
    
    (cherry picked from commit 8b92a6ad597e224b616a8b1d6983f3b55c85308e)
---
 bin/rm/rm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bin/rm/rm.c b/bin/rm/rm.c
index 16bbf7403fd4..2c41d7380cea 100644
--- a/bin/rm/rm.c
+++ b/bin/rm/rm.c
@@ -184,7 +184,7 @@ rm_tree(char **argv)
 	flags = FTS_PHYSICAL;
 	if (!needstat)
 		flags |= FTS_NOSTAT;
-	if (Wflag)
+	if (Wflag || fflag)
 		flags |= FTS_WHITEOUT;
 	if (xflag)
 		flags |= FTS_XDEV;
@@ -273,7 +273,7 @@ rm_tree(char **argv)
 
 			case FTS_W:
 				rval = undelete(p->fts_accpath);
-				if (rval == 0 && (fflag && errno == ENOENT)) {
+				if (rval == 0 || (fflag && errno == ENOENT)) {
 					if (vflag)
 						(void)printf("%s\n",
 						    p->fts_path);