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