From: Wang Zhaolong wangzhaolong1@huawei.com
HULK inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IB7MNY
--------------------------------
When the file is closed and the ->flush is executed, the writeback error is not consumed. As a result, when the file is written next time, the writeback error still exists, causing a new write failure.
Another problem is that in the write process, only special writeback error codes such as -EDQUOT, -EFBIG, and -ENOSPC are detected, and the error codes are consumed. In this case, other error codes may be left.
The writeback error code should be consumed unconditionally in the write(), fsync(), and close() to avoid sampling residual expired codes that are left over from the last invoking.
In the fsync process, the error code can be consumed. Therefore, this patch ensures that write and flush can consume error codes.
Fixes: 6fbda89b257f ("NFS: Replace custom error reporting mechanism with generic one") Signed-off-by: Wang Zhaolong wangzhaolong1@huawei.com Signed-off-by: Yang Erkun yangerkun@huawei.com --- fs/nfs/file.c | 12 ++++-------- fs/nfs/nfs4file.c | 4 +--- 2 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 9342f8074801..354dd63dbbba 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -139,7 +139,6 @@ static int nfs_file_flush(struct file *file, fl_owner_t id) { struct inode *inode = file_inode(file); - errseq_t since;
dprintk("NFS: flush(%pD2)\n", file);
@@ -148,9 +147,8 @@ nfs_file_flush(struct file *file, fl_owner_t id) return 0;
/* 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); + return file_check_and_advance_wb_err(file); }
ssize_t @@ -641,7 +639,6 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from) struct inode *inode = file_inode(file); unsigned int mntflags = NFS_SERVER(inode)->flags; ssize_t result, written; - errseq_t since; int error;
result = nfs_key_timeout_notify(file, inode); @@ -667,7 +664,6 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
nfs_clear_invalid_mapping(file->f_mapping);
- since = filemap_sample_wb_err(file->f_mapping); nfs_start_io_write(inode); result = generic_write_checks(iocb, from); if (result > 0) @@ -697,7 +693,7 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
out: /* Return error values */ - error = filemap_check_wb_err(file->f_mapping, since); + error = file_check_and_advance_wb_err(file); switch (error) { default: break; @@ -706,9 +702,9 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from) case -ENOSPC: nfs_wb_all(inode); error = file_check_and_advance_wb_err(file); - if (error < 0) - result = error; } + if (error < 0) + result = error; return result;
out_swapfile: diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 02788c3c85e5..71e1050ce15e 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -110,7 +110,6 @@ static int nfs4_file_flush(struct file *file, fl_owner_t id) { struct inode *inode = file_inode(file); - errseq_t since;
dprintk("NFS: flush(%pD2)\n", file);
@@ -126,9 +125,8 @@ nfs4_file_flush(struct file *file, fl_owner_t id) return filemap_fdatawrite(file->f_mapping);
/* 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); + return file_check_and_advance_wb_err(file); }
#ifdef CONFIG_NFS_V4_2
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/13972 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/7...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/13972 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/7...