[RFC v1] man/man2/close.2: CAVEATS: Document divergence from POSIX.1-2024

Jeff Layton jlayton@kernel.org
Tue Jan 27 00:49:28 GMT 2026


On Mon, 2026-01-26 at 17:01 -0600, Trevor Gross wrote:
> On Mon Jan 26, 2026 at 10:43 AM CST, Jeff Layton wrote:
> > On Mon, 2026-01-26 at 16:56 +0100, Jan Kara wrote:
> > > On Mon 26-01-26 14:53:12, The 8472 wrote:
> > > > On 26/01/2026 13:15, Jan Kara wrote:
> > > > > On Sun 25-01-26 10:37:01, Zack Weinberg wrote:
> > > > > > On Sat, Jan 24, 2026, at 4:57 PM, The 8472 wrote:
> > > > > > > >       [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.]
> > > > > > 
> > > > > > In particular, I really hope delayed errors *aren’t* ever reported
> > > > > > when you close a file descriptor that *isn’t* the last reference
> > > > > > to its open file description, because the thread-safe way to close
> > > > > > stdout without losing write errors[2] depends on that not happening.
> > > > > 
> > > > > So I've checked and in Linux ->flush callback for the file is called
> > > > > whenever you close a file descriptor (regardless whether there are other
> > > > > file descriptors pointing to the same file description) so it's upto
> > > > > filesystem implementation what it decides to do and which error it will
> > > > > return... Checking the implementations e.g. FUSE and NFS *will* return
> > > > > delayed writeback errors on *first* descriptor close even if there are
> > > > > other still open descriptors for the description AFAICS.
> > 
> > ...and I really wish they _didn't_.
> > 
> > Reporting a writeback error on close is not particularly useful. Most
> > filesystems don't require you to write back all data on a close(). A
> > successful close() on those just means that no error has happened yet.
> > 
> > Any application that cares about writeback errors needs to fsync(),
> > full stop.
> 
> Is there a good middle ground solution here?
> 
> It seems reasonable that an application may want to have different
> handling for errors expected during normal operation, such as temporary
> network failure with NFS, compared to more catastrophic things like
> failure to write to disk. The reason cited around [1] for avoiding fsync
> is that it comes with a cost that, for many applications, may not be
> worth it unless you are dealing with NFS.
> 
> I was wondering if it could be worth a new fnctl that provides this kind
> of "best effort" error checking behavior without having the strict
> requirements of fsync. In effect, to report the errors that you might
> currently get at close() before actually calling close() and losing the
> fd.
> 

For a long-held fd, I can see the appeal: spray writes at it and just
check occasionally (without blocking) that nothing has gone wrong.
Maybe when things are idle, you fsync().

A new fcntl(..., F_CHECKERR, ...) command that does a
file_check_and_advance_wb_err() on the fd and reports the result would
be pretty straightforward.

Would that be helpful for your use-case? This would be like a non-
blocking fsync that just reports whether an error has occurred since
the last F_CHECKERR or fsync().

> Alternatively, it would be interesting to have a deferred fsync() that
> schedules a nonblocking sync event that can be polled for completion/
> errors, with flags to indicate immediate sync or allow automatic syncing
> as needed. But there is probably a better alternative to this
> complexity.
> 
> [1]: https://github.com/rust-lang/libs-team/issues/705


Aside from the polling, I suppose you could effectively do this with
io_uring. I'm pretty sure you can issue an fsync() or sync_file_range()
that way, but I think it just ends up blocking a kernel thread until
writeback is done.

We've had people ask for a non-blocking fsync before. Maybe it's time
to get serious about adding one. What would such a thing look like?

It would be pretty simple to add a new fcntl(..., F_DATAWRITE) command
that kicks off writeback a'la filemap_fdatawrite().

Then add fcntl(..., F_WB_CHECK):

That could do a non-blocking version of filemap_fdatawait(), and return
whether any folios are still under writeback. If there is a writeback
error, it can return that instead.

The catch of course is that a polling mechanism like this could easily
livelock. If there is a lot of memory pressure, it might always return
that something is still under writeback, no matter how often you hammer
F_CHECKERR.

Maybe that's ok? You can always issue a blocking fsync() if you really
need to know draw a line in the sand.
-- 
Jeff Layton <jlayton@kernel.org>


More information about the Libc-alpha mailing list