Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=1b1a9b3163a83f52ea2ac333846d4dfd2c4edd90
Commit:     1b1a9b3163a83f52ea2ac333846d4dfd2c4edd90
Parent:     0272e1fd9f4fa8a43357c168e081744f99e67195
Author:     J. Bruce Fields <[EMAIL PROTECTED]>
AuthorDate: Wed Sep 12 08:43:59 2007 -0400
Committer:  J. Bruce Fields <[EMAIL PROTECTED]>
CommitDate: Tue Oct 9 18:31:57 2007 -0400

    knfsd: don't shutdown callbacks until nfsv4 client is freed
    
    If a callback still holds a reference on the client, then it may be
    about to perform an rpc call, so it isn't safe to call rpc_shutdown().
    (Though rpc_shutdown() does wait for any outstanding rpc's, it can't
    know if a new rpc is about to be issued with that client.)
    
    So, wait to shutdown the rpc_client until the reference count on the
    client has gone to zero.
    
    Signed-off-by: J. Bruce Fields <[EMAIL PROTECTED]>
---
 fs/nfsd/nfs4state.c |   27 +++++++++++++--------------
 1 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 48fbdac..e706c69 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -358,9 +358,22 @@ alloc_client(struct xdr_netobj name)
        return clp;
 }
 
+static void
+shutdown_callback_client(struct nfs4_client *clp)
+{
+       struct rpc_clnt *clnt = clp->cl_callback.cb_client;
+
+       /* shutdown rpc client, ending any outstanding recall rpcs */
+       if (clnt) {
+               clp->cl_callback.cb_client = NULL;
+               rpc_shutdown_client(clnt);
+       }
+}
+
 static inline void
 free_client(struct nfs4_client *clp)
 {
+       shutdown_callback_client(clp);
        if (clp->cl_cred.cr_group_info)
                put_group_info(clp->cl_cred.cr_group_info);
        kfree(clp->cl_name.data);
@@ -375,18 +388,6 @@ put_nfs4_client(struct nfs4_client *clp)
 }
 
 static void
-shutdown_callback_client(struct nfs4_client *clp)
-{
-       struct rpc_clnt *clnt = clp->cl_callback.cb_client;
-
-       /* shutdown rpc client, ending any outstanding recall rpcs */
-       if (clnt) {
-               clp->cl_callback.cb_client = NULL;
-               rpc_shutdown_client(clnt);
-       }
-}
-
-static void
 expire_client(struct nfs4_client *clp)
 {
        struct nfs4_stateowner *sop;
@@ -396,8 +397,6 @@ expire_client(struct nfs4_client *clp)
        dprintk("NFSD: expire_client cl_count %d\n",
                            atomic_read(&clp->cl_count));
 
-       shutdown_callback_client(clp);
-
        INIT_LIST_HEAD(&reaplist);
        spin_lock(&recall_lock);
        while (!list_empty(&clp->cl_delegations)) {
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to