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