Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=0285ed1f12298e5304f0f2642e2cf31a5f302e61
Commit:     0285ed1f12298e5304f0f2642e2cf31a5f302e61
Parent:     1be27f36601973815171db684c711d30557cf50c
Author:     Trond Myklebust <[EMAIL PROTECTED]>
AuthorDate: Wed Jun 27 14:29:12 2007 -0400
Committer:  Trond Myklebust <[EMAIL PROTECTED]>
CommitDate: Tue Jul 10 23:40:37 2007 -0400

    SUNRPC: Ensure that the struct gss_auth lifetime exceeds the credential's
    
    Add a refcount in order to ensure that the gss_auth doesn't disappear from
    underneath us while we're freeing up GSS contexts.
    
    Signed-off-by: Trond Myklebust <[EMAIL PROTECTED]>
---
 net/sunrpc/auth_gss/auth_gss.c |   31 +++++++++++++++++++++++++------
 1 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index debcda8..982aba6 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -79,6 +79,7 @@ static const struct rpc_credops gss_credops;
 #define isprint(c)      ((c > 0x1f) && (c < 0x7f))
 
 struct gss_auth {
+       struct kref kref;
        struct rpc_auth rpc_auth;
        struct gss_api_mech *mech;
        enum rpc_gss_svc service;
@@ -636,6 +637,7 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
        auth->au_ops = &authgss_ops;
        auth->au_flavor = flavor;
        atomic_set(&auth->au_count, 1);
+       kref_init(&gss_auth->kref);
 
        gss_auth->dentry = rpc_mkpipe(clnt->cl_dentry, gss_auth->mech->gm_name,
                        clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
@@ -661,6 +663,25 @@ out_dec:
 }
 
 static void
+gss_free(struct gss_auth *gss_auth)
+{
+       rpc_unlink(gss_auth->dentry);
+       gss_auth->dentry = NULL;
+       gss_mech_put(gss_auth->mech);
+
+       kfree(gss_auth);
+       module_put(THIS_MODULE);
+}
+
+static void
+gss_free_callback(struct kref *kref)
+{
+       struct gss_auth *gss_auth = container_of(kref, struct gss_auth, kref);
+
+       gss_free(gss_auth);
+}
+
+static void
 gss_destroy(struct rpc_auth *auth)
 {
        struct gss_auth *gss_auth;
@@ -671,12 +692,7 @@ gss_destroy(struct rpc_auth *auth)
        rpcauth_destroy_credcache(auth);
 
        gss_auth = container_of(auth, struct gss_auth, rpc_auth);
-       rpc_unlink(gss_auth->dentry);
-       gss_auth->dentry = NULL;
-       gss_mech_put(gss_auth->mech);
-
-       kfree(gss_auth);
-       module_put(THIS_MODULE);
+       kref_put(&gss_auth->kref, gss_free_callback);
 }
 
 /* gss_destroy_cred (and gss_destroy_ctx) are used to clean up after failure
@@ -725,12 +741,14 @@ static void
 gss_destroy_cred(struct rpc_cred *cred)
 {
        struct gss_cred *gss_cred = container_of(cred, struct gss_cred, 
gc_base);
+       struct gss_auth *gss_auth = container_of(cred->cr_auth, struct 
gss_auth, rpc_auth);
        struct gss_cl_ctx *ctx = gss_cred->gc_ctx;
 
        rcu_assign_pointer(gss_cred->gc_ctx, NULL);
        call_rcu(&cred->cr_rcu, gss_free_cred_callback);
        if (ctx)
                gss_put_ctx(ctx);
+       kref_put(&gss_auth->kref, gss_free_callback);
 }
 
 /*
@@ -762,6 +780,7 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred 
*acred, int flags)
         */
        cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW;
        cred->gc_service = gss_auth->service;
+       kref_get(&gss_auth->kref);
        return &cred->gc_base;
 
 out_err:
-
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