162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Request reply cache. This was heavily inspired by the
462306a36Sopenharmony_ci * implementation in 4.3BSD/4.4BSD.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#ifndef NFSCACHE_H
1062306a36Sopenharmony_ci#define NFSCACHE_H
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <linux/sunrpc/svc.h>
1362306a36Sopenharmony_ci#include "netns.h"
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci/*
1662306a36Sopenharmony_ci * Representation of a reply cache entry.
1762306a36Sopenharmony_ci *
1862306a36Sopenharmony_ci * Note that we use a sockaddr_in6 to hold the address instead of the more
1962306a36Sopenharmony_ci * typical sockaddr_storage. This is for space reasons, since sockaddr_storage
2062306a36Sopenharmony_ci * is much larger than a sockaddr_in6.
2162306a36Sopenharmony_ci */
2262306a36Sopenharmony_cistruct nfsd_cacherep {
2362306a36Sopenharmony_ci	struct {
2462306a36Sopenharmony_ci		/* Keep often-read xid, csum in the same cache line: */
2562306a36Sopenharmony_ci		__be32			k_xid;
2662306a36Sopenharmony_ci		__wsum			k_csum;
2762306a36Sopenharmony_ci		u32			k_proc;
2862306a36Sopenharmony_ci		u32			k_prot;
2962306a36Sopenharmony_ci		u32			k_vers;
3062306a36Sopenharmony_ci		unsigned int		k_len;
3162306a36Sopenharmony_ci		struct sockaddr_in6	k_addr;
3262306a36Sopenharmony_ci	} c_key;
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	struct rb_node		c_node;
3562306a36Sopenharmony_ci	struct list_head	c_lru;
3662306a36Sopenharmony_ci	unsigned char		c_state,	/* unused, inprog, done */
3762306a36Sopenharmony_ci				c_type,		/* status, buffer */
3862306a36Sopenharmony_ci				c_secure : 1;	/* req came from port < 1024 */
3962306a36Sopenharmony_ci	unsigned long		c_timestamp;
4062306a36Sopenharmony_ci	union {
4162306a36Sopenharmony_ci		struct kvec	u_vec;
4262306a36Sopenharmony_ci		__be32		u_status;
4362306a36Sopenharmony_ci	}			c_u;
4462306a36Sopenharmony_ci};
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci#define c_replvec		c_u.u_vec
4762306a36Sopenharmony_ci#define c_replstat		c_u.u_status
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci/* cache entry states */
5062306a36Sopenharmony_cienum {
5162306a36Sopenharmony_ci	RC_UNUSED,
5262306a36Sopenharmony_ci	RC_INPROG,
5362306a36Sopenharmony_ci	RC_DONE
5462306a36Sopenharmony_ci};
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci/* return values */
5762306a36Sopenharmony_cienum {
5862306a36Sopenharmony_ci	RC_DROPIT,
5962306a36Sopenharmony_ci	RC_REPLY,
6062306a36Sopenharmony_ci	RC_DOIT
6162306a36Sopenharmony_ci};
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci/*
6462306a36Sopenharmony_ci * Cache types.
6562306a36Sopenharmony_ci * We may want to add more types one day, e.g. for diropres and
6662306a36Sopenharmony_ci * attrstat replies. Using cache entries with fixed length instead
6762306a36Sopenharmony_ci * of buffer pointers may be more efficient.
6862306a36Sopenharmony_ci */
6962306a36Sopenharmony_cienum {
7062306a36Sopenharmony_ci	RC_NOCACHE,
7162306a36Sopenharmony_ci	RC_REPLSTAT,
7262306a36Sopenharmony_ci	RC_REPLBUFF,
7362306a36Sopenharmony_ci};
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci/* Cache entries expire after this time period */
7662306a36Sopenharmony_ci#define RC_EXPIRE		(120 * HZ)
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci/* Checksum this amount of the request */
7962306a36Sopenharmony_ci#define RC_CSUMLEN		(256U)
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ciint	nfsd_drc_slab_create(void);
8262306a36Sopenharmony_civoid	nfsd_drc_slab_free(void);
8362306a36Sopenharmony_ciint	nfsd_net_reply_cache_init(struct nfsd_net *nn);
8462306a36Sopenharmony_civoid	nfsd_net_reply_cache_destroy(struct nfsd_net *nn);
8562306a36Sopenharmony_ciint	nfsd_reply_cache_init(struct nfsd_net *);
8662306a36Sopenharmony_civoid	nfsd_reply_cache_shutdown(struct nfsd_net *);
8762306a36Sopenharmony_ciint	nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start,
8862306a36Sopenharmony_ci			  unsigned int len, struct nfsd_cacherep **cacherep);
8962306a36Sopenharmony_civoid	nfsd_cache_update(struct svc_rqst *rqstp, struct nfsd_cacherep *rp,
9062306a36Sopenharmony_ci			  int cachetype, __be32 *statp);
9162306a36Sopenharmony_ciint	nfsd_reply_cache_stats_show(struct seq_file *m, void *v);
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci#endif /* NFSCACHE_H */
94