lkml.org 
[lkml]   [2020]   [Aug]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.7 157/204] nfs: nfs_file_write() should check for writeback errors
    Date
    From: Scott Mayhew <smayhew@redhat.com>

    [ Upstream commit ce368536dd614452407dc31e2449eb84681a06af ]

    The NFS_CONTEXT_ERROR_WRITE flag (as well as the check of said flag) was
    removed by commit 6fbda89b257f. 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: 6fbda89b257f ("NFS: Replace custom error reporting mechanism with generic one")
    Signed-off-by: Scott Mayhew <smayhew@redhat.com>
    Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/nfs/file.c | 12 +++++++++---
    1 file changed, 9 insertions(+), 3 deletions(-)

    diff --git a/fs/nfs/file.c b/fs/nfs/file.c
    index d72496efa17b0..63940a7a70be1 100644
    --- a/fs/nfs/file.c
    +++ b/fs/nfs/file.c
    @@ -590,12 +590,14 @@ static const struct vm_operations_struct nfs_file_vm_ops = {
    .page_mkwrite = nfs_vm_page_mkwrite,
    };

    -static int nfs_need_check_write(struct file *filp, struct inode *inode)
    +static int nfs_need_check_write(struct file *filp, struct inode *inode,
    + int error)
    {
    struct nfs_open_context *ctx;

    ctx = nfs_file_open_context(filp);
    - if (nfs_ctx_key_to_expire(ctx, inode))
    + if (nfs_error_is_fatal_on_server(error) ||
    + nfs_ctx_key_to_expire(ctx, inode))
    return 1;
    return 0;
    }
    @@ -606,6 +608,8 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
    struct inode *inode = file_inode(file);
    unsigned long written = 0;
    ssize_t result;
    + errseq_t since;
    + int error;

    result = nfs_key_timeout_notify(file, inode);
    if (result)
    @@ -630,6 +634,7 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
    if (iocb->ki_pos > i_size_read(inode))
    nfs_revalidate_mapping(inode, 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) {
    @@ -648,7 +653,8 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
    goto out;

    /* Return error values */
    - if (nfs_need_check_write(file, inode)) {
    + error = filemap_check_wb_err(file->f_mapping, since);
    + if (nfs_need_check_write(file, inode, error)) {
    int err = nfs_wb_all(inode);
    if (err < 0)
    result = err;
    --
    2.25.1


    \
     
     \ /
      Last update: 2020-08-20 14:56    [W:4.392 / U:0.776 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site