Re: [RFC v1] man/man2/close.2: CAVEATS: Document divergence from POSIX.1-2024
From: The 8472 <hidden>
Date: 2026-01-24 19:34:19
Also in:
linux-fsdevel
On 23/01/2026 01:33, Zack Weinberg wrote: [...]
ERRORS
EBADF The fd argument was not a valid, open file descriptor.Unfortunately EBADF from FUSE is passed through unfiltered by the kernel on close[0], that makes it more difficult to reliably detect bugs relating to double-closes of file descriptors. [...]
Delayed errors reported by close()
In a variety of situations, most notably when writing to a file
that is hosted on a network file server, write(2) operations may
“optimistically” return successfully as soon as the write has
been queued for processing.
close(2) waits for confirmation that *most* of the processing
for previous writes to a file has been completed, and reports
any errors that the earlier write() calls *would have* reported,
if they hadn’t returned optimistically. Especially, close()
will report “disk full” (ENOSPC) and “disk quota exceeded”
(EDQUOT) errors that write() didn’t wait for.
(To wait for *all* processing to complete, it is necessary to
use fsync(2) as well.)
Because of these delayed errors, it’s important to check the
return value of close() and handle any errors it reports.
Ignoring delayed errors can cause silent loss of data.
However, when handling delayed errors, keep in mind that the
close() call should *not* be repeated. When close() has a
delayed error to report, it still closes the file before
returning. The file descriptor number might already have been
reused for some other file, especially in multithreaded
programs. To make another attempt at the failed writes, it’s
necessary to reopen the file and start all over again.
[QUERY: Do delayed errors ever happen in any of these situations?
- The fd is not the last reference to the open file description
- The OFD was opened with O_RDONLY
- The OFD was opened with O_RDWR but has never actually
been written to
- No data has been written to the OFD since the last call to
fsync() for that OFD
- No data has been written to the OFD since the last call to
fdatasync() for that OFD
If we can give some guidance about when people don’t need to
worry about delayed errors, it would be helpful.]The Rust standard library team is also interested in this topic, there is lively discussion[1] whether it makes sense to surface errors from close at all. Our current default is to ignore them. It is my understanding that errors may not have happened yet at the time of close due to delayed writeback or additional descriptors pointing to the description, e.g. in a forked child, and thus close() is not a reliable mechanism for error detection and fsync() is the only available option. Some users do care specifically about the unusual behavior on NFS, and don't want to use a heavy hammer like fsync. It's unfortunate that there's no middle ground to get errors on an open file descriptor or initiate the NFS flush behavior without a full fsync. [0] https://lore.kernel.org/linux-fsdevel/1b946a20-5e8a-497e-96ef-f7b1e037edcb@infinite-source.de/ (local) [1] https://github.com/rust-lang/libs-team/issues/705