home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / linux / sunrpc / svc.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  9.5 KB  |  322 lines

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