diff options
author | Jeff Layton <jlayton@redhat.com> | 2013-03-27 10:15:37 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2013-04-03 11:47:22 -0400 |
commit | 9dc56143c298692276231735ec6546c1fac596e0 (patch) | |
tree | 7aa12dd6ab8b4ee0863d3bdd3fa8d991aaa30c2e /fs/nfsd/nfscache.c | |
parent | 0b9ea37f24e247ed69baabf27fb211aa6a3e7622 (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.c | 46 |
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 @@ | |||
23 | static struct hlist_head * cache_hash; | 23 | static struct hlist_head * cache_hash; |
24 | static struct list_head lru_head; | 24 | static struct list_head lru_head; |
25 | static struct kmem_cache *drc_slab; | 25 | static struct kmem_cache *drc_slab; |
26 | static unsigned int num_drc_entries; | 26 | |
27 | /* max number of entries allowed in the cache */ | ||
27 | static unsigned int max_drc_entries; | 28 | static 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 */ | ||
36 | static unsigned int num_drc_entries; | ||
37 | |||
38 | /* cache misses due only to checksum comparison failures */ | ||
39 | static unsigned int payload_misses; | ||
40 | |||
41 | /* | ||
30 | * Calculate the hash index from an XID. | 42 | * Calculate the hash index from an XID. |
31 | */ | 43 | */ |
32 | static inline u32 request_hash(u32 xid) | 44 | static 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 | ||
288 | static bool | ||
289 | nfsd_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; |