linux/include/linux/sunrpc/svc.h

/* SPDX-License-Identifier: GPL-2.0 */
/*
 * linux/include/linux/sunrpc/svc.h
 *
 * RPC server declarations.
 *
 * Copyright (C) 1995, 1996 Olaf Kirch <[email protected]>
 */


#ifndef SUNRPC_SVC_H
#define SUNRPC_SVC_H

#include <linux/in.h>
#include <linux/in6.h>
#include <linux/sunrpc/types.h>
#include <linux/sunrpc/xdr.h>
#include <linux/sunrpc/auth.h>
#include <linux/sunrpc/svcauth.h>
#include <linux/lwq.h>
#include <linux/wait.h>
#include <linux/mm.h>
#include <linux/pagevec.h>

/*
 *
 * RPC service thread pool.
 *
 * Pool of threads and temporary sockets.  Generally there is only
 * a single one of these per RPC service, but on NUMA machines those
 * services that can benefit from it (i.e. nfs but not lockd) will
 * have one pool per NUMA node.  This optimisation reduces cross-
 * node traffic on multi-node NUMA NFS servers.
 */
struct svc_pool {} ____cacheline_aligned_in_smp;

/* bits for sp_flags */
enum {};


/*
 * 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 {};

/* This is used by pool_stats to find and lock an svc */
struct svc_info {};

void svc_destroy(struct svc_serv **svcp);

/*
 * 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.
 *
 * These happen to all be powers of 2, which is not strictly
 * necessary but helps enforce the real limitation, which is
 * that they should be multiples of PAGE_SIZE.
 *
 * For UDP transports, a block plus NFS,RPC, and UDP headers
 * has to fit into the IP datagram limit of 64K.  The largest
 * feasible number for all known page sizes is probably 48K,
 * but we choose 32K here.  This is the same as the historical
 * Linux limit; someone who cares more about NFS/UDP performance
 * can test a larger number.
 *
 * For TCP transports we have more freedom.  A size of 1MB is
 * chosen to match the client limit.  Other OSes are known to
 * have larger limits, but those numbers are probably beyond
 * the point of diminishing returns.
 */
#define RPCSVC_MAXPAYLOAD
#define RPCSVC_MAXPAYLOAD_TCP
#define RPCSVC_MAXPAYLOAD_UDP

extern u32 svc_max_payload(const struct svc_rqst *rqstp);

/*
 * RPC Requests and replies are stored in one or more pages.
 * We maintain an array of pages for each server thread.
 * Requests are copied into these pages as they arrive.  Remaining
 * pages are available to write the reply into.
 *
 * Pages are sent using ->sendmsg with MSG_SPLICE_PAGES so each server thread
 * needs to allocate more to replace those used in sending.  To help keep track
 * of these pages we have a receive list where all pages initialy live, and a
 * send list where pages are moved to when there are to be part of a reply.
 *
 * We use xdr_buf for holding responses as it fits well with NFS
 * read responses (that have a header, and some data pages, and possibly
 * a tail) and means we can share some client side routines.
 *
 * The xdr_buf.head kvec always points to the first page in the rq_*pages
 * list.  The xdr_buf.pages pointer points to the second page on that
 * list.  xdr_buf.tail points to the end of the first page.
 * This assumes that the non-page part of an rpc reply will fit
 * in a page - NFSd ensures this.  lockd also has no trouble.
 *
 * Each request/reply pair can have at most one "payload", plus two pages,
 * one for the request, and one for the reply.
 * We using ->sendfile to return read data, we might need one extra page
 * if the request is not page-aligned.  So add another '1'.
 */
#define RPCSVC_MAXPAGES

/*
 * The context of a single thread, including the request currently being
 * processed.
 */
struct svc_rqst {};

/* bits for rq_flags */
enum {};

#define SVC_NET(rqst)

/*
 * Rigorous type checking on sockaddr type conversions
 */
static inline struct sockaddr_in *svc_addr_in(const struct svc_rqst *rqst)
{}

static inline struct sockaddr_in6 *svc_addr_in6(const struct svc_rqst *rqst)
{}

static inline struct sockaddr *svc_addr(const struct svc_rqst *rqst)
{}

static inline struct sockaddr_in *svc_daddr_in(const struct svc_rqst *rqst)
{}

static inline struct sockaddr_in6 *svc_daddr_in6(const struct svc_rqst *rqst)
{}

static inline struct sockaddr *svc_daddr(const struct svc_rqst *rqst)
{}

/**
 * svc_thread_should_stop - check if this thread should stop
 * @rqstp: the thread that might need to stop
 *
 * To stop an svc thread, the pool flags SP_NEED_VICTIM and SP_VICTIM_REMAINS
 * are set.  The first thread which sees SP_NEED_VICTIM clears it, becoming
 * the victim using this function.  It should then promptly call
 * svc_exit_thread() to complete the process, clearing SP_VICTIM_REMAINS
 * so the task waiting for a thread to exit can wake and continue.
 *
 * Return values:
 *   %true: caller should invoke svc_exit_thread()
 *   %false: caller should do nothing
 */
static inline bool svc_thread_should_stop(struct svc_rqst *rqstp)
{}

struct svc_deferred_req {};

struct svc_process_info {};

/*
 * List of RPC programs on the same transport endpoint
 */
struct svc_program {};

/*
 * RPC program version
 */
struct svc_version {};

/*
 * RPC procedure info
 */
struct svc_procedure {};

/*
 * Function prototypes.
 */
int sunrpc_set_pool_mode(const char *val);
int sunrpc_get_pool_mode(char *val, size_t size);
int svc_rpcb_setup(struct svc_serv *serv, struct net *net);
void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net);
int svc_bind(struct svc_serv *serv, struct net *net);
struct svc_serv *svc_create(struct svc_program *, unsigned int,
			    int (*threadfn)(void *data));
struct svc_rqst *svc_rqst_alloc(struct svc_serv *serv,
					struct svc_pool *pool, int node);
bool		   svc_rqst_replace_page(struct svc_rqst *rqstp,
					 struct page *page);
void		   svc_rqst_release_pages(struct svc_rqst *rqstp);
void		   svc_rqst_free(struct svc_rqst *);
void		   svc_exit_thread(struct svc_rqst *);
struct svc_serv *  svc_create_pooled(struct svc_program *prog,
				     struct svc_stat *stats,
				     unsigned int bufsize,
				     int (*threadfn)(void *data));
int		   svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
int		   svc_pool_stats_open(struct svc_info *si, struct file *file);
void		   svc_process(struct svc_rqst *rqstp);
void		   svc_process_bc(struct rpc_rqst *req, struct svc_rqst *rqstp);
int		   svc_register(const struct svc_serv *, struct net *, const int,
				const unsigned short, const unsigned short);

void		   svc_wake_up(struct svc_serv *);
void		   svc_reserve(struct svc_rqst *rqstp, int space);
void		   svc_pool_wake_idle_thread(struct svc_pool *pool);
struct svc_pool   *svc_pool_for_cpu(struct svc_serv *serv);
char *		   svc_print_addr(struct svc_rqst *, char *, size_t);
const char *	   svc_proc_name(const struct svc_rqst *rqstp);
int		   svc_encode_result_payload(struct svc_rqst *rqstp,
					     unsigned int offset,
					     unsigned int length);
unsigned int	   svc_fill_write_vector(struct svc_rqst *rqstp,
					 struct xdr_buf *payload);
char		  *svc_fill_symlink_pathname(struct svc_rqst *rqstp,
					     struct kvec *first, void *p,
					     size_t total);
__be32		   svc_generic_init_request(struct svc_rqst *rqstp,
					    const struct svc_program *progp,
					    struct svc_process_info *procinfo);
int		   svc_generic_rpcbind_set(struct net *net,
					   const struct svc_program *progp,
					   u32 version, int family,
					   unsigned short proto,
					   unsigned short port);
int		   svc_rpcbind_set_version(struct net *net,
					   const struct svc_program *progp,
					   u32 version, int family,
					   unsigned short proto,
					   unsigned short port);

#define RPC_MAX_ADDRBUFLEN

/*
 * When we want to reduce the size of the reserved space in the response
 * buffer, we need to take into account the size of any checksum data that
 * may be at the end of the packet. This is difficult to determine exactly
 * for all cases without actually generating the checksum, so we just use a
 * static value.
 */
static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space)
{}

/**
 * svcxdr_init_decode - Prepare an xdr_stream for Call decoding
 * @rqstp: controlling server RPC transaction context
 *
 */
static inline void svcxdr_init_decode(struct svc_rqst *rqstp)
{}

/**
 * svcxdr_init_encode - Prepare an xdr_stream for svc Reply encoding
 * @rqstp: controlling server RPC transaction context
 *
 */
static inline void svcxdr_init_encode(struct svc_rqst *rqstp)
{}

/**
 * svcxdr_encode_opaque_pages - Insert pages into an xdr_stream
 * @xdr: xdr_stream to be updated
 * @pages: array of pages to insert
 * @base: starting offset of first data byte in @pages
 * @len: number of data bytes in @pages to insert
 *
 * After the @pages are added, the tail iovec is instantiated pointing
 * to end of the head buffer, and the stream is set up to encode
 * subsequent items into the tail.
 */
static inline void svcxdr_encode_opaque_pages(struct svc_rqst *rqstp,
					      struct xdr_stream *xdr,
					      struct page **pages,
					      unsigned int base,
					      unsigned int len)
{}

/**
 * svcxdr_set_auth_slack -
 * @rqstp: RPC transaction
 * @slack: buffer space to reserve for the transaction's security flavor
 *
 * Set the request's slack space requirement, and set aside that much
 * space in the rqstp's rq_res.head for use when the auth wraps the Reply.
 */
static inline void svcxdr_set_auth_slack(struct svc_rqst *rqstp, int slack)
{}

/**
 * svcxdr_set_accept_stat - Reserve space for the accept_stat field
 * @rqstp: RPC transaction context
 *
 * Return values:
 *   %true: Success
 *   %false: No response buffer space was available
 */
static inline bool svcxdr_set_accept_stat(struct svc_rqst *rqstp)
{}

#endif /* SUNRPC_SVC_H */