7e5d0e0de0
Currently the knfsd replay cache appears to try to refuse replying to retries that come within 200ms of the cache entry being created. That makes limited sense in today's world of high speed TCP. After a TCP disconnection, a client can very easily reconnect and retry an rpc in less than 200ms. If this logic drops that retry, however, the client may be quite slow to retry again. This logic is original to the first reply cache implementation in 2.1, and may have made more sense for UDP clients that retried much more frequently. After this patch we will still drop on finding the original request still in progress. We may want to fix that as well at some point, though it's less likely. Note that svc_check_conn_limits is often the cause of those disconnections. We may want to fix that some day. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Acked-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
82 lines
1.7 KiB
C
82 lines
1.7 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Request reply cache. This was heavily inspired by the
|
|
* implementation in 4.3BSD/4.4BSD.
|
|
*
|
|
* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
|
|
*/
|
|
|
|
#ifndef NFSCACHE_H
|
|
#define NFSCACHE_H
|
|
|
|
#include <linux/sunrpc/svc.h>
|
|
|
|
/*
|
|
* Representation of a reply cache entry.
|
|
*
|
|
* Note that we use a sockaddr_in6 to hold the address instead of the more
|
|
* typical sockaddr_storage. This is for space reasons, since sockaddr_storage
|
|
* is much larger than a sockaddr_in6.
|
|
*/
|
|
struct svc_cacherep {
|
|
struct list_head c_lru;
|
|
|
|
unsigned char c_state, /* unused, inprog, done */
|
|
c_type, /* status, buffer */
|
|
c_secure : 1; /* req came from port < 1024 */
|
|
struct sockaddr_in6 c_addr;
|
|
__be32 c_xid;
|
|
u32 c_prot;
|
|
u32 c_proc;
|
|
u32 c_vers;
|
|
unsigned int c_len;
|
|
__wsum c_csum;
|
|
unsigned long c_timestamp;
|
|
union {
|
|
struct kvec u_vec;
|
|
__be32 u_status;
|
|
} c_u;
|
|
};
|
|
|
|
#define c_replvec c_u.u_vec
|
|
#define c_replstat c_u.u_status
|
|
|
|
/* cache entry states */
|
|
enum {
|
|
RC_UNUSED,
|
|
RC_INPROG,
|
|
RC_DONE
|
|
};
|
|
|
|
/* return values */
|
|
enum {
|
|
RC_DROPIT,
|
|
RC_REPLY,
|
|
RC_DOIT
|
|
};
|
|
|
|
/*
|
|
* Cache types.
|
|
* We may want to add more types one day, e.g. for diropres and
|
|
* attrstat replies. Using cache entries with fixed length instead
|
|
* of buffer pointers may be more efficient.
|
|
*/
|
|
enum {
|
|
RC_NOCACHE,
|
|
RC_REPLSTAT,
|
|
RC_REPLBUFF,
|
|
};
|
|
|
|
/* Cache entries expire after this time period */
|
|
#define RC_EXPIRE (120 * HZ)
|
|
|
|
/* Checksum this amount of the request */
|
|
#define RC_CSUMLEN (256U)
|
|
|
|
int nfsd_reply_cache_init(void);
|
|
void nfsd_reply_cache_shutdown(void);
|
|
int nfsd_cache_lookup(struct svc_rqst *);
|
|
void nfsd_cache_update(struct svc_rqst *, int, __be32 *);
|
|
int nfsd_reply_cache_stats_open(struct inode *, struct file *);
|
|
|
|
#endif /* NFSCACHE_H */
|