From: Klas Lindfors Date: Wed, 25 May 2005 00:06:43 +0000 (+0000) Subject: make-clearcallback-faster-20050524 X-Git-Tag: openafs-devel-1_5_0~550 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=57150405dac2e8ba5b815e880107dda7c48cbd58 make-clearcallback-faster-20050524 FIXES 4413 hash callbacks twice so we can discard them more quickly. --- diff --git a/src/afs/afs.h b/src/afs/afs.h index 0205b75..25a49ad 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -620,6 +620,7 @@ struct vcache { struct afs_q vlruq; /* lru q next and prev */ struct vcache *nextfree; /* next on free list (if free) */ struct vcache *hnext; /* Hash next */ + struct vcache *vhnext; /* vol hash next */ struct VenusFid fid; struct mstat { afs_size_t Length; @@ -1065,6 +1066,8 @@ struct memCacheEntry { /* don't hash on the cell, our callback-breaking code sometimes fails to compute the cell correctly, and only scans one hash bucket */ #define VCHash(fid) (((fid)->Fid.Volume + (fid)->Fid.Vnode) & (VCSIZE-1)) +/* Hash only on volume to speed up volume callbacks. */ +#define VCHashV(fid) ((fid)->Fid.Volume & (VCSIZE-1)) extern struct dcache **afs_indexTable; /*Pointers to in-memory dcache entries */ extern afs_int32 *afs_indexUnique; /*dcache entry Fid.Unique */ @@ -1074,6 +1077,7 @@ extern afs_int32 afs_cacheFiles; /*Size of afs_indexTable */ extern afs_int32 afs_cacheBlocks; /*1K blocks in cache */ extern afs_int32 afs_cacheStats; /*Stat entries in cache */ extern struct vcache *afs_vhashT[VCSIZE]; /*Stat cache hash table */ +extern struct vcache *afs_vhashTV[VCSIZE]; /* cache hash table on volume */ extern afs_int32 afs_initState; /*Initialization state */ extern afs_int32 afs_termState; /* Termination state */ extern struct VenusFid afs_rootFid; /*Root for whole file system */ diff --git a/src/afs/afs_callback.c b/src/afs/afs_callback.c index bc044c2..05885e5 100644 --- a/src/afs/afs_callback.c +++ b/src/afs/afs_callback.c @@ -388,8 +388,8 @@ ClearCallBack(register struct rx_connection *a_conn, * Clear callback for the whole volume. Zip through the * hash chain, nullifying entries whose volume ID matches. */ - for (i = 0; i < VCSIZE; i++) - for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) { + i = VCHashV(&localFid); + for (tvc = afs_vhashTV[i]; tvc; tvc = tvc->vhnext) { if (tvc->fid.Fid.Volume == a_fid->Volume) { tvc->callback = NULL; tvc->quick.stamp = 0; diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index 18e02d5..c298e8e 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -2543,8 +2543,8 @@ DECL_PIOCTL(PFlushVolumeData) * the vcaches associated with the volume. */ ObtainReadLock(&afs_xvcache); - for (i = 0; i < VCSIZE; i++) { - for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) { + i = VCHashV(&avc->fid); + for (tvc = afs_vhashT[i]; tvc; tvc = tvc->vhnext) { if (tvc->fid.Fid.Volume == volume && tvc->fid.Cell == cell) { #if defined(AFS_SGI_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV) VN_HOLD(AFSTOV(tvc)); @@ -2577,7 +2577,6 @@ DECL_PIOCTL(PFlushVolumeData) AFS_FAST_RELE(tvc); } } - } ReleaseReadLock(&afs_xvcache); diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index 820de02..3dc65f4 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -69,6 +69,7 @@ struct afs_q VLRU; /*vcache LRU */ afs_int32 vcachegen = 0; unsigned int afs_paniconwarn = 0; struct vcache *afs_vhashT[VCSIZE]; +struct vcache *afs_vhashTV[VCSIZE]; static struct afs_cbr *afs_cbrHashT[CBRSIZE]; afs_int32 afs_bulkStatsLost; int afs_norefpanic = 0; @@ -129,8 +130,8 @@ int afs_FlushVCache(struct vcache *avc, int *slept) { /*afs_FlushVCache */ - register afs_int32 i, code; - register struct vcache **uvc, *wvc; + afs_int32 i, code, j; + struct vcache **uvc, *wvc, **uvc2, *wvc2; *slept = 0; AFS_STATCNT(afs_FlushVCache); @@ -174,7 +175,18 @@ afs_FlushVCache(struct vcache *avc, int *slept) break; } } - if (!wvc) + + /* remove entry from the volume hash table */ + j = VCHashV(&avc->fid); + uvc2 = &afs_vhashTV[j]; + for (wvc2 = *uvc2; wvc2; uvc2 = &wvc2->vhnext, wvc2 = *uvc2) { + if (avc == wvc2) { + *uvc2 = avc->vhnext; + avc->vhnext = (struct vcache *)NULL; + break; + } + } + if (!wvc || !wvc2) osi_Panic("flushvcache"); /* not in correct hash bucket */ if (avc->mvid) osi_FreeSmallSpace(avc->mvid); @@ -576,7 +588,7 @@ struct vcache * afs_NewVCache(struct VenusFid *afid, struct server *serverp) { struct vcache *tvc; - afs_int32 i; + afs_int32 i, j; afs_int32 anumber = VCACHE_FREE; #ifdef AFS_AIX_ENV struct gnode *gnodepnt; @@ -1074,9 +1086,12 @@ restart: memset((char *)&(tvc->callsort), 0, sizeof(struct afs_q)); tvc->slocks = NULL; i = VCHash(afid); + j = VCHashV(afid); tvc->hnext = afs_vhashT[i]; - afs_vhashT[i] = tvc; + tvc->vhnext = afs_vhashTV[j]; + afs_vhashT[i] = afs_vhashTV[j] = tvc; + if ((VLRU.next->prev != &VLRU) || (VLRU.prev->next != &VLRU)) { refpanic("NewVCache VLRU inconsistent"); } @@ -2861,7 +2876,7 @@ shutdown_vcache(void) afs_FreeAllAxs(&(tvc->Access)); } - afs_vhashT[i] = 0; + afs_vhashT[i] = afs_vhashTV[i] = 0; } } /*