From f9cc51fb40f1797b72ba5b05d7d0249b9a3b2e27 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Thu, 13 Mar 2008 04:37:44 +0000 Subject: [PATCH] windows-remove-scache-volp-20080312 LICENSE MIT The cm_scache structure has included a reference to the associated cm_volume_t, volp. By doing so the reference count on the cm_volume_t objects never hits zero unless all of the cm_scache_t objects in that volume have been reused. This prevents cm_volume object recycling. This commit removes the hard reference and instead adds a function cm_GetVolumeByFID which obtains a reference to the cm_volume that matches the cm_scache fid value as needed. A new "Volumes" registry value is added to permit explicit specification of the number of volume objects to be allocated. --- src/WINNT/afsd/afsd_init.c | 21 +++++++-- src/WINNT/afsd/cm.h | 2 +- src/WINNT/afsd/cm_callback.c | 102 ++++++++++++++++++++++++++-------------- src/WINNT/afsd/cm_conn.c | 10 ++-- src/WINNT/afsd/cm_ioctl.c | 10 ++-- src/WINNT/afsd/cm_performance.c | 2 +- src/WINNT/afsd/cm_scache.c | 46 +++++------------- src/WINNT/afsd/cm_scache.h | 3 -- src/WINNT/afsd/cm_server.c | 16 +++---- src/WINNT/afsd/cm_vnodeops.c | 8 ++-- src/WINNT/afsd/cm_volstat.c | 8 +++- src/WINNT/afsd/cm_volume.c | 56 ++++++++++++++++------ src/WINNT/afsd/cm_volume.h | 6 ++- 13 files changed, 173 insertions(+), 117 deletions(-) diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index 1344c20..7e640e6 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -553,6 +553,7 @@ int afsd_InitCM(char **reasonP) DWORD blockSize; long logChunkSize; DWORD stats; + DWORD volumes; DWORD dwValue; DWORD rx_enable_peer_stats; DWORD rx_enable_process_stats; @@ -771,10 +772,20 @@ int afsd_InitCM(char **reasonP) code = RegQueryValueEx(parmKey, "Stats", NULL, NULL, (BYTE *) &stats, &dummyLen); if (code == ERROR_SUCCESS) - afsi_log("Status cache size %d", stats); + afsi_log("Status cache entries: %d", stats); else { stats = CM_CONFIGDEFAULT_STATS; - afsi_log("Default status cache size %d", stats); + afsi_log("Default status cache entries: %d", stats); + } + + dummyLen = sizeof(volumes); + code = RegQueryValueEx(parmKey, "Volumess", NULL, NULL, + (BYTE *) &volumes, &dummyLen); + if (code == ERROR_SUCCESS) + afsi_log("Volumes cache entries: %d", volumes); + else { + volumes = CM_CONFIGDEFAULT_STATS / 3; + afsi_log("Default volume cache entries: %d", volumes); } dummyLen = sizeof(ltt); @@ -1198,7 +1209,7 @@ int afsd_InitCM(char **reasonP) cm_initParams.nChunkFiles = 0; cm_initParams.nStatCaches = stats; cm_initParams.nDataCaches = (afs_uint32)(cacheBlocks > 0xFFFFFFFF ? 0xFFFFFFFF : cacheBlocks); - cm_initParams.nVolumeCaches = stats/2; + cm_initParams.nVolumeCaches = volumes; cm_initParams.firstChunkSize = cm_chunkSize; cm_initParams.otherChunkSize = cm_chunkSize; cm_initParams.cacheSize = cacheSize; @@ -1345,9 +1356,9 @@ int afsd_InitDaemons(char **reasonP) osi_Log0(afsd_logp, "Loading Root Volume from cell"); do { - code = cm_GetVolumeByName(cm_data.rootCellp, cm_rootVolumeName, cm_rootUserp, + code = cm_FindVolumeByName(cm_data.rootCellp, cm_rootVolumeName, cm_rootUserp, &req, CM_GETVOL_FLAG_CREATE, &cm_data.rootVolumep); - afsi_log("cm_GetVolumeByName code %x root vol %x", code, + afsi_log("cm_FindVolumeByName code %x root vol %x", code, (code ? (cm_volume_t *)-1 : cm_data.rootVolumep)); } while (code && --attempts); if (code != 0) { diff --git a/src/WINNT/afsd/cm.h b/src/WINNT/afsd/cm.h index 3b3161a..14e1c91 100644 --- a/src/WINNT/afsd/cm.h +++ b/src/WINNT/afsd/cm.h @@ -93,7 +93,7 @@ #define CM_ERROR_NOSUCHDEVICE (CM_ERROR_BASE+58) #define CM_ERROR_LOCK_NOT_GRANTED (CM_ERROR_BASE+59) -/* Used by cm_FollowMountPoint and cm_GetVolumeByName */ +/* Used by cm_FollowMountPoint and cm_FindVolumeByName */ #define RWVOL 0 #define ROVOL 1 #define BACKVOL 2 diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index 7a960dc..2964067 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -262,11 +262,13 @@ void cm_RevokeVolumeCallback(struct rx_call *callp, cm_cell_t *cellp, AFSFid *fi cm_CallbackNotifyChange(scp); lock_ObtainWrite(&cm_scacheLock); cm_ReleaseSCacheNoLock(scp); - - if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp) { - scp->volp->cbExpiresRO = 0; + if (scp->flags & CM_SCACHEFLAG_PURERO) { + cm_volume_t *volp = cm_GetVolumeByFID(&scp->fid); + if (volp) { + volp->cbExpiresRO = 0; + cm_PutVolume(volp); + } } - } } /* search one hash bucket */ } /* search all hash buckets */ @@ -488,8 +490,14 @@ SRXAFSCB_InitCallBackState(struct rx_call *callp) lock_ObtainWrite(&cm_scacheLock); cm_ReleaseSCacheNoLock(scp); - if (discarded && (scp->flags & CM_SCACHEFLAG_PURERO) && scp->volp && scp->volp->cbExpiresRO != 0) - scp->volp->cbExpiresRO = 0; + if (discarded && (scp->flags & CM_SCACHEFLAG_PURERO)) { + cm_volume_t *volp = cm_GetVolumeByFID(&scp->fid); + if (volp) { + if (volp->cbExpiresRO != 0) + volp->cbExpiresRO = 0; + cm_PutVolume(volp); + } + } } /* search one hash bucket */ } /* search all hash buckets */ @@ -740,9 +748,13 @@ SRXAFSCB_GetCE(struct rx_call *callp, long index, AFSDBCacheEntry *cep) cep->Length = scp->length.LowPart; cep->DataVersion = (afs_uint32)(scp->dataVersion & 0xFFFFFFFF); cep->callback = afs_data_pointer_to_int32(scp->cbServerp); - if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp) - cep->cbExpires = scp->volp->cbExpiresRO; - else + if (scp->flags & CM_SCACHEFLAG_PURERO) { + cm_volume_t *volp = cm_GetVolumeByFID(&scp->fid); + if (volp) { + cep->cbExpires = volp->cbExpiresRO; + cm_PutVolume(volp); + } + } else cep->cbExpires = scp->cbExpires; cep->refCount = scp->refCount; cep->opens = scp->openReads; @@ -851,9 +863,13 @@ SRXAFSCB_GetCE64(struct rx_call *callp, long index, AFSDBCacheEntry64 *cep) #endif cep->DataVersion = (afs_uint32)(scp->dataVersion & 0xFFFFFFFF); cep->callback = afs_data_pointer_to_int32(scp->cbServerp); - if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp) - cep->cbExpires = scp->volp->cbExpiresRO; - else + if (scp->flags & CM_SCACHEFLAG_PURERO) { + cm_volume_t *volp = cm_GetVolumeByFID(&scp->fid); + if (volp) { + cep->cbExpires = volp->cbExpiresRO; + cm_PutVolume(volp); + } + } else cep->cbExpires = scp->cbExpires; cep->refCount = scp->refCount; cep->opens = scp->openReads; @@ -1486,17 +1502,22 @@ int cm_HaveCallback(cm_scache_t *scp) if (scp->cbServerp != NULL) { return 1; } else if (cm_OfflineROIsValid) { - switch (cm_GetVolumeStatus(scp->volp, scp->fid.volume)) { - case vl_offline: - case vl_alldown: - case vl_unknown: - return 1; - default: - return 0; + cm_volume_t *volp = cm_GetVolumeByFID(&scp->fid); + if (volp) { + switch (cm_GetVolumeStatus(volp, scp->fid.volume)) { + case vl_offline: + case vl_alldown: + case vl_unknown: + cm_PutVolume(volp); + return 1; + default: + cm_PutVolume(volp); + return 0; + } } - } else { - return 0; + return 1; } + return 0; } /* need to detect a broken callback that races with our obtaining a callback. @@ -1570,8 +1591,13 @@ void cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp, serverp = cbrp->serverp; } scp->cbExpires = cbrp->startTime + cbp->ExpirationTime; - if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp) - scp->volp->cbExpiresRO = scp->cbExpires; + if (scp->flags & CM_SCACHEFLAG_PURERO) { + cm_volume_t * volp = cm_GetVolumeByFID(&scp->fid); + if (volp) { + volp->cbExpiresRO = scp->cbExpires; + cm_PutVolume(volp); + } + } } else { if (freeFlag) serverp = cbrp->serverp; @@ -1609,10 +1635,14 @@ void cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp, cbrp->callbackCount, revp->callbackCount, cm_callbackCount); discardScp = 1; - - if ((scp->flags & CM_SCACHEFLAG_PURERO) && scp->volp && - (revp->flags & (CM_RACINGFLAG_CANCELVOL | CM_RACINGFLAG_CANCELALL))) - scp->volp->cbExpiresRO = 0; + if ((scp->flags & CM_SCACHEFLAG_PURERO) && + (revp->flags & (CM_RACINGFLAG_CANCELVOL | CM_RACINGFLAG_CANCELALL))) { + cm_volume_t *volp = cm_GetVolumeByFID(&scp->fid); + if (volp) { + volp->cbExpiresRO = 0; + cm_PutVolume(volp); + } + } } if (freeFlag) free(revp); @@ -1775,7 +1805,7 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp, long cm_CBServersUp(cm_scache_t *scp, time_t * downTime) { cm_vol_state_t *statep; - cm_volume_t * volp = scp->volp; + cm_volume_t * volp; afs_uint32 volID = scp->fid.volume; cm_serverRef_t *tsrp; int found; @@ -1785,6 +1815,7 @@ long cm_CBServersUp(cm_scache_t *scp, time_t * downTime) if (scp->cbServerp == NULL) return 1; + volp = cm_GetVolumeByFID(&scp->fid); if (volp->rw.ID == volID) { statep = &volp->rw; } else if (volp->ro.ID == volID) { @@ -1792,7 +1823,7 @@ long cm_CBServersUp(cm_scache_t *scp, time_t * downTime) } else if (volp->bk.ID == volID) { statep = &volp->bk; } - + cm_PutVolume(volp); if (statep->state == vl_online) return 1; @@ -1824,11 +1855,14 @@ void cm_CheckCBExpiration(void) for (i=0; inextp) { downTime = 0; - if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp) { - if (scp->volp->cbExpiresRO > scp->cbExpires && scp->cbExpires > 0) - scp->cbExpires = scp->volp->cbExpiresRO; + if (scp->flags & CM_SCACHEFLAG_PURERO) { + cm_volume_t *volp = cm_GetVolumeByFID(&scp->fid); + if (volp) { + if (volp->cbExpiresRO > scp->cbExpires && scp->cbExpires > 0) + scp->cbExpires = volp->cbExpiresRO; + cm_PutVolume(volp); + } } - if (scp->cbServerp && scp->cbExpires > 0 && now > scp->cbExpires && (cm_CBServersUp(scp, &downTime) || downTime == 0 || downTime >= scp->cbExpires)) { @@ -1891,7 +1925,7 @@ cm_GiveUpAllCallbacks(cm_server_t *tsp, afs_int32 markDown) cm_InitReq(&req); - code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, + code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE | CM_GETVOL_FLAG_NO_RESET, &volp); if (code == 0) { cm_UpdateVolumeStatus(volp, tsrvp->ids[i]); diff --git a/src/WINNT/afsd/cm_conn.c b/src/WINNT/afsd/cm_conn.c index c52789f..017724e 100644 --- a/src/WINNT/afsd/cm_conn.c +++ b/src/WINNT/afsd/cm_conn.c @@ -121,7 +121,7 @@ static long cm_GetServerList(struct cm_fid *fidp, struct cm_user *userp, if (!cellp) return CM_ERROR_NOSUCHCELL; - code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, CM_GETVOL_FLAG_CREATE, &volp); + code = cm_FindVolumeByID(cellp, fidp->volume, userp, reqp, CM_GETVOL_FLAG_CREATE, &volp); if (code) return code; @@ -273,7 +273,7 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, if (timeLeft > 7 && fidp) { thrd_Sleep(5000); - code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, + code = cm_FindVolumeByID(cellp, fidp->volume, userp, reqp, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp); if (code == 0) { @@ -305,7 +305,7 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, thrd_Sleep(5000); if (fidp) { /* File Server query */ - code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, + code = cm_FindVolumeByID(cellp, fidp->volume, userp, reqp, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp); if (code == 0) { @@ -375,7 +375,7 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, if (tsrp->server == serverp && tsrp->status == srv_not_busy) { tsrp->status = srv_busy; if (fidp) { /* File Server query */ - code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, + code = cm_FindVolumeByID(cellp, fidp->volume, userp, reqp, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp); if (code == 0) { @@ -470,7 +470,7 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, } if (fidp) { /* File Server query */ - code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, + code = cm_FindVolumeByID(cellp, fidp->volume, userp, reqp, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp); if (code == 0) { diff --git a/src/WINNT/afsd/cm_ioctl.c b/src/WINNT/afsd/cm_ioctl.c index 57be519..a40dea4 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -886,7 +886,7 @@ long cm_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp) return CM_ERROR_READONLY; } - code = cm_GetVolumeByID(cellp, scp->fid.volume, userp, &req, + code = cm_FindVolumeByID(cellp, scp->fid.volume, userp, &req, CM_GETVOL_FLAG_CREATE, &tvp); if (code) { cm_ReleaseSCache(scp); @@ -1212,7 +1212,7 @@ long cm_IoctlWhereIs(struct smb_ioctl *ioctlp, struct cm_user *userp) } else #endif { - code = cm_GetVolumeByID(cellp, volume, userp, &req, CM_GETVOL_FLAG_CREATE, &tvp); + code = cm_FindVolumeByID(cellp, volume, userp, &req, CM_GETVOL_FLAG_CREATE, &tvp); if (code) return code; @@ -3111,7 +3111,7 @@ long cm_IoctlPathAvailability(struct smb_ioctl *ioctlp, struct cm_user *userp) if (!cellp) return CM_ERROR_NOSUCHCELL; - code = cm_GetVolumeByID(cellp, volume, userp, &req, CM_GETVOL_FLAG_CREATE, &tvp); + code = cm_FindVolumeByID(cellp, volume, userp, &req, CM_GETVOL_FLAG_CREATE, &tvp); if (code) return code; @@ -3207,11 +3207,11 @@ long cm_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp) if (n) testp->fid.volume = n; else - code = cm_GetVolumeByName(cellp, testp->volname, userp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp); + code = cm_FindVolumeByName(cellp, testp->volname, userp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp); } if (testp->fid.volume > 0) - code = cm_GetVolumeByID(cellp, testp->fid.volume, userp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp); + code = cm_FindVolumeByID(cellp, testp->fid.volume, userp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp); if (code) return code; diff --git a/src/WINNT/afsd/cm_performance.c b/src/WINNT/afsd/cm_performance.c index ef404cc..fd11270 100644 --- a/src/WINNT/afsd/cm_performance.c +++ b/src/WINNT/afsd/cm_performance.c @@ -124,7 +124,7 @@ void cm_PerformanceAddSCache(cm_scache_t *scp) cellp = cm_FindCellByID(statp->fid.cell, 0); if (cellp) { - if (!cm_GetVolumeByID(cellp, statp->fid.volume, cm_rootUserp, &req, 0, &volp)) { + if (!cm_FindVolumeByID(cellp, statp->fid.volume, cm_rootUserp, &req, 0, &volp)) { statp->flags |= CM_FIDSTATS_HAVE_VOLUME; cm_PutVolume(volp); } diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index 403776e..7966b0b 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -189,12 +189,6 @@ long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags) * tried to store this to server but failed */ scp->mask = 0; - /* drop held volume ref */ - if (scp->volp) { - cm_PutVolume(scp->volp); - scp->volp = NULL; - } - /* discard symlink info */ scp->mountPointStringp[0] = '\0'; memset(&scp->mountRootFid, 0, sizeof(cm_fid_t)); @@ -408,11 +402,6 @@ cm_ValidateSCache(void) fprintf(stderr, "cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC\n"); return -3; } - if (scp->volp && scp->volp->magic != CM_VOLUME_MAGIC) { - afsi_log("cm_ValidateSCache failure: scp->volp->magic != CM_VOLUME_MAGIC"); - fprintf(stderr, "cm_ValidateSCache failure: scp->volp->magic != CM_VOLUME_MAGIC\n"); - return -4; - } if (i > cm_data.currentSCaches ) { afsi_log("cm_ValidateSCache failure: LRU First queue loops"); fprintf(stderr, "cm_ValidateSCache failure: LUR First queue loops\n"); @@ -442,11 +431,6 @@ cm_ValidateSCache(void) fprintf(stderr, "cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC\n"); return -7; } - if (scp->volp && scp->volp->magic != CM_VOLUME_MAGIC) { - afsi_log("cm_ValidateSCache failure: scp->volp->magic != CM_VOLUME_MAGIC"); - fprintf(stderr, "cm_ValidateSCache failure: scp->volp->magic != CM_VOLUME_MAGIC\n"); - return -8; - } if (i > cm_data.currentSCaches ) { afsi_log("cm_ValidateSCache failure: LRU Last queue loops"); fprintf(stderr, "cm_ValidateSCache failure: LUR Last queue loops\n"); @@ -478,11 +462,6 @@ cm_ValidateSCache(void) fprintf(stderr, "cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC\n"); return -11; } - if (scp->volp && scp->volp->magic != CM_VOLUME_MAGIC) { - afsi_log("cm_ValidateSCache failure: scp->volp->magic != CM_VOLUME_MAGIC"); - fprintf(stderr, "cm_ValidateSCache failure: scp->volp->magic != CM_VOLUME_MAGIC\n"); - return -12; - } if (hash != i) { afsi_log("cm_ValidateSCache failure: scp hash != hash index"); fprintf(stderr, "cm_ValidateSCache failure: scp hash != hash index\n"); @@ -517,9 +496,12 @@ cm_SuspendSCache(void) lock_ObtainWrite(&cm_scacheLock); for ( scp = cm_data.allSCachesp; scp; scp = scp->allNextp ) { if (scp->cbServerp) { - if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp) { - if (scp->volp->cbExpiresRO == scp->cbExpires) { - scp->volp->cbExpiresRO = now+1; + if (scp->flags & CM_SCACHEFLAG_PURERO) { + cm_volume_t *volp = cm_GetVolumeByFID(&scp->fid); + if (volp) { + if (volp->cbExpiresRO == scp->cbExpires) + volp->cbExpiresRO = now+1; + cm_PutVolume(volp); } } scp->cbExpires = now+1; @@ -751,9 +733,6 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp, lock_ObtainWrite(&cm_scacheLock); #endif scp->fid = *fidp; - scp->volp = cm_data.rootSCachep->volp; - if (scp->volp) - cm_GetVolume(scp->volp); /* grab an additional reference */ scp->dotdotFid.cell=AFS_FAKE_ROOT_CELL_ID; scp->dotdotFid.volume=AFS_FAKE_ROOT_VOL_ID; scp->dotdotFid.unique=1; @@ -799,7 +778,7 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp, if (!cellp) return CM_ERROR_NOSUCHCELL; - code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, CM_GETVOL_FLAG_CREATE, &volp); + code = cm_FindVolumeByID(cellp, fidp->volume, userp, reqp, CM_GETVOL_FLAG_CREATE, &volp); if (code) return code; lock_ObtainWrite(&cm_scacheLock); @@ -815,7 +794,6 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp, osi_Log1(afsd_logp,"cm_GetSCache (3) outScpp 0x%p", scp); #endif cm_HoldSCacheNoLock(scp); - osi_assertx(scp->volp == volp, "cm_scache_t volume has unexpected value"); cm_AdjustScacheLRU(scp); lock_ReleaseWrite(&cm_scacheLock); if (volp) @@ -849,8 +827,6 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp, lock_ObtainWrite(&cm_scacheLock); #endif scp->fid = *fidp; - scp->volp = volp; /* a held reference */ - if (!cm_freelanceEnabled || !isRoot) { /* if this scache entry represents a volume root then we need * to copy the dotdotFipd from the volume structure where the @@ -865,6 +841,8 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp, else if (volp->bk.ID == fidp->volume) scp->flags |= CM_SCACHEFLAG_RO; } + if (volp) + cm_PutVolume(volp); scp->nextp = cm_data.scacheHashTablep[hash]; cm_data.scacheHashTablep[hash] = scp; scp->flags |= CM_SCACHEFLAG_INHASH; @@ -1576,7 +1554,7 @@ void cm_MergeStatus(cm_scache_t *dscp, if (scp->cbServerp) { struct cm_volume *volp = NULL; - cm_GetVolumeByID(cellp, scp->fid.volume, userp, + cm_FindVolumeByID(cellp, scp->fid.volume, userp, (cm_req_t *) NULL, CM_GETVOL_FLAG_CREATE, &volp); osi_Log2(afsd_logp, "old data from server %x volume %s", scp->cbServerp->addr.sin_addr.s_addr, @@ -1893,9 +1871,9 @@ int cm_DumpSCache(FILE *outputFile, char *cookie, int lock) for (scp = cm_data.allSCachesp; scp; scp = scp->allNextp) { - sprintf(output, "%s scp=0x%p, fid (cell=%d, volume=%d, vnode=%d, unique=%d) volp=0x%p type=%d dv=%I64d len=0x%I64x mp='%s' flags=0x%x cb=0x%x refCount=%u\r\n", + sprintf(output, "%s scp=0x%p, fid (cell=%d, volume=%d, vnode=%d, unique=%d) type=%d dv=%I64d len=0x%I64x mp='%s' flags=0x%x cb=0x%x refCount=%u\r\n", cookie, scp, scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique, - scp->volp, scp->fileType, scp->dataVersion, scp->length.QuadPart, scp->mountPointStringp, scp->flags, + scp->fileType, scp->dataVersion, scp->length.QuadPart, scp->mountPointStringp, scp->flags, (unsigned long)scp->cbExpires, scp->refCount); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); } diff --git a/src/WINNT/afsd/cm_scache.h b/src/WINNT/afsd/cm_scache.h index ce3078e..8e704fc 100644 --- a/src/WINNT/afsd/cm_scache.h +++ b/src/WINNT/afsd/cm_scache.h @@ -186,9 +186,6 @@ typedef struct cm_scache { have CM_FILELOCK_FLAG_CLIENTONLY set. */ - /* volume info */ - struct cm_volume *volp; /* volume info; held reference */ - /* bulk stat progress */ osi_hyper_t bulkStatProgress; /* track bulk stats of large dirs */ diff --git a/src/WINNT/afsd/cm_server.c b/src/WINNT/afsd/cm_server.c index cc990dc..a8b15d1 100644 --- a/src/WINNT/afsd/cm_server.c +++ b/src/WINNT/afsd/cm_server.c @@ -138,7 +138,7 @@ cm_PingServer(cm_server_t *tsp) cm_InitReq(&req); lock_ReleaseMutex(&tsp->mx); - code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, + code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp); lock_ObtainMutex(&tsp->mx); if (code == 0) { @@ -175,7 +175,7 @@ cm_PingServer(cm_server_t *tsp) cm_InitReq(&req); lock_ReleaseMutex(&tsp->mx); - code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, + code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp); lock_ObtainMutex(&tsp->mx); if (code == 0) { @@ -401,7 +401,7 @@ void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp) cm_InitReq(&req); lock_ReleaseMutex(&tsp->mx); - code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, + code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp); lock_ObtainMutex(&tsp->mx); if (code == 0) { @@ -439,7 +439,7 @@ void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp) cm_InitReq(&req); lock_ReleaseMutex(&tsp->mx); - code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, + code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp); lock_ObtainMutex(&tsp->mx); if (code == 0) { @@ -530,7 +530,7 @@ void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp) cm_InitReq(&req); lock_ReleaseMutex(&tsp->mx); - code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, + code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp); lock_ObtainMutex(&tsp->mx); if (code == 0) { @@ -568,7 +568,7 @@ void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp) cm_InitReq(&req); lock_ReleaseMutex(&tsp->mx); - code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, + code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp); lock_ObtainMutex(&tsp->mx); if (code == 0) { @@ -685,7 +685,7 @@ void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp) cm_InitReq(&req); lock_ReleaseMutex(&tsp->mx); - code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, + code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp); lock_ObtainMutex(&tsp->mx); if (code == 0) { @@ -723,7 +723,7 @@ void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp) cm_InitReq(&req); lock_ReleaseMutex(&tsp->mx); - code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, + code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp); lock_ObtainMutex(&tsp->mx); if (code == 0) { diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 76aa2d6..d267f5e 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -1115,10 +1115,10 @@ long cm_FollowMountPoint(cm_scache_t *scp, cm_scache_t *dscp, cm_user_t *userp, /* now we need to get the volume */ lock_ReleaseWrite(&scp->rw); if (cm_VolNameIsID(volNamep)) { - code = cm_GetVolumeByID(cellp, atoi(volNamep), userp, reqp, + code = cm_FindVolumeByID(cellp, atoi(volNamep), userp, reqp, CM_GETVOL_FLAG_CREATE, &volp); } else { - code = cm_GetVolumeByName(cellp, volNamep, userp, reqp, + code = cm_FindVolumeByName(cellp, volNamep, userp, reqp, CM_GETVOL_FLAG_CREATE, &volp); } lock_ObtainWrite(&scp->rw); @@ -1490,10 +1490,10 @@ long cm_EvaluateVolumeReference(char * namep, long flags, cm_user_t * userp, volType = RWVOL; if (cm_VolNameIsID(volumeName)) { - code = cm_GetVolumeByID(cellp, atoi(volumeName), userp, reqp, + code = cm_FindVolumeByID(cellp, atoi(volumeName), userp, reqp, CM_GETVOL_FLAG_CREATE, &volp); } else { - code = cm_GetVolumeByName(cellp, volumeName, userp, reqp, + code = cm_FindVolumeByName(cellp, volumeName, userp, reqp, CM_GETVOL_FLAG_CREATE, &volp); } diff --git a/src/WINNT/afsd/cm_volstat.c b/src/WINNT/afsd/cm_volstat.c index 23e1c94..e90183a 100644 --- a/src/WINNT/afsd/cm_volstat.c +++ b/src/WINNT/afsd/cm_volstat.c @@ -298,6 +298,7 @@ cm_VolStatus_Path_To_ID(const char * share, const char * path, afs_uint32 * cell afs_uint32 code = 0; cm_req_t req; cm_scache_t *scp; + cm_volume_t *volp; if (cellID == NULL || volID == NULL) return CM_ERROR_INVAL; @@ -324,7 +325,12 @@ cm_VolStatus_Path_To_ID(const char * share, const char * path, afs_uint32 * cell *cellID = scp->fid.cell; *volID = scp->fid.volume; - *pstatus = cm_GetVolumeStatus(scp->volp, scp->fid.volume); + volp = cm_GetVolumeByFID(&scp->fid); + if (volp) { + *pstatus = cm_GetVolumeStatus(volp, scp->fid.volume); + cm_PutVolume(volp); + } else + *pstatus = vl_unknown; lock_ReleaseWrite(&scp->rw); cm_ReleaseSCache(scp); diff --git a/src/WINNT/afsd/cm_volume.c b/src/WINNT/afsd/cm_volume.c index fedd8ea..cc9014f 100644 --- a/src/WINNT/afsd/cm_volume.c +++ b/src/WINNT/afsd/cm_volume.c @@ -581,8 +581,45 @@ void cm_GetVolume(cm_volume_t *volp) InterlockedIncrement(&volp->refCount); } +cm_volume_t *cm_GetVolumeByFID(cm_fid_t *fidp) +{ + cm_volume_t *volp; + afs_uint32 hash; + + lock_ObtainRead(&cm_volumeLock); + hash = CM_VOLUME_ID_HASH(fidp->volume); + /* The volumeID can be any one of the three types. So we must + * search the hash table for all three types until we find it. + * We will search in the order of RO, RW, BK. + */ + for ( volp = cm_data.volumeROIDHashTablep[hash]; volp; volp = volp->ro.nextp) { + if ( fidp->cell == volp->cellp->cellID && fidp->volume == volp->ro.ID ) + break; + } + if (!volp) { + /* try RW volumes */ + for ( volp = cm_data.volumeRWIDHashTablep[hash]; volp; volp = volp->rw.nextp) { + if ( fidp->cell == volp->cellp->cellID && fidp->volume == volp->rw.ID ) + break; + } + } + if (!volp) { + /* try BK volumes */ + for ( volp = cm_data.volumeBKIDHashTablep[hash]; volp; volp = volp->bk.nextp) { + if ( fidp->cell == volp->cellp->cellID && fidp->volume == volp->bk.ID ) + break; + } + } -long cm_GetVolumeByID(cm_cell_t *cellp, afs_uint32 volumeID, cm_user_t *userp, + /* hold the volume if we found it */ + if (volp) + cm_GetVolume(volp); + + lock_ReleaseRead(&cm_volumeLock); + return volp; +} + +long cm_FindVolumeByID(cm_cell_t *cellp, afs_uint32 volumeID, cm_user_t *userp, cm_req_t *reqp, afs_uint32 flags, cm_volume_t **outVolpp) { cm_volume_t *volp; @@ -667,13 +704,13 @@ long cm_GetVolumeByID(cm_cell_t *cellp, afs_uint32 volumeID, cm_user_t *userp, /* otherwise, we didn't find it so consult the VLDB */ sprintf(volNameString, "%u", volumeID); - code = cm_GetVolumeByName(cellp, volNameString, userp, reqp, + code = cm_FindVolumeByName(cellp, volNameString, userp, reqp, flags, outVolpp); return code; } -long cm_GetVolumeByName(struct cm_cell *cellp, char *volumeNamep, +long cm_FindVolumeByName(struct cm_cell *cellp, char *volumeNamep, struct cm_user *userp, struct cm_req *reqp, afs_uint32 flags, cm_volume_t **outVolpp) { @@ -1313,19 +1350,10 @@ int cm_DumpVolumes(FILE *outputFile, char *cookie, int lock) for (volp = cm_data.allVolumesp; volp; volp=volp->allNextp) { - cm_scache_t *scp; - int scprefs = 0; - - for (scp = cm_data.allSCachesp; scp; scp = scp->allNextp) - { - if (scp->volp == volp) - scprefs++; - } - - sprintf(output, "%s - volp=0x%p cell=%s name=%s rwID=%u roID=%u bkID=%u flags=0x%x fid (cell=%d, volume=%d, vnode=%d, unique=%d) refCount=%u scpRefs=%u\r\n", + sprintf(output, "%s - volp=0x%p cell=%s name=%s rwID=%u roID=%u bkID=%u flags=0x%x dotdotFid (cell=%d, volume=%d, vnode=%d, unique=%d) refCount=%u\r\n", cookie, volp, volp->cellp->name, volp->namep, volp->rw.ID, volp->ro.ID, volp->bk.ID, volp->flags, volp->dotdotFid.cell, volp->dotdotFid.volume, volp->dotdotFid.vnode, volp->dotdotFid.unique, - volp->refCount, scprefs); + volp->refCount); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); } sprintf(output, "%s - Done dumping volumes.\r\n", cookie); diff --git a/src/WINNT/afsd/cm_volume.h b/src/WINNT/afsd/cm_volume.h index d92582d..40a2e8e 100644 --- a/src/WINNT/afsd/cm_volume.h +++ b/src/WINNT/afsd/cm_volume.h @@ -52,11 +52,11 @@ typedef struct cm_volumeRef { extern void cm_InitVolume(int newFile, long maxVols); -extern long cm_GetVolumeByName(struct cm_cell *cellp, char *volNamep, +extern long cm_FindVolumeByName(struct cm_cell *cellp, char *volNamep, struct cm_user *userp, struct cm_req *reqp, afs_uint32 flags, cm_volume_t **outVolpp); -extern long cm_GetVolumeByID(struct cm_cell *cellp, afs_uint32 volumeID, +extern long cm_FindVolumeByID(struct cm_cell *cellp, afs_uint32 volumeID, cm_user_t *userp, cm_req_t *reqp, afs_uint32 flags, cm_volume_t **outVolpp); @@ -77,6 +77,8 @@ extern afs_uint32 SDBMHash(const char *); extern void cm_GetVolume(cm_volume_t *volp); +extern cm_volume_t *cm_GetVolumeByFID(cm_fid_t *); + extern void cm_PutVolume(cm_volume_t *volp); extern long cm_GetROVolumeID(cm_volume_t *volp); -- 1.9.4