Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 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 174 175 176 177 178 179 180 181 182 183 | /* * linux/include/linux/sunrpc/svc.h * * RPC server declarations. * * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */ #ifndef SUNRPC_SVC_H #define SUNRPC_SVC_H #include <linux/in.h> #include <linux/sunrpc/types.h> #include <linux/sunrpc/xdr.h> #include <linux/sunrpc/svcauth.h> /* * RPC service. * * An RPC service is a ``daemon,'' possibly multithreaded, which * receives and processes incoming RPC messages. * It has one or more transport sockets associated with it, and maintains * a list of idle threads waiting for input. * * We currently do not support more than one RPC program per daemon. */ struct svc_serv { struct svc_rqst * sv_threads; /* idle server threads */ struct svc_sock * sv_sockets; /* pending sockets */ struct svc_program * sv_program; /* RPC program */ struct svc_stat * sv_stats; /* RPC statistics */ spinlock_t sv_lock; unsigned int sv_nrthreads; /* # of server threads */ unsigned int sv_bufsz; /* datagram buffer size */ unsigned int sv_xdrsize; /* XDR buffer size */ struct svc_sock * sv_allsocks; /* all sockets */ char * sv_name; /* service name */ }; /* * Maximum payload size supported by a kernel RPC server. * This is use to determine the max number of pages nfsd is * willing to return in a single READ operation. */ #define RPCSVC_MAXPAYLOAD 16384u /* * Buffer to store RPC requests or replies in. * Each server thread has one of these beasts. * * Area points to the allocated memory chunk currently owned by the * buffer. Base points to the buffer containing the request, which is * different from area when directly reading from an sk_buff. buf is * the current read/write position while processing an RPC request. * * The array of iovecs can hold additional data that the server process * may not want to copy into the RPC reply buffer, but pass to the * network sendmsg routines directly. The prime candidate for this * will of course be NFS READ operations, but one might also want to * do something about READLINK and READDIR. It might be worthwhile * to implement some generic readdir cache in the VFS layer... * * On the receiving end of the RPC server, the iovec may be used to hold * the list of IP fragments once we get to process fragmented UDP * datagrams directly. */ #define RPCSVC_MAXIOV ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE + 1) struct svc_buf { u32 * area; /* allocated memory */ u32 * base; /* base of RPC datagram */ int buflen; /* total length of buffer */ u32 * buf; /* read/write pointer */ int len; /* current end of buffer */ /* iovec for zero-copy NFS READs */ struct iovec iov[RPCSVC_MAXIOV]; int nriov; }; #define svc_getlong(argp, val) { (val) = *(argp)->buf++; (argp)->len--; } #define svc_putlong(resp, val) { *(resp)->buf++ = (val); (resp)->len++; } /* * The context of a single thread, including the request currently being * processed. * NOTE: First two items must be prev/next. */ struct svc_rqst { struct svc_rqst * rq_prev; /* idle list */ struct svc_rqst * rq_next; struct svc_sock * rq_sock; /* socket */ struct sockaddr_in rq_addr; /* peer address */ int rq_addrlen; struct svc_serv * rq_server; /* RPC service definition */ struct svc_procedure * rq_procinfo; /* procedure info */ struct svc_cred rq_cred; /* auth info */ struct sk_buff * rq_skbuff; /* fast recv inet buffer */ struct svc_buf rq_defbuf; /* default buffer */ struct svc_buf rq_argbuf; /* argument buffer */ struct svc_buf rq_resbuf; /* result buffer */ u32 rq_xid; /* transmission id */ u32 rq_prog; /* program number */ u32 rq_vers; /* program version */ u32 rq_proc; /* procedure number */ u32 rq_prot; /* IP protocol */ unsigned short rq_verfed : 1, /* reply has verifier */ rq_userset : 1, /* auth->setuser OK */ rq_secure : 1, /* secure port */ rq_auth : 1; /* check client */ void * rq_argp; /* decoded arguments */ void * rq_resp; /* xdr'd results */ /* Catering to nfsd */ struct svc_client * rq_client; /* RPC peer info */ struct svc_cacherep * rq_cacherep; /* cache info */ wait_queue_head_t rq_wait; /* synchronozation */ }; /* * RPC program */ struct svc_program { u32 pg_prog; /* program number */ unsigned int pg_lovers; /* lowest version */ unsigned int pg_hivers; /* lowest version */ unsigned int pg_nvers; /* number of versions */ struct svc_version ** pg_vers; /* version array */ char * pg_name; /* service name */ struct svc_stat * pg_stats; /* rpc statistics */ }; /* * RPC program version */ struct svc_version { u32 vs_vers; /* version number */ u32 vs_nproc; /* number of procedures */ struct svc_procedure * vs_proc; /* per-procedure info */ /* Override dispatch function (e.g. when caching replies). * A return value of 0 means drop the request. * vs_dispatch == NULL means use default dispatcher. */ int (*vs_dispatch)(struct svc_rqst *, u32 *); }; /* * RPC procedure info */ typedef int (*svc_procfunc)(struct svc_rqst *, void *argp, void *resp); struct svc_procedure { svc_procfunc pc_func; /* process the request */ kxdrproc_t pc_decode; /* XDR decode args */ kxdrproc_t pc_encode; /* XDR encode result */ kxdrproc_t pc_release; /* XDR free result */ unsigned int pc_argsize; /* argument struct size */ unsigned int pc_ressize; /* result struct size */ unsigned int pc_count; /* call count */ unsigned int pc_cachetype; /* cache info (NFS) */ }; /* * This is the RPC server thread function prototype */ typedef void (*svc_thread_fn)(struct svc_rqst *); /* * Function prototypes. */ struct svc_serv * svc_create(struct svc_program *, unsigned int, unsigned int); int svc_create_thread(svc_thread_fn, struct svc_serv *); void svc_exit_thread(struct svc_rqst *); void svc_destroy(struct svc_serv *); int svc_process(struct svc_serv *, struct svc_rqst *); int svc_register(struct svc_serv *, int, unsigned short); void svc_wake_up(struct svc_serv *); #endif /* SUNRPC_SVC_H */ |