Code change:
Some(false) => { cvt(unsafe { unlinkat(fd, child.name_cstr().as_ptr(), 0) })?; } <del> None => match cvt(unsafe { unlinkat(fd, child.name_cstr().as_ptr(), 0) }) { // type unknown - try to unlink Err(err) if err.raw_os_error() == Some(libc::EISDIR) || err.raw_os_error() == Some(libc::EPERM) => { // if the file is a directory unlink fails with EISDIR on Linux and EPERM everyhwere else remove_dir_all_recursive(Some(fd), Path::new(&child.file_name()))?; } result => { result?; } }, </del> <ins> None => { // POSIX specifies that calling unlink()/unlinkat(..., 0) on a directory can succeed // if the process has the appropriate privileges. This however can causing orphaned // directories requiring an fsck e.g. on Solaris and Illumos. So we try recursing // into it first instead of trying to unlink() it. remove_dir_all_recursive(Some(fd), Path::new(&child.file_name()))?; } </ins> } }

Related discussion:
text: It was reported upstream, and we're working on a fix -- but that fix will obviously only be in new versions of the operating system. To expand further on the corruption: the file system becomes inconsistent and requires repair, and the damage such as it is can only be caused by privileged users; i.e., by root or a user with root equivalent privileges. I am not yet aware of a way that it would cause actual data loss, just an interruption to service, but anything is possible. Allowing the linking and unlinking of directories is a regrettable, but seemingly intentional feature we are saddled with through our UNIX heritage. I'm working to disable and eventually remove the feature in the OS -- although we strongly value backwards compatibility, in this case I can't really see a legitimate use case or find a consumer that would be broken by doing so, but we won't know for sure until we try. While this specific case is unfortunate, and we can and will work on our end to try to mitigate the impact, the fact remains that POSIX explicitly documents and allows for implementations where on a directory does not return . For the code to be completely correct on all POSIX systems, it cannot make that assumption. In addition, working around the issue in new versions of the OS doesn't fix existing deployments out there already. Enterprise customers are often reluctant to promptly update their operating system, even though they may update software built and deployed on it -- software that may be written in Rust. I myself hit this issue by upgrading only the Rust compiler to a new stable version, and trying to build and use Rust-based software we have to build UFS ramdisks on illumos. We aim to fix the OS for the future, but the critical regression in Rust needs to be fixed as well for the present. We appreciate everybody who has looked at this so far -- please let me know how I can help expedite the process!
Thanks again for the report. The linked PR should fix the issue. Apparently only and guarantee that trying to a directory fails. , and allow it, at least in theory. After looking around a bit I found that it is even explicitly documented for and . So it is not a bug but a feature there... After changing that in you might want to adapt the man page as well.