Skip to content

Commit 9340d8b

Browse files
scottmayhewgregkh
authored andcommitted
nfs: nfs_file_write() should check for writeback errors
[ Upstream commit ce36853 ] 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]> Signed-off-by: Sasha Levin <[email protected]>
1 parent da14c05 commit 9340d8b

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
@@ -583,12 +583,14 @@ static const struct vm_operations_struct nfs_file_vm_ops = {
583583
.page_mkwrite = nfs_vm_page_mkwrite,
584584
};
585585

586-
static int nfs_need_check_write(struct file *filp, struct inode *inode)
586+
static int nfs_need_check_write(struct file *filp, struct inode *inode,
587+
int error)
587588
{
588589
struct nfs_open_context *ctx;
589590

590591
ctx = nfs_file_open_context(filp);
591-
if (nfs_ctx_key_to_expire(ctx, inode))
592+
if (nfs_error_is_fatal_on_server(error) ||
593+
nfs_ctx_key_to_expire(ctx, inode))
592594
return 1;
593595
return 0;
594596
}
@@ -599,6 +601,8 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
599601
struct inode *inode = file_inode(file);
600602
unsigned long written = 0;
601603
ssize_t result;
604+
errseq_t since;
605+
int error;
602606

603607
result = nfs_key_timeout_notify(file, inode);
604608
if (result)
@@ -623,6 +627,7 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
623627
if (iocb->ki_pos > i_size_read(inode))
624628
nfs_revalidate_mapping(inode, file->f_mapping);
625629

630+
since = filemap_sample_wb_err(file->f_mapping);
626631
nfs_start_io_write(inode);
627632
result = generic_write_checks(iocb, from);
628633
if (result > 0) {
@@ -641,7 +646,8 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
641646
goto out;
642647

643648
/* Return error values */
644-
if (nfs_need_check_write(file, inode)) {
649+
error = filemap_check_wb_err(file->f_mapping, since);
650+
if (nfs_need_check_write(file, inode, error)) {
645651
int err = nfs_wb_all(inode);
646652
if (err < 0)
647653
result = err;

0 commit comments

Comments
 (0)