Commit 717564ae authored by NeilBrown's avatar NeilBrown Committed by Khalid Elmously

NFSv4: always set NFS_LOCK_LOST when a lock is lost.

BugLink: https://bugs.launchpad.net/bugs/1775771

[ Upstream commit dce2630c ]

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: default avatarNeilBrown <neilb@suse.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: default avatarSasha Levin <alexander.levin@microsoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarJuerg Haefliger <juergh@canonical.com>
Signed-off-by: default avatarKhalid Elmously <khalid.elmously@canonical.com>
parent 21f39cf5
...@@ -1780,7 +1780,7 @@ static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *sta ...@@ -1780,7 +1780,7 @@ static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *sta
return ret; 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) { switch (err) {
default: default:
...@@ -1827,7 +1827,11 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct ...@@ -1827,7 +1827,11 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct
return -EAGAIN; return -EAGAIN;
case -ENOMEM: case -ENOMEM:
case -NFS4ERR_DENIED: 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 0;
} }
return err; return err;
...@@ -1863,7 +1867,7 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, ...@@ -1863,7 +1867,7 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx,
err = nfs4_open_recover_helper(opendata, FMODE_READ); err = nfs4_open_recover_helper(opendata, FMODE_READ);
} }
nfs4_opendata_put(opendata); 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) static void nfs4_open_confirm_prepare(struct rpc_task *task, void *calldata)
...@@ -6157,7 +6161,7 @@ int nfs4_lock_delegation_recall(struct file_lock *fl, struct nfs4_state *state, ...@@ -6157,7 +6161,7 @@ int nfs4_lock_delegation_recall(struct file_lock *fl, struct nfs4_state *state,
if (err != 0) if (err != 0)
return err; return err;
err = _nfs4_do_setlk(state, F_SETLK, fl, NFS_LOCK_NEW); 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 { struct nfs_release_lockowner_data {
......
...@@ -1386,6 +1386,7 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_ ...@@ -1386,6 +1386,7 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
struct inode *inode = state->inode; struct inode *inode = state->inode;
struct nfs_inode *nfsi = NFS_I(inode); struct nfs_inode *nfsi = NFS_I(inode);
struct file_lock *fl; struct file_lock *fl;
struct nfs4_lock_state *lsp;
int status = 0; int status = 0;
struct file_lock_context *flctx = inode->i_flctx; struct file_lock_context *flctx = inode->i_flctx;
struct list_head *list; struct list_head *list;
...@@ -1426,7 +1427,9 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_ ...@@ -1426,7 +1427,9 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
case -NFS4ERR_DENIED: case -NFS4ERR_DENIED:
case -NFS4ERR_RECLAIM_BAD: case -NFS4ERR_RECLAIM_BAD:
case -NFS4ERR_RECLAIM_CONFLICT: 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; status = 0;
} }
spin_lock(&flctx->flc_lock); spin_lock(&flctx->flc_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment