SUNRPC: IS_ERR/PTR_ERR confusion
[safe/jmp/linux-2.6] / net / sunrpc / auth_unix.c
index 82300b8..46b2647 100644 (file)
@@ -20,11 +20,6 @@ struct unx_cred {
        gid_t                   uc_gids[NFS_NGROUPS];
 };
 #define uc_uid                 uc_base.cr_uid
-#define uc_count               uc_base.cr_count
-#define uc_flags               uc_base.cr_flags
-#define uc_expire              uc_base.cr_expire
-
-#define UNX_CRED_EXPIRE                (60 * HZ)
 
 #define UNX_WRITESLACK         (21 + (UNX_MAXNODENAME >> 2))
 
@@ -34,15 +29,14 @@ struct unx_cred {
 
 static struct rpc_auth         unix_auth;
 static struct rpc_cred_cache   unix_cred_cache;
-static struct rpc_credops      unix_credops;
+static const struct rpc_credops        unix_credops;
 
 static struct rpc_auth *
 unx_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
 {
        dprintk("RPC:       creating UNIX authenticator for client %p\n",
                        clnt);
-       if (atomic_inc_return(&unix_auth.au_count) == 0)
-               unix_cred_cache.nextgc = jiffies + (unix_cred_cache.expire >> 1);
+       atomic_inc(&unix_auth.au_count);
        return &unix_auth;
 }
 
@@ -50,7 +44,7 @@ static void
 unx_destroy(struct rpc_auth *auth)
 {
        dprintk("RPC:       destroying UNIX authenticator %p\n", auth);
-       rpcauth_free_credcache(auth);
+       rpcauth_clear_credcache(auth->au_credcache);
 }
 
 /*
@@ -66,42 +60,50 @@ static struct rpc_cred *
 unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
 {
        struct unx_cred *cred;
-       int             i;
+       unsigned int groups = 0;
+       unsigned int i;
 
        dprintk("RPC:       allocating UNIX cred for uid %d gid %d\n",
                        acred->uid, acred->gid);
 
-       if (!(cred = kmalloc(sizeof(*cred), GFP_KERNEL)))
+       if (!(cred = kmalloc(sizeof(*cred), GFP_NOFS)))
                return ERR_PTR(-ENOMEM);
 
-       atomic_set(&cred->uc_count, 1);
-       cred->uc_flags = RPCAUTH_CRED_UPTODATE;
-       if (flags & RPCAUTH_LOOKUP_ROOTCREDS) {
-               cred->uc_uid = 0;
-               cred->uc_gid = 0;
-               cred->uc_gids[0] = NOGROUP;
-       } else {
-               int groups = acred->group_info->ngroups;
-               if (groups > NFS_NGROUPS)
-                       groups = NFS_NGROUPS;
-
-               cred->uc_uid = acred->uid;
-               cred->uc_gid = acred->gid;
-               for (i = 0; i < groups; i++)
-                       cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
-               if (i < NFS_NGROUPS)
-                 cred->uc_gids[i] = NOGROUP;
-       }
-       cred->uc_base.cr_auth = &unix_auth;
-       cred->uc_base.cr_ops = &unix_credops;
+       rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops);
+       cred->uc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
+
+       if (acred->group_info != NULL)
+               groups = acred->group_info->ngroups;
+       if (groups > NFS_NGROUPS)
+               groups = NFS_NGROUPS;
+
+       cred->uc_gid = acred->gid;
+       for (i = 0; i < groups; i++)
+               cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
+       if (i < NFS_NGROUPS)
+               cred->uc_gids[i] = NOGROUP;
 
-       return (struct rpc_cred *) cred;
+       return &cred->uc_base;
+}
+
+static void
+unx_free_cred(struct unx_cred *unx_cred)
+{
+       dprintk("RPC:       unx_free_cred %p\n", unx_cred);
+       kfree(unx_cred);
+}
+
+static void
+unx_free_cred_callback(struct rcu_head *head)
+{
+       struct unx_cred *unx_cred = container_of(head, struct unx_cred, uc_base.cr_rcu);
+       unx_free_cred(unx_cred);
 }
 
 static void
 unx_destroy_cred(struct rpc_cred *cred)
 {
-       kfree(cred);
+       call_rcu(&cred->cr_rcu, unx_free_cred_callback);
 }
 
 /*
@@ -112,27 +114,22 @@ unx_destroy_cred(struct rpc_cred *cred)
 static int
 unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
 {
-       struct unx_cred *cred = (struct unx_cred *) rcred;
-       int             i;
+       struct unx_cred *cred = container_of(rcred, struct unx_cred, uc_base);
+       unsigned int groups = 0;
+       unsigned int i;
 
-       if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) {
-               int groups;
 
-               if (cred->uc_uid != acred->uid
-                || cred->uc_gid != acred->gid)
-                       return 0;
+       if (cred->uc_uid != acred->uid || cred->uc_gid != acred->gid)
+               return 0;
 
+       if (acred->group_info != NULL)
                groups = acred->group_info->ngroups;
-               if (groups > NFS_NGROUPS)
-                       groups = NFS_NGROUPS;
-               for (i = 0; i < groups ; i++)
-                       if (cred->uc_gids[i] != GROUP_AT(acred->group_info, i))
-                               return 0;
-               return 1;
-       }
-       return (cred->uc_uid == 0
-            && cred->uc_gid == 0
-            && cred->uc_gids[0] == (gid_t) NOGROUP);
+       if (groups > NFS_NGROUPS)
+               groups = NFS_NGROUPS;
+       for (i = 0; i < groups ; i++)
+               if (cred->uc_gids[i] != GROUP_AT(acred->group_info, i))
+                       return 0;
+       return 1;
 }
 
 /*
@@ -143,7 +140,7 @@ static __be32 *
 unx_marshal(struct rpc_task *task, __be32 *p)
 {
        struct rpc_clnt *clnt = task->tk_client;
-       struct unx_cred *cred = (struct unx_cred *) task->tk_msg.rpc_cred;
+       struct unx_cred *cred = container_of(task->tk_msg.rpc_cred, struct unx_cred, uc_base);
        __be32          *base, *hold;
        int             i;
 
@@ -176,7 +173,7 @@ unx_marshal(struct rpc_task *task, __be32 *p)
 static int
 unx_refresh(struct rpc_task *task)
 {
-       task->tk_msg.rpc_cred->cr_flags |= RPCAUTH_CRED_UPTODATE;
+       set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_msg.rpc_cred->cr_flags);
        return 0;
 }
 
@@ -199,18 +196,21 @@ unx_validate(struct rpc_task *task, __be32 *p)
                printk("RPC: giant verf size: %u\n", size);
                return NULL;
        }
-       task->tk_auth->au_rslack = (size >> 2) + 2;
+       task->tk_msg.rpc_cred->cr_auth->au_rslack = (size >> 2) + 2;
        p += (size >> 2);
 
        return p;
 }
 
-struct rpc_authops     authunix_ops = {
+void __init rpc_init_authunix(void)
+{
+       spin_lock_init(&unix_cred_cache.lock);
+}
+
+const struct rpc_authops authunix_ops = {
        .owner          = THIS_MODULE,
        .au_flavor      = RPC_AUTH_UNIX,
-#ifdef RPC_DEBUG
        .au_name        = "UNIX",
-#endif
        .create         = unx_create,
        .destroy        = unx_destroy,
        .lookup_cred    = unx_lookup_cred,
@@ -219,7 +219,6 @@ struct rpc_authops  authunix_ops = {
 
 static
 struct rpc_cred_cache  unix_cred_cache = {
-       .expire         = UNX_CRED_EXPIRE,
 };
 
 static
@@ -233,9 +232,10 @@ struct rpc_auth            unix_auth = {
 };
 
 static
-struct rpc_credops     unix_credops = {
+const struct rpc_credops unix_credops = {
        .cr_name        = "AUTH_UNIX",
        .crdestroy      = unx_destroy_cred,
+       .crbind         = rpcauth_generic_bind_cred,
        .crmatch        = unx_match,
        .crmarshal      = unx_marshal,
        .crrefresh      = unx_refresh,