lkml.org 
[lkml]   [2021]   [Nov]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 730/917] NFS: Fix up commit deadlocks
    Date
    From: Trond Myklebust <trond.myklebust@hammerspace.com>

    [ Upstream commit 133a48abf6ecc535d7eddc6da1c3e4c972445882 ]

    If O_DIRECT bumps the commit_info rpcs_out field, then that could lead
    to fsync() hangs. The fix is to ensure that O_DIRECT calls
    nfs_commit_end().

    Fixes: 723c921e7dfc ("sched/wait, fs/nfs: Convert wait_on_atomic_t() usage to the new wait_var_event() API")
    Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/nfs/direct.c | 2 +-
    fs/nfs/pnfs_nfs.c | 2 --
    fs/nfs/write.c | 9 ++++++---
    include/linux/nfs_fs.h | 1 +
    4 files changed, 8 insertions(+), 6 deletions(-)

    diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
    index 2e894fec036b0..3c0335c15a730 100644
    --- a/fs/nfs/direct.c
    +++ b/fs/nfs/direct.c
    @@ -620,7 +620,7 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data)
    nfs_unlock_and_release_request(req);
    }

    - if (atomic_dec_and_test(&cinfo.mds->rpcs_out))
    + if (nfs_commit_end(cinfo.mds))
    nfs_direct_write_complete(dreq);
    }

    diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c
    index 02bd6e83961d9..316f68f96e573 100644
    --- a/fs/nfs/pnfs_nfs.c
    +++ b/fs/nfs/pnfs_nfs.c
    @@ -468,7 +468,6 @@ pnfs_bucket_alloc_ds_commits(struct list_head *list,
    goto out_error;
    data->ds_commit_index = i;
    list_add_tail(&data->list, list);
    - atomic_inc(&cinfo->mds->rpcs_out);
    nreq++;
    }
    mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
    @@ -520,7 +519,6 @@ pnfs_generic_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
    data->ds_commit_index = -1;
    list_splice_init(mds_pages, &data->pages);
    list_add_tail(&data->list, &list);
    - atomic_inc(&cinfo->mds->rpcs_out);
    nreq++;
    }

    diff --git a/fs/nfs/write.c b/fs/nfs/write.c
    index 735a054747752..7dce3e735fc53 100644
    --- a/fs/nfs/write.c
    +++ b/fs/nfs/write.c
    @@ -1657,10 +1657,13 @@ static void nfs_commit_begin(struct nfs_mds_commit_info *cinfo)
    atomic_inc(&cinfo->rpcs_out);
    }

    -static void nfs_commit_end(struct nfs_mds_commit_info *cinfo)
    +bool nfs_commit_end(struct nfs_mds_commit_info *cinfo)
    {
    - if (atomic_dec_and_test(&cinfo->rpcs_out))
    + if (atomic_dec_and_test(&cinfo->rpcs_out)) {
    wake_up_var(&cinfo->rpcs_out);
    + return true;
    + }
    + return false;
    }

    void nfs_commitdata_release(struct nfs_commit_data *data)
    @@ -1760,6 +1763,7 @@ void nfs_init_commit(struct nfs_commit_data *data,
    data->res.fattr = &data->fattr;
    data->res.verf = &data->verf;
    nfs_fattr_init(&data->fattr);
    + nfs_commit_begin(cinfo->mds);
    }
    EXPORT_SYMBOL_GPL(nfs_init_commit);

    @@ -1806,7 +1810,6 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how,

    /* Set up the argument struct */
    nfs_init_commit(data, head, NULL, cinfo);
    - atomic_inc(&cinfo->mds->rpcs_out);
    if (NFS_SERVER(inode)->nfs_client->cl_minorversion)
    task_flags = RPC_TASK_MOVEABLE;
    return nfs_initiate_commit(NFS_CLIENT(inode), data, NFS_PROTO(inode),
    diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
    index b9a8b925db430..4d95cc999d121 100644
    --- a/include/linux/nfs_fs.h
    +++ b/include/linux/nfs_fs.h
    @@ -569,6 +569,7 @@ extern int nfs_wb_page_cancel(struct inode *inode, struct page* page);
    extern int nfs_commit_inode(struct inode *, int);
    extern struct nfs_commit_data *nfs_commitdata_alloc(bool never_fail);
    extern void nfs_commit_free(struct nfs_commit_data *data);
    +bool nfs_commit_end(struct nfs_mds_commit_info *cinfo);

    static inline int
    nfs_have_writebacks(struct inode *inode)
    --
    2.33.0


    \
     
     \ /
      Last update: 2021-11-16 01:01    [W:4.030 / U:0.684 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site