aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfscache.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2013-03-27 10:15:37 -0400
committerJ. Bruce Fields <bfields@redhat.com>2013-04-03 11:47:22 -0400
commit9dc56143c298692276231735ec6546c1fac596e0 (patch)
tree7aa12dd6ab8b4ee0863d3bdd3fa8d991aaa30c2e /fs/nfsd/nfscache.c
parent0b9ea37f24e247ed69baabf27fb211aa6a3e7622 (diff)
nfsd: break out comparator into separate function
Break out the function that compares the rqstp and checksum against a reply cache entry. While we're at it, track the efficacy of the checksum over the NFS data by tracking the cases where we would have incorrectly matched a DRC entry if we had not tracked it or the length. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfscache.c')
-rw-r--r--fs/nfsd/nfscache.c46
1 files changed, 35 insertions, 11 deletions
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c
index c61391e8e09d..48f5ef944234 100644
--- a/fs/nfsd/nfscache.c
+++ b/fs/nfsd/nfscache.c
@@ -23,10 +23,22 @@
23static struct hlist_head * cache_hash; 23static struct hlist_head * cache_hash;
24static struct list_head lru_head; 24static struct list_head lru_head;
25static struct kmem_cache *drc_slab; 25static struct kmem_cache *drc_slab;
26static unsigned int num_drc_entries; 26
27/* max number of entries allowed in the cache */
27static unsigned int max_drc_entries; 28static unsigned int max_drc_entries;
28 29
29/* 30/*
31 * Stats and other tracking of on the duplicate reply cache. All of these and
32 * the "rc" fields in nfsdstats are protected by the cache_lock
33 */
34
35/* total number of entries */
36static unsigned int num_drc_entries;
37
38/* cache misses due only to checksum comparison failures */
39static unsigned int payload_misses;
40
41/*
30 * Calculate the hash index from an XID. 42 * Calculate the hash index from an XID.
31 */ 43 */
32static inline u32 request_hash(u32 xid) 44static inline u32 request_hash(u32 xid)
@@ -273,6 +285,26 @@ nfsd_cache_csum(struct svc_rqst *rqstp)
273 return csum; 285 return csum;
274} 286}
275 287
288static bool
289nfsd_cache_match(struct svc_rqst *rqstp, __wsum csum, struct svc_cacherep *rp)
290{
291 /* Check RPC header info first */
292 if (rqstp->rq_xid != rp->c_xid || rqstp->rq_proc != rp->c_proc ||
293 rqstp->rq_prot != rp->c_prot || rqstp->rq_vers != rp->c_vers ||
294 rqstp->rq_arg.len != rp->c_len ||
295 !rpc_cmp_addr(svc_addr(rqstp), (struct sockaddr *)&rp->c_addr) ||
296 rpc_get_port(svc_addr(rqstp)) != rpc_get_port((struct sockaddr *)&rp->c_addr))
297 return false;
298
299 /* compare checksum of NFS data */
300 if (csum != rp->c_csum) {
301 ++payload_misses;
302 return false;
303 }
304
305 return true;
306}
307
276/* 308/*
277 * Search the request hash for an entry that matches the given rqstp. 309 * Search the request hash for an entry that matches the given rqstp.
278 * Must be called with cache_lock held. Returns the found entry or 310 * Must be called with cache_lock held. Returns the found entry or
@@ -283,18 +315,10 @@ nfsd_cache_search(struct svc_rqst *rqstp, __wsum csum)
283{ 315{
284 struct svc_cacherep *rp; 316 struct svc_cacherep *rp;
285 struct hlist_head *rh; 317 struct hlist_head *rh;
286 __be32 xid = rqstp->rq_xid;
287 u32 proto = rqstp->rq_prot,
288 vers = rqstp->rq_vers,
289 proc = rqstp->rq_proc;
290 318
291 rh = &cache_hash[request_hash(xid)]; 319 rh = &cache_hash[request_hash(rqstp->rq_xid)];
292 hlist_for_each_entry(rp, rh, c_hash) { 320 hlist_for_each_entry(rp, rh, c_hash) {
293 if (xid == rp->c_xid && proc == rp->c_proc && 321 if (nfsd_cache_match(rqstp, csum, rp))
294 proto == rp->c_prot && vers == rp->c_vers &&
295 rqstp->rq_arg.len == rp->c_len && csum == rp->c_csum &&
296 rpc_cmp_addr(svc_addr(rqstp), (struct sockaddr *)&rp->c_addr) &&
297 rpc_get_port(svc_addr(rqstp)) == rpc_get_port((struct sockaddr *)&rp->c_addr))
298 return rp; 322 return rp;
299 } 323 }
300 return NULL; 324 return NULL;