Thread (49 messages) 49 messages, 14 authors, 2026-02-06

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

From: Jan Kara <jack@suse.cz>
Date: 2026-01-26 15:56:22
Also in: linux-fsdevel

On Mon 26-01-26 14:53:12, The 8472 wrote:
On 26/01/2026 13:15, Jan Kara wrote:
quoted
On Sun 25-01-26 10:37:01, Zack Weinberg wrote:
quoted
On Sat, Jan 24, 2026, at 4:57 PM, The 8472 wrote:
quoted
quoted
      [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.
Regarding the "first", does that mean the errors only get delivered once?
I've added Jeff to CC who should be able to provide you with a more
authoritative answer but AFAIK the answer is yes.

E.g. NFS does:

static int
nfs_file_flush(struct file *file, fl_owner_t id)
{
...
        /* Flush writes to the server and return any errors */
        since = filemap_sample_wb_err(file->f_mapping);
        nfs_wb_all(inode);
        return filemap_check_wb_err(file->f_mapping, since);
}

which will writeback all outstanding data on the first close and report
error if it happened. Following close has nothing to flush and thus no
error to report.

That being said if you call fsync(2) you'll still get the error back again
because fsync uses a separate writeback error counter in the file
description. But again only the first fsync(2) will return the error.
Following fsyncs will report no error.
I.e. if a concurrent fork/exec happens for process spawning and the
fork-child closes the file descriptors then this closing may basically
receive the errors and the parent will not see them (unless additional
errors happen)?
Correct AFAICT.
Or if _any_ part of the program dups the descriptor and then closes it
without reporting errors then all uses of those descriptor must consider
error delivery on close to be unreliable?
Correct as well AFAICT.

I should probably also add that traditional filesystems (classical local
disk based filesystems) don't bother with reporting delayed errors on
close(2) *at all*. So unless you call fsync(2) you will never learn there
was any writeback error. After all for these filesystems there are good
chances writeback didn't even start by the time you are calling close(2).
So overall I'd say that error reporting from close(2) is so random and
filesystem dependent that the errors are not worth paying attention to. If
you really care about data integrity (and thus writeback errors) you must
call fsync(2) in which case the kernel provides at least somewhat
consistent error reporting story. 

								Honza
-- 
Jan Kara [off-list ref]
SUSE Labs, CR
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help