|
@@ -4485,7 +4485,9 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
|
|
|
|
|
|
static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request)
|
|
|
{
|
|
|
- struct nfs_inode *nfsi = NFS_I(state->inode);
|
|
|
+ struct inode *inode = state->inode;
|
|
|
+ struct nfs4_state_owner *sp = state->owner;
|
|
|
+ struct nfs_inode *nfsi = NFS_I(inode);
|
|
|
struct nfs_seqid *seqid;
|
|
|
struct nfs4_lock_state *lsp;
|
|
|
struct rpc_task *task;
|
|
@@ -4495,12 +4497,17 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
|
|
|
status = nfs4_set_lock_state(state, request);
|
|
|
/* Unlock _before_ we do the RPC call */
|
|
|
request->fl_flags |= FL_EXISTS;
|
|
|
+ /* Exclude nfs_delegation_claim_locks() */
|
|
|
+ mutex_lock(&sp->so_delegreturn_mutex);
|
|
|
+ /* Exclude nfs4_reclaim_open_stateid() - note nesting! */
|
|
|
down_read(&nfsi->rwsem);
|
|
|
if (do_vfs_lock(request->fl_file, request) == -ENOENT) {
|
|
|
up_read(&nfsi->rwsem);
|
|
|
+ mutex_unlock(&sp->so_delegreturn_mutex);
|
|
|
goto out;
|
|
|
}
|
|
|
up_read(&nfsi->rwsem);
|
|
|
+ mutex_unlock(&sp->so_delegreturn_mutex);
|
|
|
if (status != 0)
|
|
|
goto out;
|
|
|
/* Is this a delegated lock? */
|