aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2010-07-31 14:29:08 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-08-04 08:54:09 -0400
commita17c2153d2e271b0cbacae9bed83b0eaa41db7e1 (patch)
tree3c5a73090987278e51aee1a9f185ebe40a00bd65
parent8572b8e2e3c5f3d990122348c4d2c64dad338611 (diff)
SUNRPC: Move the bound cred to struct rpc_rqst
This will allow us to save the original generic cred in rpc_message, so that if we migrate from one server to another, we can generate a new bound cred without having to punt back to the NFS layer. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/nfs2xdr.c7
-rw-r--r--fs/nfs/nfs3xdr.c8
-rw-r--r--fs/nfs/nfs4xdr.c2
-rw-r--r--include/linux/sunrpc/auth.h2
-rw-r--r--include/linux/sunrpc/xprt.h1
-rw-r--r--net/sunrpc/auth.c43
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c22
-rw-r--r--net/sunrpc/auth_null.c2
-rw-r--r--net/sunrpc/auth_unix.c6
-rw-r--r--net/sunrpc/clnt.c91
-rw-r--r--net/sunrpc/sched.c2
-rw-r--r--net/sunrpc/xprt.c2
12 files changed, 92 insertions, 96 deletions
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 81cf14257916..db8846a0e82e 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -233,7 +233,7 @@ nfs_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs
233static int 233static int
234nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args) 234nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
235{ 235{
236 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; 236 struct rpc_auth *auth = req->rq_cred->cr_auth;
237 unsigned int replen; 237 unsigned int replen;
238 u32 offset = (u32)args->offset; 238 u32 offset = (u32)args->offset;
239 u32 count = args->count; 239 u32 count = args->count;
@@ -393,8 +393,7 @@ nfs_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_symlinkargs *arg
393static int 393static int
394nfs_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs_readdirargs *args) 394nfs_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs_readdirargs *args)
395{ 395{
396 struct rpc_task *task = req->rq_task; 396 struct rpc_auth *auth = req->rq_cred->cr_auth;
397 struct rpc_auth *auth = task->tk_msg.rpc_cred->cr_auth;
398 unsigned int replen; 397 unsigned int replen;
399 u32 count = args->count; 398 u32 count = args->count;
400 399
@@ -575,7 +574,7 @@ nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res)
575static int 574static int
576nfs_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_readlinkargs *args) 575nfs_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_readlinkargs *args)
577{ 576{
578 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; 577 struct rpc_auth *auth = req->rq_cred->cr_auth;
579 unsigned int replen; 578 unsigned int replen;
580 579
581 p = xdr_encode_fhandle(p, args->fh); 580 p = xdr_encode_fhandle(p, args->fh);
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index 75dcfc7da365..9769704f8ce6 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -330,7 +330,7 @@ nfs3_xdr_accessargs(struct rpc_rqst *req, __be32 *p, struct nfs3_accessargs *arg
330static int 330static int
331nfs3_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args) 331nfs3_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
332{ 332{
333 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; 333 struct rpc_auth *auth = req->rq_cred->cr_auth;
334 unsigned int replen; 334 unsigned int replen;
335 u32 count = args->count; 335 u32 count = args->count;
336 336
@@ -471,7 +471,7 @@ nfs3_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_linkargs *args)
471static int 471static int
472nfs3_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirargs *args) 472nfs3_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirargs *args)
473{ 473{
474 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; 474 struct rpc_auth *auth = req->rq_cred->cr_auth;
475 unsigned int replen; 475 unsigned int replen;
476 u32 count = args->count; 476 u32 count = args->count;
477 477
@@ -675,7 +675,7 @@ static int
675nfs3_xdr_getaclargs(struct rpc_rqst *req, __be32 *p, 675nfs3_xdr_getaclargs(struct rpc_rqst *req, __be32 *p,
676 struct nfs3_getaclargs *args) 676 struct nfs3_getaclargs *args)
677{ 677{
678 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; 678 struct rpc_auth *auth = req->rq_cred->cr_auth;
679 unsigned int replen; 679 unsigned int replen;
680 680
681 p = xdr_encode_fhandle(p, args->fh); 681 p = xdr_encode_fhandle(p, args->fh);
@@ -802,7 +802,7 @@ nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res)
802static int 802static int
803nfs3_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readlinkargs *args) 803nfs3_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readlinkargs *args)
804{ 804{
805 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; 805 struct rpc_auth *auth = req->rq_cred->cr_auth;
806 unsigned int replen; 806 unsigned int replen;
807 807
808 p = xdr_encode_fhandle(p, args->fh); 808 p = xdr_encode_fhandle(p, args->fh);
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 257c1811feb4..08ef91291132 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -758,7 +758,7 @@ static void encode_compound_hdr(struct xdr_stream *xdr,
758 struct compound_hdr *hdr) 758 struct compound_hdr *hdr)
759{ 759{
760 __be32 *p; 760 __be32 *p;
761 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; 761 struct rpc_auth *auth = req->rq_cred->cr_auth;
762 762
763 /* initialize running count of expected bytes in reply. 763 /* initialize running count of expected bytes in reply.
764 * NOTE: the replied tag SHOULD be the same is the one sent, 764 * NOTE: the replied tag SHOULD be the same is the one sent,
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index 90e4c3827ac0..5bbc447175dc 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -135,10 +135,8 @@ void rpcauth_release(struct rpc_auth *);
135struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int); 135struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int);
136void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *); 136void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *);
137struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int); 137struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int);
138int rpcauth_bindcred(struct rpc_task *, struct rpc_cred *, int);
139struct rpc_cred * rpcauth_generic_bind_cred(struct rpc_task *, struct rpc_cred *, int); 138struct rpc_cred * rpcauth_generic_bind_cred(struct rpc_task *, struct rpc_cred *, int);
140void put_rpccred(struct rpc_cred *); 139void put_rpccred(struct rpc_cred *);
141void rpcauth_unbindcred(struct rpc_task *);
142__be32 * rpcauth_marshcred(struct rpc_task *, __be32 *); 140__be32 * rpcauth_marshcred(struct rpc_task *, __be32 *);
143__be32 * rpcauth_checkverf(struct rpc_task *, __be32 *); 141__be32 * rpcauth_checkverf(struct rpc_task *, __be32 *);
144int rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, __be32 *data, void *obj); 142int rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, __be32 *data, void *obj);
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index b51470302399..ff5a77b28c50 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -64,6 +64,7 @@ struct rpc_rqst {
64 * This is the private part 64 * This is the private part
65 */ 65 */
66 struct rpc_task * rq_task; /* RPC task data */ 66 struct rpc_task * rq_task; /* RPC task data */
67 struct rpc_cred * rq_cred; /* Bound cred */
67 __be32 rq_xid; /* request XID */ 68 __be32 rq_xid; /* request XID */
68 int rq_cong; /* has incremented xprt->cong */ 69 int rq_cong; /* has incremented xprt->cong */
69 u32 rq_seqno; /* gss seq no. used on req. */ 70 u32 rq_seqno; /* gss seq no. used on req. */
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index d8968faf5ccf..95721426296d 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -477,9 +477,10 @@ rpcauth_bind_new_cred(struct rpc_task *task, int lookupflags)
477 return rpcauth_lookupcred(auth, lookupflags); 477 return rpcauth_lookupcred(auth, lookupflags);
478} 478}
479 479
480int 480static int
481rpcauth_bindcred(struct rpc_task *task, struct rpc_cred *cred, int flags) 481rpcauth_bindcred(struct rpc_task *task, struct rpc_cred *cred, int flags)
482{ 482{
483 struct rpc_rqst *req = task->tk_rqstp;
483 struct rpc_cred *new; 484 struct rpc_cred *new;
484 int lookupflags = 0; 485 int lookupflags = 0;
485 486
@@ -493,9 +494,9 @@ rpcauth_bindcred(struct rpc_task *task, struct rpc_cred *cred, int flags)
493 new = rpcauth_bind_new_cred(task, lookupflags); 494 new = rpcauth_bind_new_cred(task, lookupflags);
494 if (IS_ERR(new)) 495 if (IS_ERR(new))
495 return PTR_ERR(new); 496 return PTR_ERR(new);
496 if (task->tk_msg.rpc_cred != NULL) 497 if (req->rq_cred != NULL)
497 put_rpccred(task->tk_msg.rpc_cred); 498 put_rpccred(req->rq_cred);
498 task->tk_msg.rpc_cred = new; 499 req->rq_cred = new;
499 return 0; 500 return 0;
500} 501}
501 502
@@ -535,22 +536,10 @@ out_nodestroy:
535} 536}
536EXPORT_SYMBOL_GPL(put_rpccred); 537EXPORT_SYMBOL_GPL(put_rpccred);
537 538
538void
539rpcauth_unbindcred(struct rpc_task *task)
540{
541 struct rpc_cred *cred = task->tk_msg.rpc_cred;
542
543 dprintk("RPC: %5u releasing %s cred %p\n",
544 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
545
546 put_rpccred(cred);
547 task->tk_msg.rpc_cred = NULL;
548}
549
550__be32 * 539__be32 *
551rpcauth_marshcred(struct rpc_task *task, __be32 *p) 540rpcauth_marshcred(struct rpc_task *task, __be32 *p)
552{ 541{
553 struct rpc_cred *cred = task->tk_msg.rpc_cred; 542 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
554 543
555 dprintk("RPC: %5u marshaling %s cred %p\n", 544 dprintk("RPC: %5u marshaling %s cred %p\n",
556 task->tk_pid, cred->cr_auth->au_ops->au_name, cred); 545 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
@@ -561,7 +550,7 @@ rpcauth_marshcred(struct rpc_task *task, __be32 *p)
561__be32 * 550__be32 *
562rpcauth_checkverf(struct rpc_task *task, __be32 *p) 551rpcauth_checkverf(struct rpc_task *task, __be32 *p)
563{ 552{
564 struct rpc_cred *cred = task->tk_msg.rpc_cred; 553 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
565 554
566 dprintk("RPC: %5u validating %s cred %p\n", 555 dprintk("RPC: %5u validating %s cred %p\n",
567 task->tk_pid, cred->cr_auth->au_ops->au_name, cred); 556 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
@@ -573,7 +562,7 @@ int
573rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, 562rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp,
574 __be32 *data, void *obj) 563 __be32 *data, void *obj)
575{ 564{
576 struct rpc_cred *cred = task->tk_msg.rpc_cred; 565 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
577 566
578 dprintk("RPC: %5u using %s cred %p to wrap rpc data\n", 567 dprintk("RPC: %5u using %s cred %p to wrap rpc data\n",
579 task->tk_pid, cred->cr_ops->cr_name, cred); 568 task->tk_pid, cred->cr_ops->cr_name, cred);
@@ -587,7 +576,7 @@ int
587rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, 576rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp,
588 __be32 *data, void *obj) 577 __be32 *data, void *obj)
589{ 578{
590 struct rpc_cred *cred = task->tk_msg.rpc_cred; 579 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
591 580
592 dprintk("RPC: %5u using %s cred %p to unwrap rpc data\n", 581 dprintk("RPC: %5u using %s cred %p to unwrap rpc data\n",
593 task->tk_pid, cred->cr_ops->cr_name, cred); 582 task->tk_pid, cred->cr_ops->cr_name, cred);
@@ -601,13 +590,21 @@ rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp,
601int 590int
602rpcauth_refreshcred(struct rpc_task *task) 591rpcauth_refreshcred(struct rpc_task *task)
603{ 592{
604 struct rpc_cred *cred = task->tk_msg.rpc_cred; 593 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
605 int err; 594 int err;
606 595
596 cred = task->tk_rqstp->rq_cred;
597 if (cred == NULL) {
598 err = rpcauth_bindcred(task, task->tk_msg.rpc_cred, task->tk_flags);
599 if (err < 0)
600 goto out;
601 cred = task->tk_rqstp->rq_cred;
602 };
607 dprintk("RPC: %5u refreshing %s cred %p\n", 603 dprintk("RPC: %5u refreshing %s cred %p\n",
608 task->tk_pid, cred->cr_auth->au_ops->au_name, cred); 604 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
609 605
610 err = cred->cr_ops->crrefresh(task); 606 err = cred->cr_ops->crrefresh(task);
607out:
611 if (err < 0) 608 if (err < 0)
612 task->tk_status = err; 609 task->tk_status = err;
613 return err; 610 return err;
@@ -616,7 +613,7 @@ rpcauth_refreshcred(struct rpc_task *task)
616void 613void
617rpcauth_invalcred(struct rpc_task *task) 614rpcauth_invalcred(struct rpc_task *task)
618{ 615{
619 struct rpc_cred *cred = task->tk_msg.rpc_cred; 616 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
620 617
621 dprintk("RPC: %5u invalidating %s cred %p\n", 618 dprintk("RPC: %5u invalidating %s cred %p\n",
622 task->tk_pid, cred->cr_auth->au_ops->au_name, cred); 619 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
@@ -627,7 +624,7 @@ rpcauth_invalcred(struct rpc_task *task)
627int 624int
628rpcauth_uptodatecred(struct rpc_task *task) 625rpcauth_uptodatecred(struct rpc_task *task)
629{ 626{
630 struct rpc_cred *cred = task->tk_msg.rpc_cred; 627 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
631 628
632 return cred == NULL || 629 return cred == NULL ||
633 test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0; 630 test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0;
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 8da2a0e68574..096e1260bc67 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -373,7 +373,7 @@ gss_handle_downcall_result(struct gss_cred *gss_cred, struct gss_upcall_msg *gss
373static void 373static void
374gss_upcall_callback(struct rpc_task *task) 374gss_upcall_callback(struct rpc_task *task)
375{ 375{
376 struct gss_cred *gss_cred = container_of(task->tk_msg.rpc_cred, 376 struct gss_cred *gss_cred = container_of(task->tk_rqstp->rq_cred,
377 struct gss_cred, gc_base); 377 struct gss_cred, gc_base);
378 struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall; 378 struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall;
379 struct inode *inode = &gss_msg->inode->vfs_inode; 379 struct inode *inode = &gss_msg->inode->vfs_inode;
@@ -502,7 +502,7 @@ static void warn_gssd(void)
502static inline int 502static inline int
503gss_refresh_upcall(struct rpc_task *task) 503gss_refresh_upcall(struct rpc_task *task)
504{ 504{
505 struct rpc_cred *cred = task->tk_msg.rpc_cred; 505 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
506 struct gss_auth *gss_auth = container_of(cred->cr_auth, 506 struct gss_auth *gss_auth = container_of(cred->cr_auth,
507 struct gss_auth, rpc_auth); 507 struct gss_auth, rpc_auth);
508 struct gss_cred *gss_cred = container_of(cred, 508 struct gss_cred *gss_cred = container_of(cred,
@@ -1064,12 +1064,12 @@ out:
1064static __be32 * 1064static __be32 *
1065gss_marshal(struct rpc_task *task, __be32 *p) 1065gss_marshal(struct rpc_task *task, __be32 *p)
1066{ 1066{
1067 struct rpc_cred *cred = task->tk_msg.rpc_cred; 1067 struct rpc_rqst *req = task->tk_rqstp;
1068 struct rpc_cred *cred = req->rq_cred;
1068 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, 1069 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1069 gc_base); 1070 gc_base);
1070 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred); 1071 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1071 __be32 *cred_len; 1072 __be32 *cred_len;
1072 struct rpc_rqst *req = task->tk_rqstp;
1073 u32 maj_stat = 0; 1073 u32 maj_stat = 0;
1074 struct xdr_netobj mic; 1074 struct xdr_netobj mic;
1075 struct kvec iov; 1075 struct kvec iov;
@@ -1119,7 +1119,7 @@ out_put_ctx:
1119 1119
1120static int gss_renew_cred(struct rpc_task *task) 1120static int gss_renew_cred(struct rpc_task *task)
1121{ 1121{
1122 struct rpc_cred *oldcred = task->tk_msg.rpc_cred; 1122 struct rpc_cred *oldcred = task->tk_rqstp->rq_cred;
1123 struct gss_cred *gss_cred = container_of(oldcred, 1123 struct gss_cred *gss_cred = container_of(oldcred,
1124 struct gss_cred, 1124 struct gss_cred,
1125 gc_base); 1125 gc_base);
@@ -1133,7 +1133,7 @@ static int gss_renew_cred(struct rpc_task *task)
1133 new = gss_lookup_cred(auth, &acred, RPCAUTH_LOOKUP_NEW); 1133 new = gss_lookup_cred(auth, &acred, RPCAUTH_LOOKUP_NEW);
1134 if (IS_ERR(new)) 1134 if (IS_ERR(new))
1135 return PTR_ERR(new); 1135 return PTR_ERR(new);
1136 task->tk_msg.rpc_cred = new; 1136 task->tk_rqstp->rq_cred = new;
1137 put_rpccred(oldcred); 1137 put_rpccred(oldcred);
1138 return 0; 1138 return 0;
1139} 1139}
@@ -1161,7 +1161,7 @@ static int gss_cred_is_negative_entry(struct rpc_cred *cred)
1161static int 1161static int
1162gss_refresh(struct rpc_task *task) 1162gss_refresh(struct rpc_task *task)
1163{ 1163{
1164 struct rpc_cred *cred = task->tk_msg.rpc_cred; 1164 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1165 int ret = 0; 1165 int ret = 0;
1166 1166
1167 if (gss_cred_is_negative_entry(cred)) 1167 if (gss_cred_is_negative_entry(cred))
@@ -1172,7 +1172,7 @@ gss_refresh(struct rpc_task *task)
1172 ret = gss_renew_cred(task); 1172 ret = gss_renew_cred(task);
1173 if (ret < 0) 1173 if (ret < 0)
1174 goto out; 1174 goto out;
1175 cred = task->tk_msg.rpc_cred; 1175 cred = task->tk_rqstp->rq_cred;
1176 } 1176 }
1177 1177
1178 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags)) 1178 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags))
@@ -1191,7 +1191,7 @@ gss_refresh_null(struct rpc_task *task)
1191static __be32 * 1191static __be32 *
1192gss_validate(struct rpc_task *task, __be32 *p) 1192gss_validate(struct rpc_task *task, __be32 *p)
1193{ 1193{
1194 struct rpc_cred *cred = task->tk_msg.rpc_cred; 1194 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1195 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred); 1195 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1196 __be32 seq; 1196 __be32 seq;
1197 struct kvec iov; 1197 struct kvec iov;
@@ -1400,7 +1400,7 @@ static int
1400gss_wrap_req(struct rpc_task *task, 1400gss_wrap_req(struct rpc_task *task,
1401 kxdrproc_t encode, void *rqstp, __be32 *p, void *obj) 1401 kxdrproc_t encode, void *rqstp, __be32 *p, void *obj)
1402{ 1402{
1403 struct rpc_cred *cred = task->tk_msg.rpc_cred; 1403 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1404 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, 1404 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1405 gc_base); 1405 gc_base);
1406 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred); 1406 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
@@ -1503,7 +1503,7 @@ static int
1503gss_unwrap_resp(struct rpc_task *task, 1503gss_unwrap_resp(struct rpc_task *task,
1504 kxdrproc_t decode, void *rqstp, __be32 *p, void *obj) 1504 kxdrproc_t decode, void *rqstp, __be32 *p, void *obj)
1505{ 1505{
1506 struct rpc_cred *cred = task->tk_msg.rpc_cred; 1506 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1507 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, 1507 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1508 gc_base); 1508 gc_base);
1509 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred); 1509 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
index 1db618f56ecb..a5c36c01707b 100644
--- a/net/sunrpc/auth_null.c
+++ b/net/sunrpc/auth_null.c
@@ -75,7 +75,7 @@ nul_marshal(struct rpc_task *task, __be32 *p)
75static int 75static int
76nul_refresh(struct rpc_task *task) 76nul_refresh(struct rpc_task *task)
77{ 77{
78 set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_msg.rpc_cred->cr_flags); 78 set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_rqstp->rq_cred->cr_flags);
79 return 0; 79 return 0;
80} 80}
81 81
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index d5e37dbf207b..4cb70dc6e7ad 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -140,7 +140,7 @@ static __be32 *
140unx_marshal(struct rpc_task *task, __be32 *p) 140unx_marshal(struct rpc_task *task, __be32 *p)
141{ 141{
142 struct rpc_clnt *clnt = task->tk_client; 142 struct rpc_clnt *clnt = task->tk_client;
143 struct unx_cred *cred = container_of(task->tk_msg.rpc_cred, struct unx_cred, uc_base); 143 struct unx_cred *cred = container_of(task->tk_rqstp->rq_cred, struct unx_cred, uc_base);
144 __be32 *base, *hold; 144 __be32 *base, *hold;
145 int i; 145 int i;
146 146
@@ -173,7 +173,7 @@ unx_marshal(struct rpc_task *task, __be32 *p)
173static int 173static int
174unx_refresh(struct rpc_task *task) 174unx_refresh(struct rpc_task *task)
175{ 175{
176 set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_msg.rpc_cred->cr_flags); 176 set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_rqstp->rq_cred->cr_flags);
177 return 0; 177 return 0;
178} 178}
179 179
@@ -196,7 +196,7 @@ unx_validate(struct rpc_task *task, __be32 *p)
196 printk("RPC: giant verf size: %u\n", size); 196 printk("RPC: giant verf size: %u\n", size);
197 return NULL; 197 return NULL;
198 } 198 }
199 task->tk_msg.rpc_cred->cr_auth->au_rslack = (size >> 2) + 2; 199 task->tk_rqstp->rq_cred->cr_auth->au_rslack = (size >> 2) + 2;
200 p += (size >> 2); 200 p += (size >> 2);
201 201
202 return p; 202 return p;
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index f34b5e3823c0..2388d83b68ff 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -605,8 +605,8 @@ rpc_task_set_rpc_message(struct rpc_task *task, const struct rpc_message *msg)
605 task->tk_msg.rpc_proc = msg->rpc_proc; 605 task->tk_msg.rpc_proc = msg->rpc_proc;
606 task->tk_msg.rpc_argp = msg->rpc_argp; 606 task->tk_msg.rpc_argp = msg->rpc_argp;
607 task->tk_msg.rpc_resp = msg->rpc_resp; 607 task->tk_msg.rpc_resp = msg->rpc_resp;
608 /* Bind the user cred */ 608 if (msg->rpc_cred != NULL)
609 task->tk_status = rpcauth_bindcred(task, msg->rpc_cred, task->tk_flags); 609 task->tk_msg.rpc_cred = get_rpccred(msg->rpc_cred);
610 } 610 }
611} 611}
612 612
@@ -909,11 +909,6 @@ call_reserve(struct rpc_task *task)
909{ 909{
910 dprint_status(task); 910 dprint_status(task);
911 911
912 if (!rpcauth_uptodatecred(task)) {
913 task->tk_action = call_refresh;
914 return;
915 }
916
917 task->tk_status = 0; 912 task->tk_status = 0;
918 task->tk_action = call_reserveresult; 913 task->tk_action = call_reserveresult;
919 xprt_reserve(task); 914 xprt_reserve(task);
@@ -977,7 +972,7 @@ call_reserveresult(struct rpc_task *task)
977static void 972static void
978call_allocate(struct rpc_task *task) 973call_allocate(struct rpc_task *task)
979{ 974{
980 unsigned int slack = task->tk_msg.rpc_cred->cr_auth->au_cslack; 975 unsigned int slack = task->tk_client->cl_auth->au_cslack;
981 struct rpc_rqst *req = task->tk_rqstp; 976 struct rpc_rqst *req = task->tk_rqstp;
982 struct rpc_xprt *xprt = task->tk_xprt; 977 struct rpc_xprt *xprt = task->tk_xprt;
983 struct rpc_procinfo *proc = task->tk_msg.rpc_proc; 978 struct rpc_procinfo *proc = task->tk_msg.rpc_proc;
@@ -985,7 +980,7 @@ call_allocate(struct rpc_task *task)
985 dprint_status(task); 980 dprint_status(task);
986 981
987 task->tk_status = 0; 982 task->tk_status = 0;
988 task->tk_action = call_bind; 983 task->tk_action = call_refresh;
989 984
990 if (req->rq_buffer) 985 if (req->rq_buffer)
991 return; 986 return;
@@ -1022,6 +1017,47 @@ call_allocate(struct rpc_task *task)
1022 rpc_exit(task, -ERESTARTSYS); 1017 rpc_exit(task, -ERESTARTSYS);
1023} 1018}
1024 1019
1020/*
1021 * 2a. Bind and/or refresh the credentials
1022 */
1023static void
1024call_refresh(struct rpc_task *task)
1025{
1026 dprint_status(task);
1027
1028 task->tk_action = call_refreshresult;
1029 task->tk_status = 0;
1030 task->tk_client->cl_stats->rpcauthrefresh++;
1031 rpcauth_refreshcred(task);
1032}
1033
1034/*
1035 * 2b. Process the results of a credential refresh
1036 */
1037static void
1038call_refreshresult(struct rpc_task *task)
1039{
1040 int status = task->tk_status;
1041
1042 dprint_status(task);
1043
1044 task->tk_status = 0;
1045 task->tk_action = call_bind;
1046 if (status >= 0 && rpcauth_uptodatecred(task))
1047 return;
1048 switch (status) {
1049 case -EACCES:
1050 rpc_exit(task, -EACCES);
1051 return;
1052 case -ENOMEM:
1053 rpc_exit(task, -ENOMEM);
1054 return;
1055 case -ETIMEDOUT:
1056 rpc_delay(task, 3*HZ);
1057 }
1058 task->tk_action = call_refresh;
1059}
1060
1025static inline int 1061static inline int
1026rpc_task_need_encode(struct rpc_task *task) 1062rpc_task_need_encode(struct rpc_task *task)
1027{ 1063{
@@ -1557,43 +1593,6 @@ out_retry:
1557 } 1593 }
1558} 1594}
1559 1595
1560/*
1561 * 8. Refresh the credentials if rejected by the server
1562 */
1563static void
1564call_refresh(struct rpc_task *task)
1565{
1566 dprint_status(task);
1567
1568 task->tk_action = call_refreshresult;
1569 task->tk_status = 0;
1570 task->tk_client->cl_stats->rpcauthrefresh++;
1571 rpcauth_refreshcred(task);
1572}
1573
1574/*
1575 * 8a. Process the results of a credential refresh
1576 */
1577static void
1578call_refreshresult(struct rpc_task *task)
1579{
1580 int status = task->tk_status;
1581
1582 dprint_status(task);
1583
1584 task->tk_status = 0;
1585 task->tk_action = call_reserve;
1586 if (status >= 0 && rpcauth_uptodatecred(task))
1587 return;
1588 if (status == -EACCES) {
1589 rpc_exit(task, -EACCES);
1590 return;
1591 }
1592 task->tk_action = call_refresh;
1593 if (status != -ETIMEDOUT)
1594 rpc_delay(task, 3*HZ);
1595}
1596
1597static __be32 * 1596static __be32 *
1598rpc_encode_header(struct rpc_task *task) 1597rpc_encode_header(struct rpc_task *task)
1599{ 1598{
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index a42296db2ecd..f6db6131fb2e 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -864,7 +864,7 @@ void rpc_put_task(struct rpc_task *task)
864 if (task->tk_rqstp) 864 if (task->tk_rqstp)
865 xprt_release(task); 865 xprt_release(task);
866 if (task->tk_msg.rpc_cred) 866 if (task->tk_msg.rpc_cred)
867 rpcauth_unbindcred(task); 867 put_rpccred(task->tk_msg.rpc_cred);
868 rpc_task_release_client(task); 868 rpc_task_release_client(task);
869 if (task->tk_workqueue != NULL) { 869 if (task->tk_workqueue != NULL) {
870 INIT_WORK(&task->u.tk_work, rpc_async_release); 870 INIT_WORK(&task->u.tk_work, rpc_async_release);
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index dcd0132396ba..70297836a191 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -1032,6 +1032,8 @@ void xprt_release(struct rpc_task *task)
1032 spin_unlock_bh(&xprt->transport_lock); 1032 spin_unlock_bh(&xprt->transport_lock);
1033 if (req->rq_buffer) 1033 if (req->rq_buffer)
1034 xprt->ops->buf_free(req->rq_buffer); 1034 xprt->ops->buf_free(req->rq_buffer);
1035 if (req->rq_cred != NULL)
1036 put_rpccred(req->rq_cred);
1035 task->tk_rqstp = NULL; 1037 task->tk_rqstp = NULL;
1036 if (req->rq_release_snd_buf) 1038 if (req->rq_release_snd_buf)
1037 req->rq_release_snd_buf(req); 1039 req->rq_release_snd_buf(req);