@@ -121,7 +121,7 @@ nfsd_cache_hash(__be32 xid)
121
121
}
122
122
123
123
static struct svc_cacherep *
124
- nfsd_reply_cache_alloc (void )
124
+ nfsd_reply_cache_alloc (struct svc_rqst * rqstp , __wsum csum )
125
125
{
126
126
struct svc_cacherep * rp ;
127
127
@@ -130,6 +130,16 @@ nfsd_reply_cache_alloc(void)
130
130
rp -> c_state = RC_UNUSED ;
131
131
rp -> c_type = RC_NOCACHE ;
132
132
INIT_LIST_HEAD (& rp -> c_lru );
133
+
134
+ rp -> c_xid = rqstp -> rq_xid ;
135
+ rp -> c_proc = rqstp -> rq_proc ;
136
+ memset (& rp -> c_addr , 0 , sizeof (rp -> c_addr ));
137
+ rpc_copy_addr ((struct sockaddr * )& rp -> c_addr , svc_addr (rqstp ));
138
+ rpc_set_port ((struct sockaddr * )& rp -> c_addr , rpc_get_port (svc_addr (rqstp )));
139
+ rp -> c_prot = rqstp -> rq_prot ;
140
+ rp -> c_vers = rqstp -> rq_vers ;
141
+ rp -> c_len = rqstp -> rq_arg .len ;
142
+ rp -> c_csum = csum ;
133
143
}
134
144
return rp ;
135
145
}
@@ -141,9 +151,11 @@ nfsd_reply_cache_free_locked(struct svc_cacherep *rp)
141
151
drc_mem_usage -= rp -> c_replvec .iov_len ;
142
152
kfree (rp -> c_replvec .iov_base );
143
153
}
144
- list_del (& rp -> c_lru );
145
- atomic_dec (& num_drc_entries );
146
- drc_mem_usage -= sizeof (* rp );
154
+ if (rp -> c_state != RC_UNUSED ) {
155
+ list_del (& rp -> c_lru );
156
+ atomic_dec (& num_drc_entries );
157
+ drc_mem_usage -= sizeof (* rp );
158
+ }
147
159
kmem_cache_free (drc_slab , rp );
148
160
}
149
161
@@ -319,24 +331,23 @@ nfsd_cache_csum(struct svc_rqst *rqstp)
319
331
}
320
332
321
333
static bool
322
- nfsd_cache_match (struct svc_rqst * rqstp , __wsum csum , struct svc_cacherep * rp )
334
+ nfsd_cache_match (const struct svc_cacherep * key , const struct svc_cacherep * rp )
323
335
{
324
336
/* Check RPC XID first */
325
- if (rqstp -> rq_xid != rp -> c_xid )
337
+ if (key -> c_xid != rp -> c_xid )
326
338
return false;
327
339
/* compare checksum of NFS data */
328
- if (csum != rp -> c_csum ) {
340
+ if (key -> c_csum != rp -> c_csum ) {
329
341
++ payload_misses ;
330
342
return false;
331
343
}
332
344
333
345
/* Other discriminators */
334
- if (rqstp -> rq_proc != rp -> c_proc ||
335
- rqstp -> rq_prot != rp -> c_prot ||
336
- rqstp -> rq_vers != rp -> c_vers ||
337
- rqstp -> rq_arg .len != rp -> c_len ||
338
- !rpc_cmp_addr (svc_addr (rqstp ), (struct sockaddr * )& rp -> c_addr ) ||
339
- rpc_get_port (svc_addr (rqstp )) != rpc_get_port ((struct sockaddr * )& rp -> c_addr ))
346
+ if (key -> c_proc != rp -> c_proc ||
347
+ key -> c_prot != rp -> c_prot ||
348
+ key -> c_vers != rp -> c_vers ||
349
+ key -> c_len != rp -> c_len ||
350
+ memcmp (& key -> c_addr , & rp -> c_addr , sizeof (key -> c_addr )) != 0 )
340
351
return false;
341
352
342
353
return true;
@@ -345,19 +356,18 @@ nfsd_cache_match(struct svc_rqst *rqstp, __wsum csum, struct svc_cacherep *rp)
345
356
/*
346
357
* Search the request hash for an entry that matches the given rqstp.
347
358
* Must be called with cache_lock held. Returns the found entry or
348
- * NULL on failure.
359
+ * inserts an empty key on failure.
349
360
*/
350
361
static struct svc_cacherep *
351
- nfsd_cache_search (struct nfsd_drc_bucket * b , struct svc_rqst * rqstp ,
352
- __wsum csum )
362
+ nfsd_cache_insert (struct nfsd_drc_bucket * b , struct svc_cacherep * key )
353
363
{
354
- struct svc_cacherep * rp , * ret = NULL ;
364
+ struct svc_cacherep * rp , * ret = key ;
355
365
struct list_head * rh = & b -> lru_head ;
356
366
unsigned int entries = 0 ;
357
367
358
368
list_for_each_entry (rp , rh , c_lru ) {
359
369
++ entries ;
360
- if (nfsd_cache_match (rqstp , csum , rp )) {
370
+ if (nfsd_cache_match (key , rp )) {
361
371
ret = rp ;
362
372
break ;
363
373
}
@@ -374,6 +384,7 @@ nfsd_cache_search(struct nfsd_drc_bucket *b, struct svc_rqst *rqstp,
374
384
atomic_read (& num_drc_entries ));
375
385
}
376
386
387
+ lru_put_end (b , ret );
377
388
return ret ;
378
389
}
379
390
@@ -389,9 +400,6 @@ nfsd_cache_lookup(struct svc_rqst *rqstp)
389
400
{
390
401
struct svc_cacherep * rp , * found ;
391
402
__be32 xid = rqstp -> rq_xid ;
392
- u32 proto = rqstp -> rq_prot ,
393
- vers = rqstp -> rq_vers ,
394
- proc = rqstp -> rq_proc ;
395
403
__wsum csum ;
396
404
u32 hash = nfsd_cache_hash (xid );
397
405
struct nfsd_drc_bucket * b = & drc_hashtbl [hash ];
@@ -410,52 +418,38 @@ nfsd_cache_lookup(struct svc_rqst *rqstp)
410
418
* Since the common case is a cache miss followed by an insert,
411
419
* preallocate an entry.
412
420
*/
413
- rp = nfsd_reply_cache_alloc ();
414
- spin_lock (& b -> cache_lock );
415
- if (likely (rp )) {
416
- atomic_inc (& num_drc_entries );
417
- drc_mem_usage += sizeof (* rp );
421
+ rp = nfsd_reply_cache_alloc (rqstp , csum );
422
+ if (!rp ) {
423
+ dprintk ("nfsd: unable to allocate DRC entry!\n" );
424
+ return rtn ;
418
425
}
419
426
420
- /* go ahead and prune the cache */
421
- prune_bucket (b );
422
-
423
- found = nfsd_cache_search (b , rqstp , csum );
424
- if (found ) {
425
- if (likely (rp ))
426
- nfsd_reply_cache_free_locked (rp );
427
+ spin_lock (& b -> cache_lock );
428
+ found = nfsd_cache_insert (b , rp );
429
+ if (found != rp ) {
430
+ nfsd_reply_cache_free_locked (rp );
427
431
rp = found ;
428
432
goto found_entry ;
429
433
}
430
434
431
- if (!rp ) {
432
- dprintk ("nfsd: unable to allocate DRC entry!\n" );
433
- goto out ;
434
- }
435
-
436
435
nfsdstats .rcmisses ++ ;
437
436
rqstp -> rq_cacherep = rp ;
438
437
rp -> c_state = RC_INPROG ;
439
- rp -> c_xid = xid ;
440
- rp -> c_proc = proc ;
441
- rpc_copy_addr ((struct sockaddr * )& rp -> c_addr , svc_addr (rqstp ));
442
- rpc_set_port ((struct sockaddr * )& rp -> c_addr , rpc_get_port (svc_addr (rqstp )));
443
- rp -> c_prot = proto ;
444
- rp -> c_vers = vers ;
445
- rp -> c_len = rqstp -> rq_arg .len ;
446
- rp -> c_csum = csum ;
447
438
448
- lru_put_end (b , rp );
439
+ atomic_inc (& num_drc_entries );
440
+ drc_mem_usage += sizeof (* rp );
441
+
442
+ /* go ahead and prune the cache */
443
+ prune_bucket (b );
449
444
out :
450
445
spin_unlock (& b -> cache_lock );
451
446
return rtn ;
452
447
453
448
found_entry :
454
- nfsdstats .rchits ++ ;
455
449
/* We found a matching entry which is either in progress or done. */
456
- lru_put_end (b , rp );
457
-
450
+ nfsdstats .rchits ++ ;
458
451
rtn = RC_DROPIT ;
452
+
459
453
/* Request being processed */
460
454
if (rp -> c_state == RC_INPROG )
461
455
goto out ;
0 commit comments