source: svn/trunk/newcon3bcm2_21bu/toolchain/mipsel-linux-uclibc/include/linux/sunrpc/svc.h

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 9.0 KB
Line 
1/*
2 * linux/include/linux/sunrpc/svc.h
3 *
4 * RPC server declarations.
5 *
6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
7 */
8
9
10#ifndef SUNRPC_SVC_H
11#define SUNRPC_SVC_H
12
13#include <asm/types.h>
14
15#include <linux/in.h>
16#include <linux/sunrpc/types.h>
17#include <linux/wait.h>
18
19/*
20 * RPC service.
21 *
22 * An RPC service is a ``daemon,'' possibly multithreaded, which
23 * receives and processes incoming RPC messages.
24 * It has one or more transport sockets associated with it, and maintains
25 * a list of idle threads waiting for input.
26 *
27 * We currently do not support more than one RPC program per daemon.
28 */
29struct svc_serv {
30        struct list_head        sv_threads;     /* idle server threads */
31        struct list_head        sv_sockets;     /* pending sockets */
32        struct svc_program *    sv_program;     /* RPC program */
33        struct svc_stat *       sv_stats;       /* RPC statistics */
34        spinlock_t              sv_lock;
35        unsigned int            sv_nrthreads;   /* # of server threads */
36        unsigned int            sv_bufsz;       /* datagram buffer size */
37        unsigned int            sv_xdrsize;     /* XDR buffer size */
38
39        struct list_head        sv_permsocks;   /* all permanent sockets */
40        struct list_head        sv_tempsocks;   /* all temporary sockets */
41        int                     sv_tmpcnt;      /* count of temporary sockets */
42
43        char *                  sv_name;        /* service name */
44};
45
46/*
47 * Maximum payload size supported by a kernel RPC server.
48 * This is use to determine the max number of pages nfsd is
49 * willing to return in a single READ operation.
50 */
51#define RPCSVC_MAXPAYLOAD       (64*1024u)
52
53/*
54 * RPC Requsts and replies are stored in one or more pages.
55 * We maintain an array of pages for each server thread.
56 * Requests are copied into these pages as they arrive.  Remaining
57 * pages are available to write the reply into.
58 *
59 * Pages are sent using ->sendpage so each server thread needs to
60 * allocate more to replace those used in sending.  To help keep track
61 * of these pages we have a receive list where all pages initialy live,
62 * and a send list where pages are moved to when there are to be part
63 * of a reply.
64 *
65 * We use xdr_buf for holding responses as it fits well with NFS
66 * read responses (that have a header, and some data pages, and possibly
67 * a tail) and means we can share some client side routines.
68 *
69 * The xdr_buf.head kvec always points to the first page in the rq_*pages
70 * list.  The xdr_buf.pages pointer points to the second page on that
71 * list.  xdr_buf.tail points to the end of the first page.
72 * This assumes that the non-page part of an rpc reply will fit
73 * in a page - NFSd ensures this.  lockd also has no trouble.
74 *
75 * Each request/reply pair can have at most one "payload", plus two pages,
76 * one for the request, and one for the reply.
77 */
78#define RPCSVC_MAXPAGES         ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE + 2)
79
80static inline __u32 svc_getu32(struct kvec *iov)
81{
82        __u32 val, *vp;
83        vp = iov->iov_base;
84        val = *vp++;
85        iov->iov_base = (void*)vp;
86        iov->iov_len -= sizeof(__u32);
87        return val;
88}
89
90static inline void svc_ungetu32(struct kvec *iov)
91{
92        __u32 *vp = (__u32 *)iov->iov_base;
93        iov->iov_base = (void *)(vp - 1);
94        iov->iov_len += sizeof(*vp);
95}
96
97static inline void svc_putu32(struct kvec *iov, __u32 val)
98{
99        __u32 *vp = iov->iov_base + iov->iov_len;
100        *vp = val;
101        iov->iov_len += sizeof(__u32);
102}
103
104       
105/*
106 * The context of a single thread, including the request currently being
107 * processed.
108 * NOTE: First two items must be prev/next.
109 */
110struct svc_rqst {
111        struct list_head        rq_list;        /* idle list */
112        struct svc_sock *       rq_sock;        /* socket */
113        struct sockaddr_in      rq_addr;        /* peer address */
114        int                     rq_addrlen;
115
116        struct svc_serv *       rq_server;      /* RPC service definition */
117        struct svc_procedure *  rq_procinfo;    /* procedure info */
118        struct auth_ops *       rq_authop;      /* authentication flavour */
119        struct svc_cred         rq_cred;        /* auth info */
120        struct sk_buff *        rq_skbuff;      /* fast recv inet buffer */
121        struct svc_deferred_req*rq_deferred;    /* deferred request we are replaying */
122
123        struct xdr_buf          rq_arg;
124        struct xdr_buf          rq_res;
125        struct page *           rq_argpages[RPCSVC_MAXPAGES];
126        struct page *           rq_respages[RPCSVC_MAXPAGES];
127        int                     rq_restailpage;
128        short                   rq_argused;     /* pages used for argument */
129        short                   rq_arghi;       /* pages available in argument page list */
130        short                   rq_resused;     /* pages used for result */
131
132        __u32                   rq_xid;         /* transmission id */
133        __u32                   rq_prog;        /* program number */
134        __u32                   rq_vers;        /* program version */
135        __u32                   rq_proc;        /* procedure number */
136        __u32                   rq_prot;        /* IP protocol */
137        unsigned short
138                                rq_secure  : 1; /* secure port */
139
140
141        __u32                   rq_daddr;       /* dest addr of request - reply from here */
142
143        void *                  rq_argp;        /* decoded arguments */
144        void *                  rq_resp;        /* xdr'd results */
145        void *                  rq_auth_data;   /* flavor-specific data */
146
147        int                     rq_reserved;    /* space on socket outq
148                                                 * reserved for this request
149                                                 */
150
151        struct cache_req        rq_chandle;     /* handle passed to caches for
152                                                 * request delaying
153                                                 */
154        /* Catering to nfsd */
155        struct auth_domain *    rq_client;      /* RPC peer info */
156        struct svc_cacherep *   rq_cacherep;    /* cache info */
157        struct knfsd_fh *       rq_reffh;       /* Referrence filehandle, used to
158                                                 * determine what device number
159                                                 * to report (real or virtual)
160                                                 */
161
162        wait_queue_head_t       rq_wait;        /* synchronization */
163};
164
165/*
166 * Check buffer bounds after decoding arguments
167 */
168static inline int
169xdr_argsize_check(struct svc_rqst *rqstp, __u32 *p)
170{
171        char *cp = (char *)p;
172        struct kvec *vec = &rqstp->rq_arg.head[0];
173        return cp - (char*)vec->iov_base <= vec->iov_len;
174}
175
176static inline int
177xdr_ressize_check(struct svc_rqst *rqstp, __u32 *p)
178{
179        struct kvec *vec = &rqstp->rq_res.head[0];
180        char *cp = (char*)p;
181
182        vec->iov_len = cp - (char*)vec->iov_base;
183
184        return vec->iov_len <= PAGE_SIZE;
185}
186
187static inline int svc_take_page(struct svc_rqst *rqstp)
188{
189        if (rqstp->rq_arghi <= rqstp->rq_argused)
190                return -ENOMEM;
191        rqstp->rq_arghi--;
192        rqstp->rq_respages[rqstp->rq_resused] =
193                rqstp->rq_argpages[rqstp->rq_arghi];
194        rqstp->rq_resused++;
195        return 0;
196}
197
198static inline void svc_pushback_allpages(struct svc_rqst *rqstp)
199{
200        while (rqstp->rq_resused) {
201                if (rqstp->rq_respages[--rqstp->rq_resused] == NULL)
202                        continue;
203                rqstp->rq_argpages[rqstp->rq_arghi++] =
204                        rqstp->rq_respages[rqstp->rq_resused];
205                rqstp->rq_respages[rqstp->rq_resused] = NULL;
206        }
207}
208
209static inline void svc_pushback_unused_pages(struct svc_rqst *rqstp)
210{
211        while (rqstp->rq_resused &&
212               rqstp->rq_res.pages != &rqstp->rq_respages[rqstp->rq_resused]) {
213
214                if (rqstp->rq_respages[--rqstp->rq_resused] != NULL) {
215                        rqstp->rq_argpages[rqstp->rq_arghi++] =
216                                rqstp->rq_respages[rqstp->rq_resused];
217                        rqstp->rq_respages[rqstp->rq_resused] = NULL;
218                }
219        }
220}
221
222static inline void svc_free_allpages(struct svc_rqst *rqstp)
223{
224        while (rqstp->rq_resused) {
225                if (rqstp->rq_respages[--rqstp->rq_resused] == NULL)
226                        continue;
227                put_page(rqstp->rq_respages[rqstp->rq_resused]);
228                rqstp->rq_respages[rqstp->rq_resused] = NULL;
229        }
230}
231
232struct svc_deferred_req {
233        __u32                   prot;   /* protocol (UDP or TCP) */
234        struct sockaddr_in      addr;
235        struct svc_sock         *svsk;  /* where reply must go */
236        struct cache_deferred_req handle;
237        int                     argslen;
238        __u32                   args[0];
239};
240
241/*
242 * RPC program
243 */
244struct svc_program {
245        __u32                   pg_prog;        /* program number */
246        unsigned int            pg_lovers;      /* lowest version */
247        unsigned int            pg_hivers;      /* lowest version */
248        unsigned int            pg_nvers;       /* number of versions */
249        struct svc_version **   pg_vers;        /* version array */
250        char *                  pg_name;        /* service name */
251        char *                  pg_class;       /* class name: services sharing authentication */
252        struct svc_stat *       pg_stats;       /* rpc statistics */
253        int                     (*pg_authenticate)(struct svc_rqst *);
254};
255
256/*
257 * RPC program version
258 */
259struct svc_version {
260        __u32                   vs_vers;        /* version number */
261        __u32                   vs_nproc;       /* number of procedures */
262        struct svc_procedure *  vs_proc;        /* per-procedure info */
263        __u32                   vs_xdrsize;     /* xdrsize needed for this version */
264
265        /* Override dispatch function (e.g. when caching replies).
266         * A return value of 0 means drop the request.
267         * vs_dispatch == NULL means use default dispatcher.
268         */
269        int                     (*vs_dispatch)(struct svc_rqst *, __u32 *);
270};
271
272/*
273 * RPC procedure info
274 */
275typedef int     (*svc_procfunc)(struct svc_rqst *, void *argp, void *resp);
276struct svc_procedure {
277        svc_procfunc            pc_func;        /* process the request */
278        kxdrproc_t              pc_decode;      /* XDR decode args */
279        kxdrproc_t              pc_encode;      /* XDR encode result */
280        kxdrproc_t              pc_release;     /* XDR free result */
281        unsigned int            pc_argsize;     /* argument struct size */
282        unsigned int            pc_ressize;     /* result struct size */
283        unsigned int            pc_count;       /* call count */
284        unsigned int            pc_cachetype;   /* cache info (NFS) */
285        unsigned int            pc_xdrressize;  /* maximum size of XDR reply */
286};
287
288/*
289 * This is the RPC server thread function prototype
290 */
291typedef void            (*svc_thread_fn)(struct svc_rqst *);
292
293/*
294 * Function prototypes.
295 */
296struct svc_serv *  svc_create(struct svc_program *, unsigned int);
297int                svc_create_thread(svc_thread_fn, struct svc_serv *);
298void               svc_exit_thread(struct svc_rqst *);
299void               svc_destroy(struct svc_serv *);
300int                svc_process(struct svc_serv *, struct svc_rqst *);
301int                svc_register(struct svc_serv *, int, unsigned short);
302void               svc_wake_up(struct svc_serv *);
303void               svc_reserve(struct svc_rqst *rqstp, int space);
304
305#endif /* SUNRPC_SVC_H */
Note: See TracBrowser for help on using the repository browser.