NFSv4: Ensure delegation recall and byte range lock removal don't conflict
Add a mutex to the struct nfs4_state_owner to ensure that delegation recall doesn't conflict with byte range lock removal. Note that we nest the new mutex _outside_ the state manager reclaim protection (nfsi->rwsem) in order to avoid deadlocks. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
37380e4264
commit
65b62a29f7
4 changed files with 16 additions and 2 deletions
|
@ -71,8 +71,10 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_
|
|||
int status = 0;
|
||||
|
||||
if (inode->i_flock == NULL)
|
||||
goto out;
|
||||
return 0;
|
||||
|
||||
if (inode->i_flock == NULL)
|
||||
goto out;
|
||||
/* Protect inode->i_flock using the file locks lock */
|
||||
lock_flocks();
|
||||
for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
|
||||
|
@ -113,12 +115,15 @@ again:
|
|||
get_nfs_open_context(ctx);
|
||||
spin_unlock(&inode->i_lock);
|
||||
sp = state->owner;
|
||||
/* Block nfs4_proc_unlck */
|
||||
mutex_lock(&sp->so_delegreturn_mutex);
|
||||
seq = raw_seqcount_begin(&sp->so_reclaim_seqcount);
|
||||
err = nfs4_open_delegation_recall(ctx, state, stateid);
|
||||
if (!err)
|
||||
err = nfs_delegation_claim_locks(ctx, state);
|
||||
if (!err && read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
|
||||
err = -EAGAIN;
|
||||
mutex_unlock(&sp->so_delegreturn_mutex);
|
||||
put_nfs_open_context(ctx);
|
||||
if (err != 0)
|
||||
return err;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue