On Tue, Apr 04, 2017 at 12:25:46PM -0400, Jeff Layton wrote: > That said, I think giving more specific errors where we can is useful. > When your program is erroring out and writing 'I/O error' to the logs, > then how much time will your admins burn before they figure out that it > really failed because the filesystem was full? df is one of the first things I check ... a few years ago, I also learned to check df -i ... ;-) Anyway, given the decision to simply report the last error lets us do this implementation: void filemap_set_wb_error(struct address_space *mapping, int err) { struct inode *inode = mapping->host; unsigned int wb_err; if (!err) return; /* * This should be called with the error code that we want to return * on fsync. Thus, it should always be <= 0. */ WARN_ON(err > 0 || err < -MAX_ERRNO); spin_lock(&inode->i_lock); wb_err = ((mapping->wb_err & ~MAX_ERRNO) + (1 << 12)) | -err; WRITE_ONCE(mapping->wb_err, wb_err); spin_unlock(&inode->i_lock); } int filemap_report_wb_error(struct file *file) { struct inode *inode = file_inode(file); unsigned int wb_err = READ_ONCE(mapping->wb_err); if (file->f_wb_err == wb_err) return 0; return -(wb_err & 4095); } That only gives us 20 bits of counter, but I think that's enough.