diff options
author | Ricardo Labiaga <ricardo.labiaga@netapp.com> | 2009-04-01 09:23:06 -0400 |
---|---|---|
committer | Benny Halevy <bhalevy@panasas.com> | 2009-06-17 17:11:28 -0400 |
commit | 1cad7ea6fe98dc414bd3df55275c147bd15ebf97 (patch) | |
tree | 1df4c7075e6a197bc95d69e6d1c95a8b8f4b8646 /net | |
parent | 0d90ba1cd416525c4825c111db862d8b15a02e9b (diff) |
nfs41: Refactor svc_process()
net/sunrpc/svc.c:svc_process() is used by the NFSv4 callback service
to process RPC requests arriving over connections initiated by the
server. NFSv4.1 supports callbacks over the backchannel on connections
initiated by the client. This patch refactors svc_process() so that
common code can also be used by the backchannel.
Signed-off-by: Ricardo Labiaga <ricardo.labiaga@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/svc.c | 80 |
1 files changed, 50 insertions, 30 deletions
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 8847add6ca16..bfda66db2f4f 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -970,20 +970,18 @@ svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) | |||
970 | } | 970 | } |
971 | 971 | ||
972 | /* | 972 | /* |
973 | * Process the RPC request. | 973 | * Common routine for processing the RPC request. |
974 | */ | 974 | */ |
975 | int | 975 | static int |
976 | svc_process(struct svc_rqst *rqstp) | 976 | svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) |
977 | { | 977 | { |
978 | struct svc_program *progp; | 978 | struct svc_program *progp; |
979 | struct svc_version *versp = NULL; /* compiler food */ | 979 | struct svc_version *versp = NULL; /* compiler food */ |
980 | struct svc_procedure *procp = NULL; | 980 | struct svc_procedure *procp = NULL; |
981 | struct kvec * argv = &rqstp->rq_arg.head[0]; | ||
982 | struct kvec * resv = &rqstp->rq_res.head[0]; | ||
983 | struct svc_serv *serv = rqstp->rq_server; | 981 | struct svc_serv *serv = rqstp->rq_server; |
984 | kxdrproc_t xdr; | 982 | kxdrproc_t xdr; |
985 | __be32 *statp; | 983 | __be32 *statp; |
986 | u32 dir, prog, vers, proc; | 984 | u32 prog, vers, proc; |
987 | __be32 auth_stat, rpc_stat; | 985 | __be32 auth_stat, rpc_stat; |
988 | int auth_res; | 986 | int auth_res; |
989 | __be32 *reply_statp; | 987 | __be32 *reply_statp; |
@@ -993,19 +991,6 @@ svc_process(struct svc_rqst *rqstp) | |||
993 | if (argv->iov_len < 6*4) | 991 | if (argv->iov_len < 6*4) |
994 | goto err_short_len; | 992 | goto err_short_len; |
995 | 993 | ||
996 | /* setup response xdr_buf. | ||
997 | * Initially it has just one page | ||
998 | */ | ||
999 | rqstp->rq_resused = 1; | ||
1000 | resv->iov_base = page_address(rqstp->rq_respages[0]); | ||
1001 | resv->iov_len = 0; | ||
1002 | rqstp->rq_res.pages = rqstp->rq_respages + 1; | ||
1003 | rqstp->rq_res.len = 0; | ||
1004 | rqstp->rq_res.page_base = 0; | ||
1005 | rqstp->rq_res.page_len = 0; | ||
1006 | rqstp->rq_res.buflen = PAGE_SIZE; | ||
1007 | rqstp->rq_res.tail[0].iov_base = NULL; | ||
1008 | rqstp->rq_res.tail[0].iov_len = 0; | ||
1009 | /* Will be turned off only in gss privacy case: */ | 994 | /* Will be turned off only in gss privacy case: */ |
1010 | rqstp->rq_splice_ok = 1; | 995 | rqstp->rq_splice_ok = 1; |
1011 | /* Will be turned off only when NFSv4 Sessions are used */ | 996 | /* Will be turned off only when NFSv4 Sessions are used */ |
@@ -1014,17 +999,13 @@ svc_process(struct svc_rqst *rqstp) | |||
1014 | /* Setup reply header */ | 999 | /* Setup reply header */ |
1015 | rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); | 1000 | rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); |
1016 | 1001 | ||
1017 | rqstp->rq_xid = svc_getu32(argv); | ||
1018 | svc_putu32(resv, rqstp->rq_xid); | 1002 | svc_putu32(resv, rqstp->rq_xid); |
1019 | 1003 | ||
1020 | dir = svc_getnl(argv); | ||
1021 | vers = svc_getnl(argv); | 1004 | vers = svc_getnl(argv); |
1022 | 1005 | ||
1023 | /* First words of reply: */ | 1006 | /* First words of reply: */ |
1024 | svc_putnl(resv, 1); /* REPLY */ | 1007 | svc_putnl(resv, 1); /* REPLY */ |
1025 | 1008 | ||
1026 | if (dir != 0) /* direction != CALL */ | ||
1027 | goto err_bad_dir; | ||
1028 | if (vers != 2) /* RPC version number */ | 1009 | if (vers != 2) /* RPC version number */ |
1029 | goto err_bad_rpc; | 1010 | goto err_bad_rpc; |
1030 | 1011 | ||
@@ -1147,7 +1128,7 @@ svc_process(struct svc_rqst *rqstp) | |||
1147 | sendit: | 1128 | sendit: |
1148 | if (svc_authorise(rqstp)) | 1129 | if (svc_authorise(rqstp)) |
1149 | goto dropit; | 1130 | goto dropit; |
1150 | return svc_send(rqstp); | 1131 | return 1; /* Caller can now send it */ |
1151 | 1132 | ||
1152 | dropit: | 1133 | dropit: |
1153 | svc_authorise(rqstp); /* doesn't hurt to call this twice */ | 1134 | svc_authorise(rqstp); /* doesn't hurt to call this twice */ |
@@ -1161,12 +1142,6 @@ err_short_len: | |||
1161 | 1142 | ||
1162 | goto dropit; /* drop request */ | 1143 | goto dropit; /* drop request */ |
1163 | 1144 | ||
1164 | err_bad_dir: | ||
1165 | svc_printk(rqstp, "bad direction %d, dropping request\n", dir); | ||
1166 | |||
1167 | serv->sv_stats->rpcbadfmt++; | ||
1168 | goto dropit; /* drop request */ | ||
1169 | |||
1170 | err_bad_rpc: | 1145 | err_bad_rpc: |
1171 | serv->sv_stats->rpcbadfmt++; | 1146 | serv->sv_stats->rpcbadfmt++; |
1172 | svc_putnl(resv, 1); /* REJECT */ | 1147 | svc_putnl(resv, 1); /* REJECT */ |
@@ -1220,6 +1195,51 @@ err_bad: | |||
1220 | EXPORT_SYMBOL_GPL(svc_process); | 1195 | EXPORT_SYMBOL_GPL(svc_process); |
1221 | 1196 | ||
1222 | /* | 1197 | /* |
1198 | * Process the RPC request. | ||
1199 | */ | ||
1200 | int | ||
1201 | svc_process(struct svc_rqst *rqstp) | ||
1202 | { | ||
1203 | struct kvec *argv = &rqstp->rq_arg.head[0]; | ||
1204 | struct kvec *resv = &rqstp->rq_res.head[0]; | ||
1205 | struct svc_serv *serv = rqstp->rq_server; | ||
1206 | u32 dir; | ||
1207 | int error; | ||
1208 | |||
1209 | /* | ||
1210 | * Setup response xdr_buf. | ||
1211 | * Initially it has just one page | ||
1212 | */ | ||
1213 | rqstp->rq_resused = 1; | ||
1214 | resv->iov_base = page_address(rqstp->rq_respages[0]); | ||
1215 | resv->iov_len = 0; | ||
1216 | rqstp->rq_res.pages = rqstp->rq_respages + 1; | ||
1217 | rqstp->rq_res.len = 0; | ||
1218 | rqstp->rq_res.page_base = 0; | ||
1219 | rqstp->rq_res.page_len = 0; | ||
1220 | rqstp->rq_res.buflen = PAGE_SIZE; | ||
1221 | rqstp->rq_res.tail[0].iov_base = NULL; | ||
1222 | rqstp->rq_res.tail[0].iov_len = 0; | ||
1223 | |||
1224 | rqstp->rq_xid = svc_getu32(argv); | ||
1225 | |||
1226 | dir = svc_getnl(argv); | ||
1227 | if (dir != 0) { | ||
1228 | /* direction != CALL */ | ||
1229 | svc_printk(rqstp, "bad direction %d, dropping request\n", dir); | ||
1230 | serv->sv_stats->rpcbadfmt++; | ||
1231 | svc_drop(rqstp); | ||
1232 | return 0; | ||
1233 | } | ||
1234 | |||
1235 | error = svc_process_common(rqstp, argv, resv); | ||
1236 | if (error <= 0) | ||
1237 | return error; | ||
1238 | |||
1239 | return svc_send(rqstp); | ||
1240 | } | ||
1241 | |||
1242 | /* | ||
1223 | * Return (transport-specific) limit on the rpc payload. | 1243 | * Return (transport-specific) limit on the rpc payload. |
1224 | */ | 1244 | */ |
1225 | u32 svc_max_payload(const struct svc_rqst *rqstp) | 1245 | u32 svc_max_payload(const struct svc_rqst *rqstp) |