Hello, [reproduced with rm 8.30 and current git head on ubuntu 20.04 amd64]
Whilst trying to answer https://unix.stackexchange.com/questions/505317/using-rm-one-file-system-to-only-delete-files-on-the-local-filesystem I noticed that "rm -rf --preserve-root=all some-dir" was not race-free. "some-dir", as the root of a filesystem could still be removed recursively if the filesystem is mounted after "rm" has checked that "some-dir" was not a mountpoint but before "rm" opens that directory. That can be reproduced with gdb: $ mkdir -p 1 2/dir $ gdb --quiet --args rm -rf --preserve-root=all --one-file-system 1 Reading symbols from rm... (gdb) break __fxstatat Breakpoint 1 at 0x25e0 (gdb) break __lxstat Breakpoint 2 at 0x2570 (gdb) break unlinkat Breakpoint 3 at 0x24d0 (gdb) r Starting program: /home/chazelas/install/cvs/coreutils/INSTALL.d/bin/rm -rf --preserve-root=all --one-file-system 1 Breakpoint 2, __GI___lxstat (vers=1, name=0x55555556350c "/", buf=0x7fffffffd820) at ../sysdeps/unix/sysv/linux/wordsize-64/lxstat.c:33 33 ../sysdeps/unix/sysv/linux/wordsize-64/lxstat.c: No such file or directory. (gdb) c Continuing. Breakpoint 1, __GI___fxstatat (vers=1, fd=-100, file=0x5555555705b0 "1", st=0x555555570520, flag=256) at ../sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c:36 36 ../sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c: No such file or directory. (gdb) c Continuing. Breakpoint 2, __GI___lxstat (vers=1, name=0x555555570700 "1/..", buf=0x7fffffffd7b0) at ../sysdeps/unix/sysv/linux/wordsize-64/lxstat.c:33 33 ../sysdeps/unix/sysv/linux/wordsize-64/lxstat.c: No such file or directory. (gdb) fin Run till exit from #0 __GI___lxstat (vers=1, name=0x555555570700 "1/..", buf=0x7fffffffd7b0) at ../sysdeps/unix/sysv/linux/wordsize-64/lxstat.c:33 0x000055555555839e in rm_fts (fts=0x55555556f200, ent=0x5555555704b0, x=0x7fffffffd900) at src/remove.c:473 473 if (!parent || lstat (parent, &statbuf)) Value returned is $1 = 0 (gdb) !bindfs --no-allow-other 2 1 (gdb) !ls 1 dir (gdb) c Continuing. Breakpoint 1, __GI___fxstatat (vers=1, fd=4, file=0x5555555706c0 "dir", st=0x555555570630, flag=256) at ../sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c:36 36 ../sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c: No such file or directory. (gdb) c Continuing. Breakpoint 3, unlinkat () at ../sysdeps/unix/syscall-template.S:78 78 ../sysdeps/unix/syscall-template.S: No such file or directory. (gdb) bt #0 unlinkat () at ../sysdeps/unix/syscall-template.S:78 #1 0x0000555555557ddc in excise (fts=0x55555556f200, ent=0x5555555705c0, x=0x7fffffffd900, is_dir=true) at src/remove.c:370 #2 0x0000555555558547 in rm_fts (fts=0x55555556f200, ent=0x5555555705c0, x=0x7fffffffd900) at src/remove.c:508 #3 0x000055555555892d in rm (file=0x7fffffffda58, x=0x7fffffffd900) at src/remove.c:608 #4 0x000055555555749d in main (argc=5, argv=0x7fffffffda38) at src/rm.c:370 (gdb) bindfs is a fuse-based file system to mount one directory over another. 2 is mounted over 1 after rm has compared the result of stat("1") and stat("1/.."), and we see unlink("1/dir") being done. It seems to me that race window could be closed if "." and ".." were compared after the directory is opened. -- Stephane