Commit 36939848 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] don't report async write errors on close() after all

I had second thoughts on this.

Reporting background writeout errors via close() only really makes sense if
allthe IO has completed anyway: ie, the app has had the fd open without
writing to it for many tens of seconds.

It would be OK if it was harmless, but it is not.  Changes are, applications
ignore errors from close().  So if an application does a fork/exit and the
child correctly does an fsync() of the fd, the close-on-exit will have wiped
out any accumulated EIO/ENOSPC errors.

Or if someone does dup()/close()/fsync(), the fsync() could fail to detect
earlier errors, thanks to the close.


So.  The clear-and-report of errors on close() makes the reporting of errors
on fsync/msync/fdatasync less reliable.
parent 1c890ad9
...@@ -945,20 +945,12 @@ asmlinkage long sys_creat(const char __user * pathname, int mode) ...@@ -945,20 +945,12 @@ asmlinkage long sys_creat(const char __user * pathname, int mode)
*/ */
int filp_close(struct file *filp, fl_owner_t id) int filp_close(struct file *filp, fl_owner_t id)
{ {
struct address_space *mapping = filp->f_dentry->d_inode->i_mapping; int retval;
int retval = 0, err;
/* Report and clear outstanding errors */ /* Report and clear outstanding errors */
err = filp->f_error; retval = filp->f_error;
if (err) { if (retval)
filp->f_error = 0; filp->f_error = 0;
retval = err;
}
if (test_and_clear_bit(AS_ENOSPC, &mapping->flags))
retval = -ENOSPC;
if (test_and_clear_bit(AS_EIO, &mapping->flags))
retval = -EIO;
if (!file_count(filp)) { if (!file_count(filp)) {
printk(KERN_ERR "VFS: Close: file count is 0\n"); printk(KERN_ERR "VFS: Close: file count is 0\n");
...@@ -966,7 +958,7 @@ int filp_close(struct file *filp, fl_owner_t id) ...@@ -966,7 +958,7 @@ int filp_close(struct file *filp, fl_owner_t id)
} }
if (filp->f_op && filp->f_op->flush) { if (filp->f_op && filp->f_op->flush) {
err = filp->f_op->flush(filp); int err = filp->f_op->flush(filp);
if (!retval) if (!retval)
retval = err; retval = err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment