1
2
3
4
5
6
7
8
9
10#ifndef SUNRPC_SVC_H
11#define SUNRPC_SVC_H
12
13#include <linux/in.h>
14#include <linux/in6.h>
15#include <linux/sunrpc/types.h>
16#include <linux/sunrpc/xdr.h>
17#include <linux/sunrpc/auth.h>
18#include <linux/sunrpc/svcauth.h>
19#include <linux/wait.h>
20#include <linux/mm.h>
21
22
23
24
25typedef int (*svc_thread_fn)(void *);
26
27
28struct svc_pool_stats {
29 unsigned long packets;
30 unsigned long sockets_queued;
31 unsigned long threads_woken;
32 unsigned long overloads_avoided;
33 unsigned long threads_timedout;
34};
35
36
37
38
39
40
41
42
43
44
45
46struct svc_pool {
47 unsigned int sp_id;
48 spinlock_t sp_lock;
49 struct list_head sp_threads;
50 struct list_head sp_sockets;
51 unsigned int sp_nrthreads;
52 struct list_head sp_all_threads;
53 int sp_nwaking;
54 struct svc_pool_stats sp_stats;
55} ____cacheline_aligned_in_smp;
56
57
58
59
60
61
62
63
64
65
66
67struct svc_serv {
68 struct svc_program * sv_program;
69 struct svc_stat * sv_stats;
70 spinlock_t sv_lock;
71 unsigned int sv_nrthreads;
72 unsigned int sv_maxconn;
73
74
75
76 unsigned int sv_max_payload;
77 unsigned int sv_max_mesg;
78 unsigned int sv_xdrsize;
79 struct list_head sv_permsocks;
80 struct list_head sv_tempsocks;
81 int sv_tmpcnt;
82 struct timer_list sv_temptimer;
83
84 char * sv_name;
85
86 unsigned int sv_nrpools;
87 struct svc_pool * sv_pools;
88
89 void (*sv_shutdown)(struct svc_serv *serv);
90
91
92
93
94 struct module * sv_module;
95
96 svc_thread_fn sv_function;
97#if defined(CONFIG_NFS_V4_1)
98 struct list_head sv_cb_list;
99
100
101 spinlock_t sv_cb_lock;
102 wait_queue_head_t sv_cb_waitq;
103
104 struct svc_xprt *bc_xprt;
105#endif
106};
107
108
109
110
111
112
113
114static inline void svc_get(struct svc_serv *serv)
115{
116 serv->sv_nrthreads++;
117}
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140#define RPCSVC_MAXPAYLOAD (1*1024*1024u)
141#define RPCSVC_MAXPAYLOAD_TCP RPCSVC_MAXPAYLOAD
142#define RPCSVC_MAXPAYLOAD_UDP (32*1024u)
143
144extern u32 svc_max_payload(const struct svc_rqst *rqstp);
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE \
174 + 2 + 1)
175
176static inline u32 svc_getnl(struct kvec *iov)
177{
178 __be32 val, *vp;
179 vp = iov->iov_base;
180 val = *vp++;
181 iov->iov_base = (void*)vp;
182 iov->iov_len -= sizeof(__be32);
183 return ntohl(val);
184}
185
186static inline void svc_putnl(struct kvec *iov, u32 val)
187{
188 __be32 *vp = iov->iov_base + iov->iov_len;
189 *vp = htonl(val);
190 iov->iov_len += sizeof(__be32);
191}
192
193static inline __be32 svc_getu32(struct kvec *iov)
194{
195 __be32 val, *vp;
196 vp = iov->iov_base;
197 val = *vp++;
198 iov->iov_base = (void*)vp;
199 iov->iov_len -= sizeof(__be32);
200 return val;
201}
202
203static inline void svc_ungetu32(struct kvec *iov)
204{
205 __be32 *vp = (__be32 *)iov->iov_base;
206 iov->iov_base = (void *)(vp - 1);
207 iov->iov_len += sizeof(*vp);
208}
209
210static inline void svc_putu32(struct kvec *iov, __be32 val)
211{
212 __be32 *vp = iov->iov_base + iov->iov_len;
213 *vp = val;
214 iov->iov_len += sizeof(__be32);
215}
216
217union svc_addr_u {
218 struct in_addr addr;
219 struct in6_addr addr6;
220};
221
222
223
224
225
226struct svc_rqst {
227 struct list_head rq_list;
228 struct list_head rq_all;
229 struct svc_xprt * rq_xprt;
230 struct sockaddr_storage rq_addr;
231 size_t rq_addrlen;
232
233 struct svc_serv * rq_server;
234 struct svc_pool * rq_pool;
235 struct svc_procedure * rq_procinfo;
236 struct auth_ops * rq_authop;
237 u32 rq_flavor;
238 struct svc_cred rq_cred;
239 void * rq_xprt_ctxt;
240 struct svc_deferred_req*rq_deferred;
241 int rq_usedeferral;
242
243 size_t rq_xprt_hlen;
244 struct xdr_buf rq_arg;
245 struct xdr_buf rq_res;
246 struct page * rq_pages[RPCSVC_MAXPAGES];
247 struct page * *rq_respages;
248 int rq_resused;
249
250 struct kvec rq_vec[RPCSVC_MAXPAGES];
251
252 __be32 rq_xid;
253 u32 rq_prog;
254 u32 rq_vers;
255 u32 rq_proc;
256 u32 rq_prot;
257 unsigned short
258 rq_secure : 1;
259
260 union svc_addr_u rq_daddr;
261
262
263 void * rq_argp;
264 void * rq_resp;
265 void * rq_auth_data;
266
267 int rq_reserved;
268
269
270
271 struct cache_req rq_chandle;
272
273
274
275 struct auth_domain * rq_client;
276 struct auth_domain * rq_gssclient;
277 struct svc_cacherep * rq_cacherep;
278 struct knfsd_fh * rq_reffh;
279
280
281
282 int rq_splice_ok;
283
284
285 wait_queue_head_t rq_wait;
286 struct task_struct *rq_task;
287 int rq_waking;
288};
289
290
291
292
293static inline struct sockaddr_in *svc_addr_in(const struct svc_rqst *rqst)
294{
295 return (struct sockaddr_in *) &rqst->rq_addr;
296}
297
298static inline struct sockaddr_in6 *svc_addr_in6(const struct svc_rqst *rqst)
299{
300 return (struct sockaddr_in6 *) &rqst->rq_addr;
301}
302
303static inline struct sockaddr *svc_addr(const struct svc_rqst *rqst)
304{
305 return (struct sockaddr *) &rqst->rq_addr;
306}
307
308
309
310
311static inline int
312xdr_argsize_check(struct svc_rqst *rqstp, __be32 *p)
313{
314 char *cp = (char *)p;
315 struct kvec *vec = &rqstp->rq_arg.head[0];
316 return cp >= (char*)vec->iov_base
317 && cp <= (char*)vec->iov_base + vec->iov_len;
318}
319
320static inline int
321xdr_ressize_check(struct svc_rqst *rqstp, __be32 *p)
322{
323 struct kvec *vec = &rqstp->rq_res.head[0];
324 char *cp = (char*)p;
325
326 vec->iov_len = cp - (char*)vec->iov_base;
327
328 return vec->iov_len <= PAGE_SIZE;
329}
330
331static inline void svc_free_res_pages(struct svc_rqst *rqstp)
332{
333 while (rqstp->rq_resused) {
334 struct page **pp = (rqstp->rq_respages +
335 --rqstp->rq_resused);
336 if (*pp) {
337 put_page(*pp);
338 *pp = NULL;
339 }
340 }
341}
342
343struct svc_deferred_req {
344 u32 prot;
345 struct svc_xprt *xprt;
346 struct sockaddr_storage addr;
347 size_t addrlen;
348 union svc_addr_u daddr;
349 struct cache_deferred_req handle;
350 size_t xprt_hlen;
351 int argslen;
352 __be32 args[0];
353};
354
355
356
357
358struct svc_program {
359 struct svc_program * pg_next;
360 u32 pg_prog;
361 unsigned int pg_lovers;
362 unsigned int pg_hivers;
363 unsigned int pg_nvers;
364 struct svc_version ** pg_vers;
365 char * pg_name;
366 char * pg_class;
367 struct svc_stat * pg_stats;
368 int (*pg_authenticate)(struct svc_rqst *);
369};
370
371
372
373
374struct svc_version {
375 u32 vs_vers;
376 u32 vs_nproc;
377 struct svc_procedure * vs_proc;
378 u32 vs_xdrsize;
379
380 unsigned int vs_hidden : 1;
381
382
383
384
385
386
387 int (*vs_dispatch)(struct svc_rqst *, __be32 *);
388};
389
390
391
392
393typedef __be32 (*svc_procfunc)(struct svc_rqst *, void *argp, void *resp);
394struct svc_procedure {
395 svc_procfunc pc_func;
396 kxdrproc_t pc_decode;
397 kxdrproc_t pc_encode;
398 kxdrproc_t pc_release;
399 unsigned int pc_argsize;
400 unsigned int pc_ressize;
401 unsigned int pc_count;
402 unsigned int pc_cachetype;
403 unsigned int pc_xdrressize;
404};
405
406
407
408
409struct svc_serv *svc_create(struct svc_program *, unsigned int,
410 void (*shutdown)(struct svc_serv *));
411struct svc_rqst *svc_prepare_thread(struct svc_serv *serv,
412 struct svc_pool *pool);
413void svc_exit_thread(struct svc_rqst *);
414struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int,
415 void (*shutdown)(struct svc_serv *),
416 svc_thread_fn, struct module *);
417int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
418int svc_pool_stats_open(struct svc_serv *serv, struct file *file);
419void svc_destroy(struct svc_serv *);
420int svc_process(struct svc_rqst *);
421int bc_svc_process(struct svc_serv *, struct rpc_rqst *,
422 struct svc_rqst *);
423int svc_register(const struct svc_serv *, const int,
424 const unsigned short, const unsigned short);
425
426void svc_wake_up(struct svc_serv *);
427void svc_reserve(struct svc_rqst *rqstp, int space);
428struct svc_pool * svc_pool_for_cpu(struct svc_serv *serv, int cpu);
429char * svc_print_addr(struct svc_rqst *, char *, size_t);
430
431#define RPC_MAX_ADDRBUFLEN (63U)
432
433
434
435
436
437
438
439
440static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space)
441{
442 int added_space = 0;
443
444 if (rqstp->rq_authop->flavour)
445 added_space = RPC_MAX_AUTH_SIZE;
446 svc_reserve(rqstp, space + added_space);
447}
448
449#endif
450