diff options
| author | Jeff Layton <jlayton@redhat.com> | 2009-08-14 12:57:57 -0400 |
|---|---|---|
| committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-08-21 11:27:43 -0400 |
| commit | aa9a4ec7707a5391cde556f3fa1b0eb4bca3bcf6 (patch) | |
| tree | abb684bea62a77a0172d6be2f45f0414acedc5cc | |
| parent | 363168b4ea8ec26aeb982ac6024a09f907ecd27e (diff) | |
nfsd: convert nfs4_cb_conn struct to hold address in sockaddr_storage
...rather than as a separate address and port fields. This will be
necessary for implementing callbacks over IPv6. Also, convert
gen_callback to use the standard rpcuaddr2sockaddr routine rather than
its own private one.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Acked-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
| -rw-r--r-- | fs/nfsd/nfs4callback.c | 11 | ||||
| -rw-r--r-- | fs/nfsd/nfs4state.c | 81 | ||||
| -rw-r--r-- | include/linux/nfsd/state.h | 4 |
3 files changed, 13 insertions, 83 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 3fd23f7aceca..81d1c5285dcc 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
| @@ -377,7 +377,6 @@ static int max_cb_time(void) | |||
| 377 | 377 | ||
| 378 | int setup_callback_client(struct nfs4_client *clp) | 378 | int setup_callback_client(struct nfs4_client *clp) |
| 379 | { | 379 | { |
| 380 | struct sockaddr_in addr; | ||
| 381 | struct nfs4_cb_conn *cb = &clp->cl_cb_conn; | 380 | struct nfs4_cb_conn *cb = &clp->cl_cb_conn; |
| 382 | struct rpc_timeout timeparms = { | 381 | struct rpc_timeout timeparms = { |
| 383 | .to_initval = max_cb_time(), | 382 | .to_initval = max_cb_time(), |
| @@ -385,8 +384,8 @@ int setup_callback_client(struct nfs4_client *clp) | |||
| 385 | }; | 384 | }; |
| 386 | struct rpc_create_args args = { | 385 | struct rpc_create_args args = { |
| 387 | .protocol = IPPROTO_TCP, | 386 | .protocol = IPPROTO_TCP, |
| 388 | .address = (struct sockaddr *)&addr, | 387 | .address = (struct sockaddr *) &cb->cb_addr, |
| 389 | .addrsize = sizeof(addr), | 388 | .addrsize = cb->cb_addrlen, |
| 390 | .timeout = &timeparms, | 389 | .timeout = &timeparms, |
| 391 | .program = &cb_program, | 390 | .program = &cb_program, |
| 392 | .prognumber = cb->cb_prog, | 391 | .prognumber = cb->cb_prog, |
| @@ -400,12 +399,6 @@ int setup_callback_client(struct nfs4_client *clp) | |||
| 400 | if (!clp->cl_principal && (clp->cl_flavor >= RPC_AUTH_GSS_KRB5)) | 399 | if (!clp->cl_principal && (clp->cl_flavor >= RPC_AUTH_GSS_KRB5)) |
| 401 | return -EINVAL; | 400 | return -EINVAL; |
| 402 | 401 | ||
| 403 | /* Initialize address */ | ||
| 404 | memset(&addr, 0, sizeof(addr)); | ||
| 405 | addr.sin_family = AF_INET; | ||
| 406 | addr.sin_port = htons(cb->cb_port); | ||
| 407 | addr.sin_addr.s_addr = htonl(cb->cb_addr); | ||
| 408 | |||
| 409 | /* Create RPC client */ | 402 | /* Create RPC client */ |
| 410 | client = rpc_create(&args); | 403 | client = rpc_create(&args); |
| 411 | if (IS_ERR(client)) { | 404 | if (IS_ERR(client)) { |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index bfc14d879ea1..96a742308cee 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
| @@ -897,76 +897,6 @@ find_unconfirmed_client_by_str(const char *dname, unsigned int hashval, | |||
| 897 | return NULL; | 897 | return NULL; |
| 898 | } | 898 | } |
| 899 | 899 | ||
| 900 | /* a helper function for parse_callback */ | ||
| 901 | static int | ||
| 902 | parse_octet(unsigned int *lenp, char **addrp) | ||
| 903 | { | ||
| 904 | unsigned int len = *lenp; | ||
| 905 | char *p = *addrp; | ||
| 906 | int n = -1; | ||
| 907 | char c; | ||
| 908 | |||
| 909 | for (;;) { | ||
| 910 | if (!len) | ||
| 911 | break; | ||
| 912 | len--; | ||
| 913 | c = *p++; | ||
| 914 | if (c == '.') | ||
| 915 | break; | ||
| 916 | if ((c < '0') || (c > '9')) { | ||
| 917 | n = -1; | ||
| 918 | break; | ||
| 919 | } | ||
| 920 | if (n < 0) | ||
| 921 | n = 0; | ||
| 922 | n = (n * 10) + (c - '0'); | ||
| 923 | if (n > 255) { | ||
| 924 | n = -1; | ||
| 925 | break; | ||
| 926 | } | ||
| 927 | } | ||
| 928 | *lenp = len; | ||
| 929 | *addrp = p; | ||
| 930 | return n; | ||
| 931 | } | ||
| 932 | |||
| 933 | /* parse and set the setclientid ipv4 callback address */ | ||
| 934 | static int | ||
| 935 | parse_ipv4(unsigned int addr_len, char *addr_val, unsigned int *cbaddrp, unsigned short *cbportp) | ||
| 936 | { | ||
| 937 | int temp = 0; | ||
| 938 | u32 cbaddr = 0; | ||
| 939 | u16 cbport = 0; | ||
| 940 | u32 addrlen = addr_len; | ||
| 941 | char *addr = addr_val; | ||
| 942 | int i, shift; | ||
| 943 | |||
| 944 | /* ipaddress */ | ||
| 945 | shift = 24; | ||
| 946 | for(i = 4; i > 0 ; i--) { | ||
| 947 | if ((temp = parse_octet(&addrlen, &addr)) < 0) { | ||
| 948 | return 0; | ||
| 949 | } | ||
| 950 | cbaddr |= (temp << shift); | ||
| 951 | if (shift > 0) | ||
| 952 | shift -= 8; | ||
| 953 | } | ||
| 954 | *cbaddrp = cbaddr; | ||
| 955 | |||
| 956 | /* port */ | ||
| 957 | shift = 8; | ||
| 958 | for(i = 2; i > 0 ; i--) { | ||
| 959 | if ((temp = parse_octet(&addrlen, &addr)) < 0) { | ||
| 960 | return 0; | ||
| 961 | } | ||
| 962 | cbport |= (temp << shift); | ||
| 963 | if (shift > 0) | ||
| 964 | shift -= 8; | ||
| 965 | } | ||
| 966 | *cbportp = cbport; | ||
| 967 | return 1; | ||
| 968 | } | ||
| 969 | |||
| 970 | static void | 900 | static void |
| 971 | gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se) | 901 | gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se) |
| 972 | { | 902 | { |
| @@ -976,14 +906,21 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se) | |||
| 976 | if ((se->se_callback_netid_len != 3) || memcmp((char *)se->se_callback_netid_val, "tcp", 3)) | 906 | if ((se->se_callback_netid_len != 3) || memcmp((char *)se->se_callback_netid_val, "tcp", 3)) |
| 977 | goto out_err; | 907 | goto out_err; |
| 978 | 908 | ||
| 979 | if ( !(parse_ipv4(se->se_callback_addr_len, se->se_callback_addr_val, | 909 | cb->cb_addrlen = rpc_uaddr2sockaddr(se->se_callback_addr_val, |
| 980 | &cb->cb_addr, &cb->cb_port))) | 910 | se->se_callback_addr_len, |
| 911 | (struct sockaddr *) &cb->cb_addr, | ||
| 912 | sizeof(cb->cb_addr)); | ||
| 913 | |||
| 914 | if (!cb->cb_addrlen || cb->cb_addr.ss_family != AF_INET) | ||
| 981 | goto out_err; | 915 | goto out_err; |
| 916 | |||
| 982 | cb->cb_minorversion = 0; | 917 | cb->cb_minorversion = 0; |
| 983 | cb->cb_prog = se->se_callback_prog; | 918 | cb->cb_prog = se->se_callback_prog; |
| 984 | cb->cb_ident = se->se_callback_ident; | 919 | cb->cb_ident = se->se_callback_ident; |
| 985 | return; | 920 | return; |
| 986 | out_err: | 921 | out_err: |
| 922 | cb->cb_addr.ss_family = AF_UNSPEC; | ||
| 923 | cb->cb_addrlen = 0; | ||
| 987 | dprintk(KERN_INFO "NFSD: this client (clientid %08x/%08x) " | 924 | dprintk(KERN_INFO "NFSD: this client (clientid %08x/%08x) " |
| 988 | "will not receive delegations\n", | 925 | "will not receive delegations\n", |
| 989 | clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id); | 926 | clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id); |
diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h index 3510ddd4be49..fb0c404c7c5c 100644 --- a/include/linux/nfsd/state.h +++ b/include/linux/nfsd/state.h | |||
| @@ -81,8 +81,8 @@ struct nfs4_delegation { | |||
| 81 | /* client delegation callback info */ | 81 | /* client delegation callback info */ |
| 82 | struct nfs4_cb_conn { | 82 | struct nfs4_cb_conn { |
| 83 | /* SETCLIENTID info */ | 83 | /* SETCLIENTID info */ |
| 84 | u32 cb_addr; | 84 | struct sockaddr_storage cb_addr; |
| 85 | unsigned short cb_port; | 85 | size_t cb_addrlen; |
| 86 | u32 cb_prog; | 86 | u32 cb_prog; |
| 87 | u32 cb_minorversion; | 87 | u32 cb_minorversion; |
| 88 | u32 cb_ident; /* minorversion 0 only */ | 88 | u32 cb_ident; /* minorversion 0 only */ |
