diff options
| -rw-r--r-- | fs/nfsd/nfs4state.c | 89 |
1 files changed, 45 insertions, 44 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 76b7bcbb3f20..a2bd37e655cf 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
| @@ -759,27 +759,6 @@ expire_client(struct nfs4_client *clp) | |||
| 759 | put_nfs4_client(clp); | 759 | put_nfs4_client(clp); |
| 760 | } | 760 | } |
| 761 | 761 | ||
| 762 | static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir) | ||
| 763 | { | ||
| 764 | struct nfs4_client *clp; | ||
| 765 | |||
| 766 | clp = alloc_client(name); | ||
| 767 | if (clp == NULL) | ||
| 768 | return NULL; | ||
| 769 | memcpy(clp->cl_recdir, recdir, HEXDIR_LEN); | ||
| 770 | atomic_set(&clp->cl_count, 1); | ||
| 771 | atomic_set(&clp->cl_cb_conn.cb_set, 0); | ||
| 772 | INIT_LIST_HEAD(&clp->cl_idhash); | ||
| 773 | INIT_LIST_HEAD(&clp->cl_strhash); | ||
| 774 | INIT_LIST_HEAD(&clp->cl_openowners); | ||
| 775 | INIT_LIST_HEAD(&clp->cl_delegations); | ||
| 776 | INIT_LIST_HEAD(&clp->cl_sessions); | ||
| 777 | INIT_LIST_HEAD(&clp->cl_lru); | ||
| 778 | clear_bit(0, &clp->cl_cb_slot_busy); | ||
| 779 | rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table"); | ||
| 780 | return clp; | ||
| 781 | } | ||
| 782 | |||
| 783 | static void copy_verf(struct nfs4_client *target, nfs4_verifier *source) | 762 | static void copy_verf(struct nfs4_client *target, nfs4_verifier *source) |
| 784 | { | 763 | { |
| 785 | memcpy(target->cl_verifier.data, source->data, | 764 | memcpy(target->cl_verifier.data, source->data, |
| @@ -842,6 +821,46 @@ static void gen_confirm(struct nfs4_client *clp) | |||
| 842 | *p++ = i++; | 821 | *p++ = i++; |
| 843 | } | 822 | } |
| 844 | 823 | ||
| 824 | static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir, | ||
| 825 | struct svc_rqst *rqstp, nfs4_verifier *verf) | ||
| 826 | { | ||
| 827 | struct nfs4_client *clp; | ||
| 828 | struct sockaddr *sa = svc_addr(rqstp); | ||
| 829 | char *princ; | ||
| 830 | |||
| 831 | clp = alloc_client(name); | ||
| 832 | if (clp == NULL) | ||
| 833 | return NULL; | ||
| 834 | |||
| 835 | princ = svc_gss_principal(rqstp); | ||
| 836 | if (princ) { | ||
| 837 | clp->cl_principal = kstrdup(princ, GFP_KERNEL); | ||
| 838 | if (clp->cl_principal == NULL) { | ||
| 839 | free_client(clp); | ||
| 840 | return NULL; | ||
| 841 | } | ||
| 842 | } | ||
| 843 | |||
| 844 | memcpy(clp->cl_recdir, recdir, HEXDIR_LEN); | ||
| 845 | atomic_set(&clp->cl_count, 1); | ||
| 846 | atomic_set(&clp->cl_cb_conn.cb_set, 0); | ||
| 847 | INIT_LIST_HEAD(&clp->cl_idhash); | ||
| 848 | INIT_LIST_HEAD(&clp->cl_strhash); | ||
| 849 | INIT_LIST_HEAD(&clp->cl_openowners); | ||
| 850 | INIT_LIST_HEAD(&clp->cl_delegations); | ||
| 851 | INIT_LIST_HEAD(&clp->cl_sessions); | ||
| 852 | INIT_LIST_HEAD(&clp->cl_lru); | ||
| 853 | clear_bit(0, &clp->cl_cb_slot_busy); | ||
| 854 | rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table"); | ||
| 855 | copy_verf(clp, verf); | ||
| 856 | rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa); | ||
| 857 | clp->cl_flavor = rqstp->rq_flavor; | ||
| 858 | copy_cred(&clp->cl_cred, &rqstp->rq_cred); | ||
| 859 | gen_confirm(clp); | ||
| 860 | |||
| 861 | return clp; | ||
| 862 | } | ||
| 863 | |||
| 845 | static int check_name(struct xdr_netobj name) | 864 | static int check_name(struct xdr_netobj name) |
| 846 | { | 865 | { |
| 847 | if (name.len == 0) | 866 | if (name.len == 0) |
| @@ -1189,17 +1208,13 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, | |||
| 1189 | 1208 | ||
| 1190 | out_new: | 1209 | out_new: |
| 1191 | /* Normal case */ | 1210 | /* Normal case */ |
| 1192 | new = create_client(exid->clname, dname); | 1211 | new = create_client(exid->clname, dname, rqstp, &verf); |
| 1193 | if (new == NULL) { | 1212 | if (new == NULL) { |
| 1194 | status = nfserr_serverfault; | 1213 | status = nfserr_serverfault; |
| 1195 | goto out; | 1214 | goto out; |
| 1196 | } | 1215 | } |
| 1197 | 1216 | ||
| 1198 | copy_verf(new, &verf); | ||
| 1199 | copy_cred(&new->cl_cred, &rqstp->rq_cred); | ||
| 1200 | rpc_copy_addr((struct sockaddr *) &new->cl_addr, sa); | ||
| 1201 | gen_clid(new); | 1217 | gen_clid(new); |
| 1202 | gen_confirm(new); | ||
| 1203 | add_to_unconfirmed(new, strhashval); | 1218 | add_to_unconfirmed(new, strhashval); |
| 1204 | out_copy: | 1219 | out_copy: |
| 1205 | exid->clientid.cl_boot = new->cl_clientid.cl_boot; | 1220 | exid->clientid.cl_boot = new->cl_clientid.cl_boot; |
| @@ -1473,7 +1488,6 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
| 1473 | unsigned int strhashval; | 1488 | unsigned int strhashval; |
| 1474 | struct nfs4_client *conf, *unconf, *new; | 1489 | struct nfs4_client *conf, *unconf, *new; |
| 1475 | __be32 status; | 1490 | __be32 status; |
| 1476 | char *princ; | ||
| 1477 | char dname[HEXDIR_LEN]; | 1491 | char dname[HEXDIR_LEN]; |
| 1478 | 1492 | ||
| 1479 | if (!check_name(clname)) | 1493 | if (!check_name(clname)) |
| @@ -1518,7 +1532,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
| 1518 | */ | 1532 | */ |
| 1519 | if (unconf) | 1533 | if (unconf) |
| 1520 | expire_client(unconf); | 1534 | expire_client(unconf); |
| 1521 | new = create_client(clname, dname); | 1535 | new = create_client(clname, dname, rqstp, &clverifier); |
| 1522 | if (new == NULL) | 1536 | if (new == NULL) |
| 1523 | goto out; | 1537 | goto out; |
| 1524 | gen_clid(new); | 1538 | gen_clid(new); |
| @@ -1535,7 +1549,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
| 1535 | */ | 1549 | */ |
| 1536 | expire_client(unconf); | 1550 | expire_client(unconf); |
| 1537 | } | 1551 | } |
| 1538 | new = create_client(clname, dname); | 1552 | new = create_client(clname, dname, rqstp, &clverifier); |
| 1539 | if (new == NULL) | 1553 | if (new == NULL) |
| 1540 | goto out; | 1554 | goto out; |
| 1541 | copy_clid(new, conf); | 1555 | copy_clid(new, conf); |
| @@ -1545,7 +1559,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
| 1545 | * probable client reboot; state will be removed if | 1559 | * probable client reboot; state will be removed if |
| 1546 | * confirmed. | 1560 | * confirmed. |
| 1547 | */ | 1561 | */ |
| 1548 | new = create_client(clname, dname); | 1562 | new = create_client(clname, dname, rqstp, &clverifier); |
| 1549 | if (new == NULL) | 1563 | if (new == NULL) |
| 1550 | goto out; | 1564 | goto out; |
| 1551 | gen_clid(new); | 1565 | gen_clid(new); |
| @@ -1556,24 +1570,11 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
| 1556 | * confirmed. | 1570 | * confirmed. |
| 1557 | */ | 1571 | */ |
| 1558 | expire_client(unconf); | 1572 | expire_client(unconf); |
| 1559 | new = create_client(clname, dname); | 1573 | new = create_client(clname, dname, rqstp, &clverifier); |
| 1560 | if (new == NULL) | 1574 | if (new == NULL) |
| 1561 | goto out; | 1575 | goto out; |
| 1562 | gen_clid(new); | 1576 | gen_clid(new); |
| 1563 | } | 1577 | } |
| 1564 | copy_verf(new, &clverifier); | ||
| 1565 | rpc_copy_addr((struct sockaddr *) &new->cl_addr, sa); | ||
| 1566 | new->cl_flavor = rqstp->rq_flavor; | ||
| 1567 | princ = svc_gss_principal(rqstp); | ||
| 1568 | if (princ) { | ||
| 1569 | new->cl_principal = kstrdup(princ, GFP_KERNEL); | ||
| 1570 | if (new->cl_principal == NULL) { | ||
| 1571 | free_client(new); | ||
| 1572 | goto out; | ||
| 1573 | } | ||
| 1574 | } | ||
| 1575 | copy_cred(&new->cl_cred, &rqstp->rq_cred); | ||
| 1576 | gen_confirm(new); | ||
| 1577 | gen_callback(new, setclid, rpc_get_scope_id(sa)); | 1578 | gen_callback(new, setclid, rpc_get_scope_id(sa)); |
| 1578 | add_to_unconfirmed(new, strhashval); | 1579 | add_to_unconfirmed(new, strhashval); |
| 1579 | setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot; | 1580 | setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot; |
