nfsd: when updating an entry with RC_NOCACHE, just free it
authorJeff Layton <jlayton@redhat.com>
Mon, 4 Feb 2013 13:18:04 +0000 (08:18 -0500)
committerJ. Bruce Fields <bfields@redhat.com>
Mon, 4 Feb 2013 22:19:11 +0000 (17:19 -0500)
There's no need to keep entries around that we're declaring RC_NOCACHE.
Ditto if there's a problem with the entry.

With this change too, there's no need to test for RC_UNUSED in the
search function. If the entry's in the hash table then it's either
INPROG or DONE.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/nfsd/nfscache.c

index 69d29d4ea579ff225841d9c367951b4df4023026..e8ea785e295ded2bb730b8ae8f76795a5ed612e5 100644 (file)
@@ -98,6 +98,14 @@ nfsd_reply_cache_free_locked(struct svc_cacherep *rp)
        kmem_cache_free(drc_slab, rp);
 }
 
+static void
+nfsd_reply_cache_free(struct svc_cacherep *rp)
+{
+       spin_lock(&cache_lock);
+       nfsd_reply_cache_free_locked(rp);
+       spin_unlock(&cache_lock);
+}
+
 int nfsd_reply_cache_init(void)
 {
        drc_slab = kmem_cache_create("nfsd_drc", sizeof(struct svc_cacherep),
@@ -182,8 +190,7 @@ nfsd_cache_search(struct svc_rqst *rqstp)
 
        rh = &cache_hash[request_hash(xid)];
        hlist_for_each_entry(rp, hn, rh, c_hash) {
-               if (rp->c_state != RC_UNUSED &&
-                   xid == rp->c_xid && proc == rp->c_proc &&
+               if (xid == rp->c_xid && proc == rp->c_proc &&
                    proto == rp->c_prot && vers == rp->c_vers &&
                    !nfsd_cache_entry_expired(rp) &&
                    rpc_cmp_addr(svc_addr(rqstp), (struct sockaddr *)&rp->c_addr) &&
@@ -353,7 +360,7 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp)
 
        /* Don't cache excessive amounts of data and XDR failures */
        if (!statp || len > (256 >> 2)) {
-               rp->c_state = RC_UNUSED;
+               nfsd_reply_cache_free(rp);
                return;
        }
 
@@ -367,12 +374,15 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp)
                cachv = &rp->c_replvec;
                cachv->iov_base = kmalloc(len << 2, GFP_KERNEL);
                if (!cachv->iov_base) {
-                       rp->c_state = RC_UNUSED;
+                       nfsd_reply_cache_free(rp);
                        return;
                }
                cachv->iov_len = len << 2;
                memcpy(cachv->iov_base, statp, len << 2);
                break;
+       case RC_NOCACHE:
+               nfsd_reply_cache_free(rp);
+               return;
        }
        spin_lock(&cache_lock);
        lru_put_end(rp);