diff options
-rw-r--r-- | fs/nfsd/nfs4state.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 2e80a59e7e91..309ec3b1090a 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -673,15 +673,20 @@ nfs4_put_stid(struct nfs4_stid *s) static void nfs4_put_deleg_lease(struct nfs4_file *fp) { - lockdep_assert_held(&state_lock); + struct file *filp = NULL; + struct file_lock *fl; - if (!fp->fi_lease) - return; - if (atomic_dec_and_test(&fp->fi_delegees)) { - vfs_setlease(fp->fi_deleg_file, F_UNLCK, &fp->fi_lease); + spin_lock(&fp->fi_lock); + if (fp->fi_lease && atomic_dec_and_test(&fp->fi_delegees)) { + swap(filp, fp->fi_deleg_file); + fl = fp->fi_lease; fp->fi_lease = NULL; - fput(fp->fi_deleg_file); - fp->fi_deleg_file = NULL; + } + spin_unlock(&fp->fi_lock); + + if (filp) { + vfs_setlease(filp, F_UNLCK, &fl); + fput(filp); } } @@ -717,8 +722,7 @@ unhash_delegation_locked(struct nfs4_delegation *dp) list_del_init(&dp->dl_recall_lru); list_del_init(&dp->dl_perfile); spin_unlock(&fp->fi_lock); - if (fp) - nfs4_put_deleg_lease(fp); + nfs4_put_deleg_lease(fp); } static void destroy_delegation(struct nfs4_delegation *dp) |