lkml.org 
[lkml]   [2018]   [May]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 027/329] NFSv4: always set NFS_LOCK_LOST when a lock is lost.
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: NeilBrown <neilb@suse.com>

    [ Upstream commit dce2630c7da73b0634686bca557cc8945cc450c8 ]

    There are 2 comments in the NFSv4 code which suggest that
    SIGLOST should possibly be sent to a process. In these
    cases a lock has been lost.
    The current practice is to set NFS_LOCK_LOST so that
    read/write returns EIO when a lock is lost.
    So change these comments to code when sets NFS_LOCK_LOST.

    One case is when lock recovery after apparent server restart
    fails with NFS4ERR_DENIED, NFS4ERR_RECLAIM_BAD, or
    NFS4ERRO_RECLAIM_CONFLICT. The other case is when a lock
    attempt as part of lease recovery fails with NFS4ERR_DENIED.

    In an ideal world, these should not happen. However I have
    a packet trace showing an NFSv4.1 session getting
    NFS4ERR_BADSESSION after an extended network parition. The
    NFSv4.1 client treats this like server reboot until/unless
    it get NFS4ERR_NO_GRACE, in which case it switches over to
    "nograce" recovery mode. In this network trace, the client
    attempts to recover a lock and the server (incorrectly)
    reports NFS4ERR_DENIED rather than NFS4ERR_NO_GRACE. This
    leads to the ineffective comment and the client then
    continues to write using the OPEN stateid.

    Signed-off-by: NeilBrown <neilb@suse.com>
    Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    fs/nfs/nfs4proc.c | 12 ++++++++----
    fs/nfs/nfs4state.c | 5 ++++-
    2 files changed, 12 insertions(+), 5 deletions(-)

    --- a/fs/nfs/nfs4proc.c
    +++ b/fs/nfs/nfs4proc.c
    @@ -1934,7 +1934,7 @@ static int nfs4_open_reclaim(struct nfs4
    return ret;
    }

    -static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct nfs4_state *state, const nfs4_stateid *stateid, int err)
    +static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct nfs4_state *state, const nfs4_stateid *stateid, struct file_lock *fl, int err)
    {
    switch (err) {
    default:
    @@ -1981,7 +1981,11 @@ static int nfs4_handle_delegation_recall
    return -EAGAIN;
    case -ENOMEM:
    case -NFS4ERR_DENIED:
    - /* kill_proc(fl->fl_pid, SIGLOST, 1); */
    + if (fl) {
    + struct nfs4_lock_state *lsp = fl->fl_u.nfs4_fl.owner;
    + if (lsp)
    + set_bit(NFS_LOCK_LOST, &lsp->ls_flags);
    + }
    return 0;
    }
    return err;
    @@ -2017,7 +2021,7 @@ int nfs4_open_delegation_recall(struct n
    err = nfs4_open_recover_helper(opendata, FMODE_READ);
    }
    nfs4_opendata_put(opendata);
    - return nfs4_handle_delegation_recall_error(server, state, stateid, err);
    + return nfs4_handle_delegation_recall_error(server, state, stateid, NULL, err);
    }

    static void nfs4_open_confirm_prepare(struct rpc_task *task, void *calldata)
    @@ -6499,7 +6503,7 @@ int nfs4_lock_delegation_recall(struct f
    if (err != 0)
    return err;
    err = _nfs4_do_setlk(state, F_SETLK, fl, NFS_LOCK_NEW);
    - return nfs4_handle_delegation_recall_error(server, state, stateid, err);
    + return nfs4_handle_delegation_recall_error(server, state, stateid, fl, err);
    }

    struct nfs_release_lockowner_data {
    --- a/fs/nfs/nfs4state.c
    +++ b/fs/nfs/nfs4state.c
    @@ -1429,6 +1429,7 @@ static int nfs4_reclaim_locks(struct nfs
    struct inode *inode = state->inode;
    struct nfs_inode *nfsi = NFS_I(inode);
    struct file_lock *fl;
    + struct nfs4_lock_state *lsp;
    int status = 0;
    struct file_lock_context *flctx = inode->i_flctx;
    struct list_head *list;
    @@ -1469,7 +1470,9 @@ restart:
    case -NFS4ERR_DENIED:
    case -NFS4ERR_RECLAIM_BAD:
    case -NFS4ERR_RECLAIM_CONFLICT:
    - /* kill_proc(fl->fl_pid, SIGLOST, 1); */
    + lsp = fl->fl_u.nfs4_fl.owner;
    + if (lsp)
    + set_bit(NFS_LOCK_LOST, &lsp->ls_flags);
    status = 0;
    }
    spin_lock(&flctx->flc_lock);

    \
     
     \ /
      Last update: 2018-05-28 16:58    [W:4.019 / U:1.108 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site