Commit 792c95dd authored by J. Bruce Fields's avatar J. Bruce Fields

nfsd4: delay session removal till free_client

Have unhash_client_locked() remove client and associated sessions from
global hashes, but delay further dismantling till free_client().

(After unhash_client_locked(), the only remaining references outside the
destroying thread are from any connections which have xpt_user callbacks
registered.)

This will simplify locking on session destruction.
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 5a3c9d71
...@@ -883,6 +883,13 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name) ...@@ -883,6 +883,13 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
static inline void static inline void
free_client(struct nfs4_client *clp) free_client(struct nfs4_client *clp)
{ {
while (!list_empty(&clp->cl_sessions)) {
struct nfsd4_session *ses;
ses = list_entry(clp->cl_sessions.next, struct nfsd4_session,
se_perclnt);
list_del(&ses->se_perclnt);
nfsd4_put_session(ses);
}
if (clp->cl_cred.cr_group_info) if (clp->cl_cred.cr_group_info)
put_group_info(clp->cl_cred.cr_group_info); put_group_info(clp->cl_cred.cr_group_info);
kfree(clp->cl_principal); kfree(clp->cl_principal);
...@@ -909,15 +916,12 @@ release_session_client(struct nfsd4_session *session) ...@@ -909,15 +916,12 @@ release_session_client(struct nfsd4_session *session)
static inline void static inline void
unhash_client_locked(struct nfs4_client *clp) unhash_client_locked(struct nfs4_client *clp)
{ {
struct nfsd4_session *ses;
mark_client_expired(clp); mark_client_expired(clp);
list_del(&clp->cl_lru); list_del(&clp->cl_lru);
while (!list_empty(&clp->cl_sessions)) { list_for_each_entry(ses, &clp->cl_sessions, se_perclnt)
struct nfsd4_session *ses; list_del_init(&ses->se_hash);
ses = list_entry(clp->cl_sessions.next, struct nfsd4_session,
se_perclnt);
unhash_session(ses);
nfsd4_put_session(ses);
}
} }
static void static void
...@@ -1031,6 +1035,8 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir, ...@@ -1031,6 +1035,8 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
if (clp == NULL) if (clp == NULL)
return NULL; return NULL;
INIT_LIST_HEAD(&clp->cl_sessions);
princ = svc_gss_principal(rqstp); princ = svc_gss_principal(rqstp);
if (princ) { if (princ) {
clp->cl_principal = kstrdup(princ, GFP_KERNEL); clp->cl_principal = kstrdup(princ, GFP_KERNEL);
...@@ -1047,7 +1053,6 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir, ...@@ -1047,7 +1053,6 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
INIT_LIST_HEAD(&clp->cl_strhash); INIT_LIST_HEAD(&clp->cl_strhash);
INIT_LIST_HEAD(&clp->cl_openowners); INIT_LIST_HEAD(&clp->cl_openowners);
INIT_LIST_HEAD(&clp->cl_delegations); INIT_LIST_HEAD(&clp->cl_delegations);
INIT_LIST_HEAD(&clp->cl_sessions);
INIT_LIST_HEAD(&clp->cl_lru); INIT_LIST_HEAD(&clp->cl_lru);
spin_lock_init(&clp->cl_lock); spin_lock_init(&clp->cl_lock);
INIT_WORK(&clp->cl_cb_null.cb_work, nfsd4_do_callback_rpc); INIT_WORK(&clp->cl_cb_null.cb_work, nfsd4_do_callback_rpc);
......
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