nfsd: Do not refuse to serve out of cache
authorTrond Myklebust <trond.myklebust@primarydata.com>
Wed, 28 Mar 2018 16:18:01 +0000 (12:18 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Fri, 11 May 2018 19:48:57 +0000 (15:48 -0400)
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>
fs/nfsd/cache.h
fs/nfsd/nfscache.c

index 046b3f0..b7559c6 100644 (file)
@@ -67,11 +67,6 @@ enum {
        RC_REPLBUFF,
 };
 
-/*
- * If requests are retransmitted within this interval, they're dropped.
- */
-#define RC_DELAY               (HZ/5)
-
 /* Cache entries expire after this time period */
 #define RC_EXPIRE              (120 * HZ)
 
index 334f2ad..637f87c 100644 (file)
@@ -394,7 +394,6 @@ nfsd_cache_lookup(struct svc_rqst *rqstp)
        __wsum                  csum;
        u32 hash = nfsd_cache_hash(xid);
        struct nfsd_drc_bucket *b = &drc_hashtbl[hash];
-       unsigned long           age;
        int type = rqstp->rq_cachetype;
        int rtn = RC_DOIT;
 
@@ -461,12 +460,11 @@ nfsd_cache_lookup(struct svc_rqst *rqstp)
 found_entry:
        nfsdstats.rchits++;
        /* We found a matching entry which is either in progress or done. */
-       age = jiffies - rp->c_timestamp;
        lru_put_end(b, rp);
 
        rtn = RC_DROPIT;
-       /* Request being processed or excessive rexmits */
-       if (rp->c_state == RC_INPROG || age < RC_DELAY)
+       /* Request being processed */
+       if (rp->c_state == RC_INPROG)
                goto out;
 
        /* From the hall of fame of impractical attacks: