Home | History | Annotate | Download | only in sunrpc
      1 /*
      2  * linux/include/linux/sunrpc/svc.h
      3  *
      4  * RPC server declarations.
      5  *
      6  * Copyright (C) 1995, 1996 Olaf Kirch <okir (at) 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 	int			rq_sendfile_ok; /* turned off in gss privacy
    163 						 * to prevent encrypting page
    164 						 * cache pages */
    165 	wait_queue_head_t	rq_wait;	/* synchronization */
    166 };
    167 
    168 /*
    169  * Check buffer bounds after decoding arguments
    170  */
    171 static inline int
    172 xdr_argsize_check(struct svc_rqst *rqstp, u32 *p)
    173 {
    174 	char *cp = (char *)p;
    175 	struct kvec *vec = &rqstp->rq_arg.head[0];
    176 	return cp >= (char*)vec->iov_base
    177 		&& cp <= (char*)vec->iov_base + vec->iov_len;
    178 }
    179 
    180 static inline int
    181 xdr_ressize_check(struct svc_rqst *rqstp, u32 *p)
    182 {
    183 	struct kvec *vec = &rqstp->rq_res.head[0];
    184 	char *cp = (char*)p;
    185 
    186 	vec->iov_len = cp - (char*)vec->iov_base;
    187 
    188 	return vec->iov_len <= PAGE_SIZE;
    189 }
    190 
    191 static inline struct page *
    192 svc_take_res_page(struct svc_rqst *rqstp)
    193 {
    194 	if (rqstp->rq_arghi <= rqstp->rq_argused)
    195 		return NULL;
    196 	rqstp->rq_arghi--;
    197 	rqstp->rq_respages[rqstp->rq_resused] =
    198 		rqstp->rq_argpages[rqstp->rq_arghi];
    199 	return rqstp->rq_respages[rqstp->rq_resused++];
    200 }
    201 
    202 static inline void svc_take_page(struct svc_rqst *rqstp)
    203 {
    204 	if (rqstp->rq_arghi <= rqstp->rq_argused) {
    205 		WARN_ON(1);
    206 		return;
    207 	}
    208 	rqstp->rq_arghi--;
    209 	rqstp->rq_respages[rqstp->rq_resused] =
    210 		rqstp->rq_argpages[rqstp->rq_arghi];
    211 	rqstp->rq_resused++;
    212 }
    213 
    214 static inline void svc_pushback_allpages(struct svc_rqst *rqstp)
    215 {
    216         while (rqstp->rq_resused) {
    217 		if (rqstp->rq_respages[--rqstp->rq_resused] == NULL)
    218 			continue;
    219 		rqstp->rq_argpages[rqstp->rq_arghi++] =
    220 			rqstp->rq_respages[rqstp->rq_resused];
    221 		rqstp->rq_respages[rqstp->rq_resused] = NULL;
    222 	}
    223 }
    224 
    225 static inline void svc_pushback_unused_pages(struct svc_rqst *rqstp)
    226 {
    227 	while (rqstp->rq_resused &&
    228 	       rqstp->rq_res.pages != &rqstp->rq_respages[rqstp->rq_resused]) {
    229 
    230 		if (rqstp->rq_respages[--rqstp->rq_resused] != NULL) {
    231 			rqstp->rq_argpages[rqstp->rq_arghi++] =
    232 				rqstp->rq_respages[rqstp->rq_resused];
    233 			rqstp->rq_respages[rqstp->rq_resused] = NULL;
    234 		}
    235 	}
    236 }
    237 
    238 static inline void svc_free_allpages(struct svc_rqst *rqstp)
    239 {
    240         while (rqstp->rq_resused) {
    241 		if (rqstp->rq_respages[--rqstp->rq_resused] == NULL)
    242 			continue;
    243 		put_page(rqstp->rq_respages[rqstp->rq_resused]);
    244 		rqstp->rq_respages[rqstp->rq_resused] = NULL;
    245 	}
    246 }
    247 
    248 struct svc_deferred_req {
    249 	u32			prot;	/* protocol (UDP or TCP) */
    250 	struct sockaddr_in	addr;
    251 	struct svc_sock		*svsk;	/* where reply must go */
    252 	u32			daddr;	/* where reply must come from */
    253 	struct cache_deferred_req handle;
    254 	int			argslen;
    255 	u32			args[0];
    256 };
    257 
    258 /*
    259  * List of RPC programs on the same transport endpoint
    260  */
    261 struct svc_program {
    262 	struct svc_program *	pg_next;	/* other programs (same xprt) */
    263 	u32			pg_prog;	/* program number */
    264 	unsigned int		pg_lovers;	/* lowest version */
    265 	unsigned int		pg_hivers;	/* lowest version */
    266 	unsigned int		pg_nvers;	/* number of versions */
    267 	struct svc_version **	pg_vers;	/* version array */
    268 	char *			pg_name;	/* service name */
    269 	char *			pg_class;	/* class name: services sharing authentication */
    270 	struct svc_stat *	pg_stats;	/* rpc statistics */
    271 	int			(*pg_authenticate)(struct svc_rqst *);
    272 };
    273 
    274 /*
    275  * RPC program version
    276  */
    277 struct svc_version {
    278 	u32			vs_vers;	/* version number */
    279 	u32			vs_nproc;	/* number of procedures */
    280 	struct svc_procedure *	vs_proc;	/* per-procedure info */
    281 	u32			vs_xdrsize;	/* xdrsize needed for this version */
    282 
    283 	/* Override dispatch function (e.g. when caching replies).
    284 	 * A return value of 0 means drop the request.
    285 	 * vs_dispatch == NULL means use default dispatcher.
    286 	 */
    287 	int			(*vs_dispatch)(struct svc_rqst *, u32 *);
    288 };
    289 
    290 /*
    291  * RPC procedure info
    292  */
    293 typedef int	(*svc_procfunc)(struct svc_rqst *, void *argp, void *resp);
    294 struct svc_procedure {
    295 	svc_procfunc		pc_func;	/* process the request */
    296 	kxdrproc_t		pc_decode;	/* XDR decode args */
    297 	kxdrproc_t		pc_encode;	/* XDR encode result */
    298 	kxdrproc_t		pc_release;	/* XDR free result */
    299 	unsigned int		pc_argsize;	/* argument struct size */
    300 	unsigned int		pc_ressize;	/* result struct size */
    301 	unsigned int		pc_count;	/* call count */
    302 	unsigned int		pc_cachetype;	/* cache info (NFS) */
    303 	unsigned int		pc_xdrressize;	/* maximum size of XDR reply */
    304 };
    305 
    306 /*
    307  * This is the RPC server thread function prototype
    308  */
    309 typedef void		(*svc_thread_fn)(struct svc_rqst *);
    310 
    311 /*
    312  * Function prototypes.
    313  */
    314 struct svc_serv *  svc_create(struct svc_program *, unsigned int);
    315 int		   svc_create_thread(svc_thread_fn, struct svc_serv *);
    316 void		   svc_exit_thread(struct svc_rqst *);
    317 void		   svc_destroy(struct svc_serv *);
    318 int		   svc_process(struct svc_serv *, struct svc_rqst *);
    319 int		   svc_register(struct svc_serv *, int, unsigned short);
    320 void		   svc_wake_up(struct svc_serv *);
    321 void		   svc_reserve(struct svc_rqst *rqstp, int space);
    322 
    323 #endif /* SUNRPC_SVC_H */
    324