static int
 nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
 {
-       struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
+       struct rpc_auth *auth = req->rq_cred->cr_auth;
        unsigned int replen;
        u32 offset = (u32)args->offset;
        u32 count = args->count;
 static int
 nfs_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs_readdirargs *args)
 {
-       struct rpc_task *task = req->rq_task;
-       struct rpc_auth *auth = task->tk_msg.rpc_cred->cr_auth;
+       struct rpc_auth *auth = req->rq_cred->cr_auth;
        unsigned int replen;
        u32 count = args->count;
 
 static int
 nfs_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_readlinkargs *args)
 {
-       struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
+       struct rpc_auth *auth = req->rq_cred->cr_auth;
        unsigned int replen;
 
        p = xdr_encode_fhandle(p, args->fh);
 
 static int
 nfs3_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
 {
-       struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
+       struct rpc_auth *auth = req->rq_cred->cr_auth;
        unsigned int replen;
        u32 count = args->count;
 
 static int
 nfs3_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirargs *args)
 {
-       struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
+       struct rpc_auth *auth = req->rq_cred->cr_auth;
        unsigned int replen;
        u32 count = args->count;
 
 nfs3_xdr_getaclargs(struct rpc_rqst *req, __be32 *p,
                    struct nfs3_getaclargs *args)
 {
-       struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
+       struct rpc_auth *auth = req->rq_cred->cr_auth;
        unsigned int replen;
 
        p = xdr_encode_fhandle(p, args->fh);
 static int
 nfs3_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readlinkargs *args)
 {
-       struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
+       struct rpc_auth *auth = req->rq_cred->cr_auth;
        unsigned int replen;
 
        p = xdr_encode_fhandle(p, args->fh);
 
                                struct compound_hdr *hdr)
 {
        __be32 *p;
-       struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
+       struct rpc_auth *auth = req->rq_cred->cr_auth;
 
        /* initialize running count of expected bytes in reply.
         * NOTE: the replied tag SHOULD be the same is the one sent,
 
 struct rpc_cred *      rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int);
 void                   rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *);
 struct rpc_cred *      rpcauth_lookupcred(struct rpc_auth *, int);
-int                    rpcauth_bindcred(struct rpc_task *, struct rpc_cred *, int);
 struct rpc_cred *      rpcauth_generic_bind_cred(struct rpc_task *, struct rpc_cred *, int);
 void                   put_rpccred(struct rpc_cred *);
-void                   rpcauth_unbindcred(struct rpc_task *);
 __be32 *               rpcauth_marshcred(struct rpc_task *, __be32 *);
 __be32 *               rpcauth_checkverf(struct rpc_task *, __be32 *);
 int                    rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, __be32 *data, void *obj);
 
         * This is the private part
         */
        struct rpc_task *       rq_task;        /* RPC task data */
+       struct rpc_cred *       rq_cred;        /* Bound cred */
        __be32                  rq_xid;         /* request XID */
        int                     rq_cong;        /* has incremented xprt->cong */
        u32                     rq_seqno;       /* gss seq no. used on req. */
 
        return rpcauth_lookupcred(auth, lookupflags);
 }
 
-int
+static int
 rpcauth_bindcred(struct rpc_task *task, struct rpc_cred *cred, int flags)
 {
+       struct rpc_rqst *req = task->tk_rqstp;
        struct rpc_cred *new;
        int lookupflags = 0;
 
                new = rpcauth_bind_new_cred(task, lookupflags);
        if (IS_ERR(new))
                return PTR_ERR(new);
-       if (task->tk_msg.rpc_cred != NULL)
-               put_rpccred(task->tk_msg.rpc_cred);
-       task->tk_msg.rpc_cred = new;
+       if (req->rq_cred != NULL)
+               put_rpccred(req->rq_cred);
+       req->rq_cred = new;
        return 0;
 }
 
 }
 EXPORT_SYMBOL_GPL(put_rpccred);
 
-void
-rpcauth_unbindcred(struct rpc_task *task)
-{
-       struct rpc_cred *cred = task->tk_msg.rpc_cred;
-
-       dprintk("RPC: %5u releasing %s cred %p\n",
-               task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
-
-       put_rpccred(cred);
-       task->tk_msg.rpc_cred = NULL;
-}
-
 __be32 *
 rpcauth_marshcred(struct rpc_task *task, __be32 *p)
 {
-       struct rpc_cred *cred = task->tk_msg.rpc_cred;
+       struct rpc_cred *cred = task->tk_rqstp->rq_cred;
 
        dprintk("RPC: %5u marshaling %s cred %p\n",
                task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
 __be32 *
 rpcauth_checkverf(struct rpc_task *task, __be32 *p)
 {
-       struct rpc_cred *cred = task->tk_msg.rpc_cred;
+       struct rpc_cred *cred = task->tk_rqstp->rq_cred;
 
        dprintk("RPC: %5u validating %s cred %p\n",
                task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
 rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp,
                __be32 *data, void *obj)
 {
-       struct rpc_cred *cred = task->tk_msg.rpc_cred;
+       struct rpc_cred *cred = task->tk_rqstp->rq_cred;
 
        dprintk("RPC: %5u using %s cred %p to wrap rpc data\n",
                        task->tk_pid, cred->cr_ops->cr_name, cred);
 rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp,
                __be32 *data, void *obj)
 {
-       struct rpc_cred *cred = task->tk_msg.rpc_cred;
+       struct rpc_cred *cred = task->tk_rqstp->rq_cred;
 
        dprintk("RPC: %5u using %s cred %p to unwrap rpc data\n",
                        task->tk_pid, cred->cr_ops->cr_name, cred);
 int
 rpcauth_refreshcred(struct rpc_task *task)
 {
-       struct rpc_cred *cred = task->tk_msg.rpc_cred;
+       struct rpc_cred *cred = task->tk_rqstp->rq_cred;
        int err;
 
+       cred = task->tk_rqstp->rq_cred;
+       if (cred == NULL) {
+               err = rpcauth_bindcred(task, task->tk_msg.rpc_cred, task->tk_flags);
+               if (err < 0)
+                       goto out;
+               cred = task->tk_rqstp->rq_cred;
+       };
        dprintk("RPC: %5u refreshing %s cred %p\n",
                task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
 
        err = cred->cr_ops->crrefresh(task);
+out:
        if (err < 0)
                task->tk_status = err;
        return err;
 void
 rpcauth_invalcred(struct rpc_task *task)
 {
-       struct rpc_cred *cred = task->tk_msg.rpc_cred;
+       struct rpc_cred *cred = task->tk_rqstp->rq_cred;
 
        dprintk("RPC: %5u invalidating %s cred %p\n",
                task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
 int
 rpcauth_uptodatecred(struct rpc_task *task)
 {
-       struct rpc_cred *cred = task->tk_msg.rpc_cred;
+       struct rpc_cred *cred = task->tk_rqstp->rq_cred;
 
        return cred == NULL ||
                test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0;
 
 static void
 gss_upcall_callback(struct rpc_task *task)
 {
-       struct gss_cred *gss_cred = container_of(task->tk_msg.rpc_cred,
+       struct gss_cred *gss_cred = container_of(task->tk_rqstp->rq_cred,
                        struct gss_cred, gc_base);
        struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall;
        struct inode *inode = &gss_msg->inode->vfs_inode;
 static inline int
 gss_refresh_upcall(struct rpc_task *task)
 {
-       struct rpc_cred *cred = task->tk_msg.rpc_cred;
+       struct rpc_cred *cred = task->tk_rqstp->rq_cred;
        struct gss_auth *gss_auth = container_of(cred->cr_auth,
                        struct gss_auth, rpc_auth);
        struct gss_cred *gss_cred = container_of(cred,
 static __be32 *
 gss_marshal(struct rpc_task *task, __be32 *p)
 {
-       struct rpc_cred *cred = task->tk_msg.rpc_cred;
+       struct rpc_rqst *req = task->tk_rqstp;
+       struct rpc_cred *cred = req->rq_cred;
        struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
                                                 gc_base);
        struct gss_cl_ctx       *ctx = gss_cred_get_ctx(cred);
        __be32          *cred_len;
-       struct rpc_rqst *req = task->tk_rqstp;
        u32             maj_stat = 0;
        struct xdr_netobj mic;
        struct kvec     iov;
 
 static int gss_renew_cred(struct rpc_task *task)
 {
-       struct rpc_cred *oldcred = task->tk_msg.rpc_cred;
+       struct rpc_cred *oldcred = task->tk_rqstp->rq_cred;
        struct gss_cred *gss_cred = container_of(oldcred,
                                                 struct gss_cred,
                                                 gc_base);
        new = gss_lookup_cred(auth, &acred, RPCAUTH_LOOKUP_NEW);
        if (IS_ERR(new))
                return PTR_ERR(new);
-       task->tk_msg.rpc_cred = new;
+       task->tk_rqstp->rq_cred = new;
        put_rpccred(oldcred);
        return 0;
 }
 static int
 gss_refresh(struct rpc_task *task)
 {
-       struct rpc_cred *cred = task->tk_msg.rpc_cred;
+       struct rpc_cred *cred = task->tk_rqstp->rq_cred;
        int ret = 0;
 
        if (gss_cred_is_negative_entry(cred))
                ret = gss_renew_cred(task);
                if (ret < 0)
                        goto out;
-               cred = task->tk_msg.rpc_cred;
+               cred = task->tk_rqstp->rq_cred;
        }
 
        if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags))
 static __be32 *
 gss_validate(struct rpc_task *task, __be32 *p)
 {
-       struct rpc_cred *cred = task->tk_msg.rpc_cred;
+       struct rpc_cred *cred = task->tk_rqstp->rq_cred;
        struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
        __be32          seq;
        struct kvec     iov;
 gss_wrap_req(struct rpc_task *task,
             kxdrproc_t encode, void *rqstp, __be32 *p, void *obj)
 {
-       struct rpc_cred *cred = task->tk_msg.rpc_cred;
+       struct rpc_cred *cred = task->tk_rqstp->rq_cred;
        struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
                        gc_base);
        struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
 gss_unwrap_resp(struct rpc_task *task,
                kxdrproc_t decode, void *rqstp, __be32 *p, void *obj)
 {
-       struct rpc_cred *cred = task->tk_msg.rpc_cred;
+       struct rpc_cred *cred = task->tk_rqstp->rq_cred;
        struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
                        gc_base);
        struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
 
 static int
 nul_refresh(struct rpc_task *task)
 {
-       set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_msg.rpc_cred->cr_flags);
+       set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_rqstp->rq_cred->cr_flags);
        return 0;
 }
 
 
 unx_marshal(struct rpc_task *task, __be32 *p)
 {
        struct rpc_clnt *clnt = task->tk_client;
-       struct unx_cred *cred = container_of(task->tk_msg.rpc_cred, struct unx_cred, uc_base);
+       struct unx_cred *cred = container_of(task->tk_rqstp->rq_cred, struct unx_cred, uc_base);
        __be32          *base, *hold;
        int             i;
 
 static int
 unx_refresh(struct rpc_task *task)
 {
-       set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_msg.rpc_cred->cr_flags);
+       set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_rqstp->rq_cred->cr_flags);
        return 0;
 }
 
                printk("RPC: giant verf size: %u\n", size);
                return NULL;
        }
-       task->tk_msg.rpc_cred->cr_auth->au_rslack = (size >> 2) + 2;
+       task->tk_rqstp->rq_cred->cr_auth->au_rslack = (size >> 2) + 2;
        p += (size >> 2);
 
        return p;
 
                task->tk_msg.rpc_proc = msg->rpc_proc;
                task->tk_msg.rpc_argp = msg->rpc_argp;
                task->tk_msg.rpc_resp = msg->rpc_resp;
-               /* Bind the user cred */
-               task->tk_status = rpcauth_bindcred(task, msg->rpc_cred, task->tk_flags);
+               if (msg->rpc_cred != NULL)
+                       task->tk_msg.rpc_cred = get_rpccred(msg->rpc_cred);
        }
 }
 
 {
        dprint_status(task);
 
-       if (!rpcauth_uptodatecred(task)) {
-               task->tk_action = call_refresh;
-               return;
-       }
-
        task->tk_status  = 0;
        task->tk_action  = call_reserveresult;
        xprt_reserve(task);
 static void
 call_allocate(struct rpc_task *task)
 {
-       unsigned int slack = task->tk_msg.rpc_cred->cr_auth->au_cslack;
+       unsigned int slack = task->tk_client->cl_auth->au_cslack;
        struct rpc_rqst *req = task->tk_rqstp;
        struct rpc_xprt *xprt = task->tk_xprt;
        struct rpc_procinfo *proc = task->tk_msg.rpc_proc;
        dprint_status(task);
 
        task->tk_status = 0;
-       task->tk_action = call_bind;
+       task->tk_action = call_refresh;
 
        if (req->rq_buffer)
                return;
        rpc_exit(task, -ERESTARTSYS);
 }
 
+/*
+ * 2a. Bind and/or refresh the credentials
+ */
+static void
+call_refresh(struct rpc_task *task)
+{
+       dprint_status(task);
+
+       task->tk_action = call_refreshresult;
+       task->tk_status = 0;
+       task->tk_client->cl_stats->rpcauthrefresh++;
+       rpcauth_refreshcred(task);
+}
+
+/*
+ * 2b. Process the results of a credential refresh
+ */
+static void
+call_refreshresult(struct rpc_task *task)
+{
+       int status = task->tk_status;
+
+       dprint_status(task);
+
+       task->tk_status = 0;
+       task->tk_action = call_bind;
+       if (status >= 0 && rpcauth_uptodatecred(task))
+               return;
+       switch (status) {
+       case -EACCES:
+               rpc_exit(task, -EACCES);
+               return;
+       case -ENOMEM:
+               rpc_exit(task, -ENOMEM);
+               return;
+       case -ETIMEDOUT:
+               rpc_delay(task, 3*HZ);
+       }
+       task->tk_action = call_refresh;
+}
+
 static inline int
 rpc_task_need_encode(struct rpc_task *task)
 {
        }
 }
 
-/*
- * 8.  Refresh the credentials if rejected by the server
- */
-static void
-call_refresh(struct rpc_task *task)
-{
-       dprint_status(task);
-
-       task->tk_action = call_refreshresult;
-       task->tk_status = 0;
-       task->tk_client->cl_stats->rpcauthrefresh++;
-       rpcauth_refreshcred(task);
-}
-
-/*
- * 8a. Process the results of a credential refresh
- */
-static void
-call_refreshresult(struct rpc_task *task)
-{
-       int status = task->tk_status;
-
-       dprint_status(task);
-
-       task->tk_status = 0;
-       task->tk_action = call_reserve;
-       if (status >= 0 && rpcauth_uptodatecred(task))
-               return;
-       if (status == -EACCES) {
-               rpc_exit(task, -EACCES);
-               return;
-       }
-       task->tk_action = call_refresh;
-       if (status != -ETIMEDOUT)
-               rpc_delay(task, 3*HZ);
-}
-
 static __be32 *
 rpc_encode_header(struct rpc_task *task)
 {
 
        if (task->tk_rqstp)
                xprt_release(task);
        if (task->tk_msg.rpc_cred)
-               rpcauth_unbindcred(task);
+               put_rpccred(task->tk_msg.rpc_cred);
        rpc_task_release_client(task);
        if (task->tk_workqueue != NULL) {
                INIT_WORK(&task->u.tk_work, rpc_async_release);
 
        spin_unlock_bh(&xprt->transport_lock);
        if (req->rq_buffer)
                xprt->ops->buf_free(req->rq_buffer);
+       if (req->rq_cred != NULL)
+               put_rpccred(req->rq_cred);
        task->tk_rqstp = NULL;
        if (req->rq_release_snd_buf)
                req->rq_release_snd_buf(req);