aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/nfs4state.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 3f572cb3f896..dede43c37336 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -693,6 +693,20 @@ free_client(struct nfs4_client *clp)
693 kfree(clp); 693 kfree(clp);
694} 694}
695 695
696/* must be called under the client_lock */
697static inline void
698unhash_client_locked(struct nfs4_client *clp)
699{
700 list_del(&clp->cl_lru);
701 while (!list_empty(&clp->cl_sessions)) {
702 struct nfsd4_session *ses;
703 ses = list_entry(clp->cl_sessions.next, struct nfsd4_session,
704 se_perclnt);
705 unhash_session(ses);
706 nfsd4_put_session(ses);
707 }
708}
709
696static void 710static void
697expire_client(struct nfs4_client *clp) 711expire_client(struct nfs4_client *clp)
698{ 712{
@@ -719,21 +733,14 @@ expire_client(struct nfs4_client *clp)
719 sop = list_entry(clp->cl_openowners.next, struct nfs4_stateowner, so_perclient); 733 sop = list_entry(clp->cl_openowners.next, struct nfs4_stateowner, so_perclient);
720 release_openowner(sop); 734 release_openowner(sop);
721 } 735 }
736 nfsd4_set_callback_client(clp, NULL);
737 if (clp->cl_cb_conn.cb_xprt)
738 svc_xprt_put(clp->cl_cb_conn.cb_xprt);
722 list_del(&clp->cl_idhash); 739 list_del(&clp->cl_idhash);
723 list_del(&clp->cl_strhash); 740 list_del(&clp->cl_strhash);
724 spin_lock(&client_lock); 741 spin_lock(&client_lock);
725 list_del(&clp->cl_lru); 742 unhash_client_locked(clp);
726 while (!list_empty(&clp->cl_sessions)) {
727 struct nfsd4_session *ses;
728 ses = list_entry(clp->cl_sessions.next, struct nfsd4_session,
729 se_perclnt);
730 unhash_session(ses);
731 nfsd4_put_session(ses);
732 }
733 spin_unlock(&client_lock); 743 spin_unlock(&client_lock);
734 nfsd4_set_callback_client(clp, NULL);
735 if (clp->cl_cb_conn.cb_xprt)
736 svc_xprt_put(clp->cl_cb_conn.cb_xprt);
737 free_client(clp); 744 free_client(clp);
738} 745}
739 746