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