Skip to content

Commit ce36853

Browse files
scottmayhewTrond Myklebust
authored andcommitted
nfs: nfs_file_write() should check for writeback errors
The NFS_CONTEXT_ERROR_WRITE flag (as well as the check of said flag) was removed by commit 6fbda89. The absence of an error check allows writes to be continually queued up for a server that may no longer be able to handle them. Fix it by adding an error check using the generic error reporting functions. Fixes: 6fbda89 ("NFS: Replace custom error reporting mechanism with generic one") Signed-off-by: Scott Mayhew <[email protected]> Signed-off-by: Trond Myklebust <[email protected]>
1 parent 67dd23f commit ce36853

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

fs/nfs/file.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -591,12 +591,14 @@ static const struct vm_operations_struct nfs_file_vm_ops = {
591591
.page_mkwrite = nfs_vm_page_mkwrite,
592592
};
593593

594-
static int nfs_need_check_write(struct file *filp, struct inode *inode)
594+
static int nfs_need_check_write(struct file *filp, struct inode *inode,
595+
int error)
595596
{
596597
struct nfs_open_context *ctx;
597598

598599
ctx = nfs_file_open_context(filp);
599-
if (nfs_ctx_key_to_expire(ctx, inode))
600+
if (nfs_error_is_fatal_on_server(error) ||
601+
nfs_ctx_key_to_expire(ctx, inode))
600602
return 1;
601603
return 0;
602604
}
@@ -607,6 +609,8 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
607609
struct inode *inode = file_inode(file);
608610
unsigned long written = 0;
609611
ssize_t result;
612+
errseq_t since;
613+
int error;
610614

611615
result = nfs_key_timeout_notify(file, inode);
612616
if (result)
@@ -631,6 +635,7 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
631635
if (iocb->ki_pos > i_size_read(inode))
632636
nfs_revalidate_mapping(inode, file->f_mapping);
633637

638+
since = filemap_sample_wb_err(file->f_mapping);
634639
nfs_start_io_write(inode);
635640
result = generic_write_checks(iocb, from);
636641
if (result > 0) {
@@ -649,7 +654,8 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
649654
goto out;
650655

651656
/* Return error values */
652-
if (nfs_need_check_write(file, inode)) {
657+
error = filemap_check_wb_err(file->f_mapping, since);
658+
if (nfs_need_check_write(file, inode, error)) {
653659
int err = nfs_wb_all(inode);
654660
if (err < 0)
655661
result = err;

0 commit comments

Comments
 (0)