lkml.org 
[lkml]   [2022]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.18 678/879] NFS: Dont report ENOSPC write errors twice
    Date
    From: Trond Myklebust <trond.myklebust@hammerspace.com>

    [ Upstream commit e6005436f6cc9ed13288f936903f0151e5543485 ]

    Any errors reported by the write() system call need to be cleared from
    the file descriptor's error tracking. The current call to nfs_wb_all()
    causes the error to be reported, but since it doesn't call
    file_check_and_advance_wb_err(), we can end up reporting the same error
    a second time when the application calls fsync().

    Note that since Linux 4.13, the rule is that EIO may be reported for
    write(), but it must be reported by a subsequent fsync(), so let's just
    drop reporting it in write.

    The check for nfs_ctx_key_to_expire() is just a duplicate to the one
    already in nfs_write_end(), so let's drop that too.

    Reported-by: ChenXiaoSong <chenxiaosong2@huawei.com>
    Fixes: ce368536dd61 ("nfs: nfs_file_write() should check for writeback errors")
    Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
    Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/nfs/file.c | 34 ++++++++++++++--------------------
    1 file changed, 14 insertions(+), 20 deletions(-)

    diff --git a/fs/nfs/file.c b/fs/nfs/file.c
    index 7c380e555224..87e4cd5e8fe2 100644
    --- a/fs/nfs/file.c
    +++ b/fs/nfs/file.c
    @@ -598,18 +598,6 @@ 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,
    - int error)
    -{
    - struct nfs_open_context *ctx;
    -
    - ctx = nfs_file_open_context(filp);
    - if (nfs_error_is_fatal_on_server(error) ||
    - nfs_ctx_key_to_expire(ctx, inode))
    - return 1;
    - return 0;
    -}
    -
    ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
    {
    struct file *file = iocb->ki_filp;
    @@ -637,7 +625,7 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
    if (iocb->ki_flags & IOCB_APPEND || iocb->ki_pos > i_size_read(inode)) {
    result = nfs_revalidate_file_size(inode, file);
    if (result)
    - goto out;
    + return result;
    }

    nfs_clear_invalid_mapping(file->f_mapping);
    @@ -656,6 +644,7 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)

    written = result;
    iocb->ki_pos += written;
    + nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written);

    if (mntflags & NFS_MOUNT_WRITE_EAGER) {
    result = filemap_fdatawrite_range(file->f_mapping,
    @@ -673,17 +662,22 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
    }
    result = generic_write_sync(iocb, written);
    if (result < 0)
    - goto out;
    + return result;

    +out:
    /* Return error values */
    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;
    + switch (error) {
    + default:
    + break;
    + case -EDQUOT:
    + case -EFBIG:
    + case -ENOSPC:
    + nfs_wb_all(inode);
    + error = file_check_and_advance_wb_err(file);
    + if (error < 0)
    + result = error;
    }
    - nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written);
    -out:
    return result;

    out_swapfile:
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-06-08 04:50    [W:6.399 / U:0.324 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site