Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+92 -96
+3 -4
fs/nfs/nfs2xdr.c
··· 233 233 static int 234 234 nfs_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 237 unsigned int replen; 238 238 u32 offset = (u32)args->offset; 239 239 u32 count = args->count; ··· 393 393 static int 394 394 nfs_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs_readdirargs *args) 395 395 { 396 - struct rpc_task *task = req->rq_task; 397 - struct rpc_auth *auth = task->tk_msg.rpc_cred->cr_auth; 396 + struct rpc_auth *auth = req->rq_cred->cr_auth; 398 397 unsigned int replen; 399 398 u32 count = args->count; 400 399 ··· 574 575 static int 575 576 nfs_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_readlinkargs *args) 576 577 { 577 - struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; 578 + struct rpc_auth *auth = req->rq_cred->cr_auth; 578 579 unsigned int replen; 579 580 580 581 p = xdr_encode_fhandle(p, args->fh);
+4 -4
fs/nfs/nfs3xdr.c
··· 330 330 static int 331 331 nfs3_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 334 unsigned int replen; 335 335 u32 count = args->count; 336 336 ··· 471 471 static int 472 472 nfs3_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 475 unsigned int replen; 476 476 u32 count = args->count; 477 477 ··· 675 675 nfs3_xdr_getaclargs(struct rpc_rqst *req, __be32 *p, 676 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 679 unsigned int replen; 680 680 681 681 p = xdr_encode_fhandle(p, args->fh); ··· 802 802 static int 803 803 nfs3_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 806 unsigned int replen; 807 807 808 808 p = xdr_encode_fhandle(p, args->fh);
+1 -1
fs/nfs/nfs4xdr.c
··· 758 758 struct compound_hdr *hdr) 759 759 { 760 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 763 /* initialize running count of expected bytes in reply. 764 764 * NOTE: the replied tag SHOULD be the same is the one sent,
-2
include/linux/sunrpc/auth.h
··· 135 135 struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int); 136 136 void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *); 137 137 struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int); 138 - int rpcauth_bindcred(struct rpc_task *, struct rpc_cred *, int); 139 138 struct rpc_cred * rpcauth_generic_bind_cred(struct rpc_task *, struct rpc_cred *, int); 140 139 void put_rpccred(struct rpc_cred *); 141 - void rpcauth_unbindcred(struct rpc_task *); 142 140 __be32 * rpcauth_marshcred(struct rpc_task *, __be32 *); 143 141 __be32 * rpcauth_checkverf(struct rpc_task *, __be32 *); 144 142 int rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, __be32 *data, void *obj);
+1
include/linux/sunrpc/xprt.h
··· 64 64 * This is the private part 65 65 */ 66 66 struct rpc_task * rq_task; /* RPC task data */ 67 + struct rpc_cred * rq_cred; /* Bound cred */ 67 68 __be32 rq_xid; /* request XID */ 68 69 int rq_cong; /* has incremented xprt->cong */ 69 70 u32 rq_seqno; /* gss seq no. used on req. */
+20 -23
net/sunrpc/auth.c
··· 477 477 return rpcauth_lookupcred(auth, lookupflags); 478 478 } 479 479 480 - int 480 + static int 481 481 rpcauth_bindcred(struct rpc_task *task, struct rpc_cred *cred, int flags) 482 482 { 483 + struct rpc_rqst *req = task->tk_rqstp; 483 484 struct rpc_cred *new; 484 485 int lookupflags = 0; 485 486 ··· 494 493 new = rpcauth_bind_new_cred(task, lookupflags); 495 494 if (IS_ERR(new)) 496 495 return PTR_ERR(new); 497 - if (task->tk_msg.rpc_cred != NULL) 498 - put_rpccred(task->tk_msg.rpc_cred); 499 - task->tk_msg.rpc_cred = new; 496 + if (req->rq_cred != NULL) 497 + put_rpccred(req->rq_cred); 498 + req->rq_cred = new; 500 499 return 0; 501 500 } 502 501 ··· 536 535 } 537 536 EXPORT_SYMBOL_GPL(put_rpccred); 538 537 539 - void 540 - rpcauth_unbindcred(struct rpc_task *task) 541 - { 542 - struct rpc_cred *cred = task->tk_msg.rpc_cred; 543 - 544 - dprintk("RPC: %5u releasing %s cred %p\n", 545 - task->tk_pid, cred->cr_auth->au_ops->au_name, cred); 546 - 547 - put_rpccred(cred); 548 - task->tk_msg.rpc_cred = NULL; 549 - } 550 - 551 538 __be32 * 552 539 rpcauth_marshcred(struct rpc_task *task, __be32 *p) 553 540 { 554 - struct rpc_cred *cred = task->tk_msg.rpc_cred; 541 + struct rpc_cred *cred = task->tk_rqstp->rq_cred; 555 542 556 543 dprintk("RPC: %5u marshaling %s cred %p\n", 557 544 task->tk_pid, cred->cr_auth->au_ops->au_name, cred); ··· 550 561 __be32 * 551 562 rpcauth_checkverf(struct rpc_task *task, __be32 *p) 552 563 { 553 - struct rpc_cred *cred = task->tk_msg.rpc_cred; 564 + struct rpc_cred *cred = task->tk_rqstp->rq_cred; 554 565 555 566 dprintk("RPC: %5u validating %s cred %p\n", 556 567 task->tk_pid, cred->cr_auth->au_ops->au_name, cred); ··· 562 573 rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, 563 574 __be32 *data, void *obj) 564 575 { 565 - struct rpc_cred *cred = task->tk_msg.rpc_cred; 576 + struct rpc_cred *cred = task->tk_rqstp->rq_cred; 566 577 567 578 dprintk("RPC: %5u using %s cred %p to wrap rpc data\n", 568 579 task->tk_pid, cred->cr_ops->cr_name, cred); ··· 576 587 rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, 577 588 __be32 *data, void *obj) 578 589 { 579 - struct rpc_cred *cred = task->tk_msg.rpc_cred; 590 + struct rpc_cred *cred = task->tk_rqstp->rq_cred; 580 591 581 592 dprintk("RPC: %5u using %s cred %p to unwrap rpc data\n", 582 593 task->tk_pid, cred->cr_ops->cr_name, cred); ··· 590 601 int 591 602 rpcauth_refreshcred(struct rpc_task *task) 592 603 { 593 - struct rpc_cred *cred = task->tk_msg.rpc_cred; 604 + struct rpc_cred *cred = task->tk_rqstp->rq_cred; 594 605 int err; 595 606 607 + cred = task->tk_rqstp->rq_cred; 608 + if (cred == NULL) { 609 + err = rpcauth_bindcred(task, task->tk_msg.rpc_cred, task->tk_flags); 610 + if (err < 0) 611 + goto out; 612 + cred = task->tk_rqstp->rq_cred; 613 + }; 596 614 dprintk("RPC: %5u refreshing %s cred %p\n", 597 615 task->tk_pid, cred->cr_auth->au_ops->au_name, cred); 598 616 599 617 err = cred->cr_ops->crrefresh(task); 618 + out: 600 619 if (err < 0) 601 620 task->tk_status = err; 602 621 return err; ··· 613 616 void 614 617 rpcauth_invalcred(struct rpc_task *task) 615 618 { 616 - struct rpc_cred *cred = task->tk_msg.rpc_cred; 619 + struct rpc_cred *cred = task->tk_rqstp->rq_cred; 617 620 618 621 dprintk("RPC: %5u invalidating %s cred %p\n", 619 622 task->tk_pid, cred->cr_auth->au_ops->au_name, cred); ··· 624 627 int 625 628 rpcauth_uptodatecred(struct rpc_task *task) 626 629 { 627 - struct rpc_cred *cred = task->tk_msg.rpc_cred; 630 + struct rpc_cred *cred = task->tk_rqstp->rq_cred; 628 631 629 632 return cred == NULL || 630 633 test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0;
+11 -11
net/sunrpc/auth_gss/auth_gss.c
··· 373 373 static void 374 374 gss_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 377 struct gss_cred, gc_base); 378 378 struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall; 379 379 struct inode *inode = &gss_msg->inode->vfs_inode; ··· 502 502 static inline int 503 503 gss_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 506 struct gss_auth *gss_auth = container_of(cred->cr_auth, 507 507 struct gss_auth, rpc_auth); 508 508 struct gss_cred *gss_cred = container_of(cred, ··· 1064 1064 static __be32 * 1065 1065 gss_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 1069 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, 1069 1070 gc_base); 1070 1071 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred); 1071 1072 __be32 *cred_len; 1072 - struct rpc_rqst *req = task->tk_rqstp; 1073 1073 u32 maj_stat = 0; 1074 1074 struct xdr_netobj mic; 1075 1075 struct kvec iov; ··· 1119 1119 1120 1120 static 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 1123 struct gss_cred *gss_cred = container_of(oldcred, 1124 1124 struct gss_cred, 1125 1125 gc_base); ··· 1133 1133 new = gss_lookup_cred(auth, &acred, RPCAUTH_LOOKUP_NEW); 1134 1134 if (IS_ERR(new)) 1135 1135 return PTR_ERR(new); 1136 - task->tk_msg.rpc_cred = new; 1136 + task->tk_rqstp->rq_cred = new; 1137 1137 put_rpccred(oldcred); 1138 1138 return 0; 1139 1139 } ··· 1161 1161 static int 1162 1162 gss_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 1165 int ret = 0; 1166 1166 1167 1167 if (gss_cred_is_negative_entry(cred)) ··· 1172 1172 ret = gss_renew_cred(task); 1173 1173 if (ret < 0) 1174 1174 goto out; 1175 - cred = task->tk_msg.rpc_cred; 1175 + cred = task->tk_rqstp->rq_cred; 1176 1176 } 1177 1177 1178 1178 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags)) ··· 1191 1191 static __be32 * 1192 1192 gss_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 1195 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred); 1196 1196 __be32 seq; 1197 1197 struct kvec iov; ··· 1400 1400 gss_wrap_req(struct rpc_task *task, 1401 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 1404 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, 1405 1405 gc_base); 1406 1406 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred); ··· 1503 1503 gss_unwrap_resp(struct rpc_task *task, 1504 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 1507 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, 1508 1508 gc_base); 1509 1509 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
+1 -1
net/sunrpc/auth_null.c
··· 75 75 static int 76 76 nul_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 79 return 0; 80 80 } 81 81
+3 -3
net/sunrpc/auth_unix.c
··· 140 140 unx_marshal(struct rpc_task *task, __be32 *p) 141 141 { 142 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 144 __be32 *base, *hold; 145 145 int i; 146 146 ··· 173 173 static int 174 174 unx_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 177 return 0; 178 178 } 179 179 ··· 196 196 printk("RPC: giant verf size: %u\n", size); 197 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 200 p += (size >> 2); 201 201 202 202 return p;
+45 -46
net/sunrpc/clnt.c
··· 605 605 task->tk_msg.rpc_proc = msg->rpc_proc; 606 606 task->tk_msg.rpc_argp = msg->rpc_argp; 607 607 task->tk_msg.rpc_resp = msg->rpc_resp; 608 - /* Bind the user cred */ 609 - task->tk_status = rpcauth_bindcred(task, msg->rpc_cred, task->tk_flags); 608 + if (msg->rpc_cred != NULL) 609 + task->tk_msg.rpc_cred = get_rpccred(msg->rpc_cred); 610 610 } 611 611 } 612 612 ··· 909 909 { 910 910 dprint_status(task); 911 911 912 - if (!rpcauth_uptodatecred(task)) { 913 - task->tk_action = call_refresh; 914 - return; 915 - } 916 - 917 912 task->tk_status = 0; 918 913 task->tk_action = call_reserveresult; 919 914 xprt_reserve(task); ··· 972 977 static void 973 978 call_allocate(struct rpc_task *task) 974 979 { 975 - unsigned int slack = task->tk_msg.rpc_cred->cr_auth->au_cslack; 980 + unsigned int slack = task->tk_client->cl_auth->au_cslack; 976 981 struct rpc_rqst *req = task->tk_rqstp; 977 982 struct rpc_xprt *xprt = task->tk_xprt; 978 983 struct rpc_procinfo *proc = task->tk_msg.rpc_proc; ··· 980 985 dprint_status(task); 981 986 982 987 task->tk_status = 0; 983 - task->tk_action = call_bind; 988 + task->tk_action = call_refresh; 984 989 985 990 if (req->rq_buffer) 986 991 return; ··· 1015 1020 } 1016 1021 1017 1022 rpc_exit(task, -ERESTARTSYS); 1023 + } 1024 + 1025 + /* 1026 + * 2a. Bind and/or refresh the credentials 1027 + */ 1028 + static void 1029 + call_refresh(struct rpc_task *task) 1030 + { 1031 + dprint_status(task); 1032 + 1033 + task->tk_action = call_refreshresult; 1034 + task->tk_status = 0; 1035 + task->tk_client->cl_stats->rpcauthrefresh++; 1036 + rpcauth_refreshcred(task); 1037 + } 1038 + 1039 + /* 1040 + * 2b. Process the results of a credential refresh 1041 + */ 1042 + static void 1043 + call_refreshresult(struct rpc_task *task) 1044 + { 1045 + int status = task->tk_status; 1046 + 1047 + dprint_status(task); 1048 + 1049 + task->tk_status = 0; 1050 + task->tk_action = call_bind; 1051 + if (status >= 0 && rpcauth_uptodatecred(task)) 1052 + return; 1053 + switch (status) { 1054 + case -EACCES: 1055 + rpc_exit(task, -EACCES); 1056 + return; 1057 + case -ENOMEM: 1058 + rpc_exit(task, -ENOMEM); 1059 + return; 1060 + case -ETIMEDOUT: 1061 + rpc_delay(task, 3*HZ); 1062 + } 1063 + task->tk_action = call_refresh; 1018 1064 } 1019 1065 1020 1066 static inline int ··· 1591 1555 xprt_conditional_disconnect(task->tk_xprt, 1592 1556 req->rq_connect_cookie); 1593 1557 } 1594 - } 1595 - 1596 - /* 1597 - * 8. Refresh the credentials if rejected by the server 1598 - */ 1599 - static void 1600 - call_refresh(struct rpc_task *task) 1601 - { 1602 - dprint_status(task); 1603 - 1604 - task->tk_action = call_refreshresult; 1605 - task->tk_status = 0; 1606 - task->tk_client->cl_stats->rpcauthrefresh++; 1607 - rpcauth_refreshcred(task); 1608 - } 1609 - 1610 - /* 1611 - * 8a. Process the results of a credential refresh 1612 - */ 1613 - static void 1614 - call_refreshresult(struct rpc_task *task) 1615 - { 1616 - int status = task->tk_status; 1617 - 1618 - dprint_status(task); 1619 - 1620 - task->tk_status = 0; 1621 - task->tk_action = call_reserve; 1622 - if (status >= 0 && rpcauth_uptodatecred(task)) 1623 - return; 1624 - if (status == -EACCES) { 1625 - rpc_exit(task, -EACCES); 1626 - return; 1627 - } 1628 - task->tk_action = call_refresh; 1629 - if (status != -ETIMEDOUT) 1630 - rpc_delay(task, 3*HZ); 1631 1558 } 1632 1559 1633 1560 static __be32 *
+1 -1
net/sunrpc/sched.c
··· 864 864 if (task->tk_rqstp) 865 865 xprt_release(task); 866 866 if (task->tk_msg.rpc_cred) 867 - rpcauth_unbindcred(task); 867 + put_rpccred(task->tk_msg.rpc_cred); 868 868 rpc_task_release_client(task); 869 869 if (task->tk_workqueue != NULL) { 870 870 INIT_WORK(&task->u.tk_work, rpc_async_release);
+2
net/sunrpc/xprt.c
··· 1032 1032 spin_unlock_bh(&xprt->transport_lock); 1033 1033 if (req->rq_buffer) 1034 1034 xprt->ops->buf_free(req->rq_buffer); 1035 + if (req->rq_cred != NULL) 1036 + put_rpccred(req->rq_cred); 1035 1037 task->tk_rqstp = NULL; 1036 1038 if (req->rq_release_snd_buf) 1037 1039 req->rq_release_snd_buf(req);