diff -urNp x-ref/fs/nfsd/nfscache.c x/fs/nfsd/nfscache.c --- x-ref/fs/nfsd/nfscache.c 2002-11-29 02:23:16.000000000 +0100 +++ x/fs/nfsd/nfscache.c 2002-12-02 18:46:47.000000000 +0100 @@ -39,6 +39,7 @@ static struct svc_cacherep * lru_head; static struct svc_cacherep * lru_tail; static struct svc_cacherep * nfscache; static int cache_disabled = 1; +static spinlock_t cache_lock = SPIN_LOCK_UNLOCKED; static int nfsd_cache_append(struct svc_rqst *rqstp, struct svc_buf *data); @@ -178,6 +179,8 @@ nfsd_cache_lookup(struct svc_rqst *rqstp return RC_DOIT; } + spin_lock(&cache_lock); + rp = rh = (struct svc_cacherep *) &hash_list[REQHASH(xid)]; while ((rp = rp->c_hash_next) != rh) { if (rp->c_state != RC_UNUSED && @@ -185,6 +188,8 @@ nfsd_cache_lookup(struct svc_rqst *rqstp proto == rp->c_prot && vers == rp->c_vers && time_before(jiffies, rp->c_timestamp + 120*HZ) && memcmp((char*)&rqstp->rq_addr, (char*)&rp->c_addr, sizeof(rp->c_addr))==0) { + lru_put_front(rp); + spin_unlock(&cache_lock); nfsdstats.rchits++; goto found_entry; } @@ -200,6 +205,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp if (safe++ > CACHESIZE) { printk("nfsd: loop in repcache LRU list\n"); cache_disabled = 1; + spin_unlock(&cache_lock); return RC_DOIT; } } @@ -214,6 +220,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp printk(KERN_WARNING "nfsd: disabling repcache.\n"); cache_disabled = 1; } + spin_unlock(&cache_lock); return RC_DOIT; } @@ -227,6 +234,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp rp->c_timestamp = jiffies; hash_refile(rp); + spin_unlock(&cache_lock); /* release any buffer */ if (rp->c_type == RC_REPLBUFF) { @@ -241,7 +249,6 @@ found_entry: /* We found a matching entry which is either in progress or done. */ age = jiffies - rp->c_timestamp; rp->c_timestamp = jiffies; - lru_put_front(rp); /* Request being processed or excessive rexmits */ if (rp->c_state == RC_INPROG || age < RC_DELAY) @@ -324,11 +331,13 @@ nfsd_cache_update(struct svc_rqst *rqstp break; } + spin_lock(&cache_lock); lru_put_front(rp); rp->c_secure = rqstp->rq_secure; rp->c_type = cachetype; rp->c_state = RC_DONE; rp->c_timestamp = jiffies; + spin_unlock(&cache_lock); return; }