Index: openafs/src/WINNT/afsd/NTMakefile diff -c openafs/src/WINNT/afsd/NTMakefile:1.46.2.4 openafs/src/WINNT/afsd/NTMakefile:1.46.2.5 *** openafs/src/WINNT/afsd/NTMakefile:1.46.2.4 Thu Aug 31 06:29:48 2006 --- openafs/src/WINNT/afsd/NTMakefile Thu Jul 5 15:22:15 2007 *************** *** 52,57 **** --- 52,58 ---- $(INCFILEDIR)\cm_callback.h \ $(INCFILEDIR)\cm_aclent.h \ $(INCFILEDIR)\cm_volume.h \ + $(INCFILEDIR)\cm_volstat.h \ $(INCFILEDIR)\cm_dcache.h \ $(INCFILEDIR)\cm_access.h \ $(INCFILEDIR)\cm_vnodeops.h \ *************** *** 101,106 **** --- 102,108 ---- $(OUT)\cm_cell.obj \ $(OUT)\cm_server.obj \ $(OUT)\cm_volume.obj \ + $(OUT)\cm_volstat.obj \ $(OUT)\cm_config.obj \ $(OUT)\cm_conn.obj \ $(OUT)\cm_user.obj \ Index: openafs/src/WINNT/afsd/afsd.h diff -c openafs/src/WINNT/afsd/afsd.h:1.18.2.1 openafs/src/WINNT/afsd/afsd.h:1.18.2.3 *** openafs/src/WINNT/afsd/afsd.h:1.18.2.1 Mon Feb 26 20:32:09 2007 --- openafs/src/WINNT/afsd/afsd.h Thu Jul 5 15:22:15 2007 *************** *** 40,49 **** #endif /* DISKCACHE95 */ #include "cm_conn.h" #include "cm_aclent.h" - #include "cm_cell.h" #include "cm_server.h" #include "cm_scache.h" #include "cm_volume.h" #include "cm_dcache.h" #include "cm_access.h" #include "cm_utils.h" --- 40,50 ---- #endif /* DISKCACHE95 */ #include "cm_conn.h" #include "cm_aclent.h" #include "cm_server.h" + #include "cm_cell.h" #include "cm_scache.h" #include "cm_volume.h" + #include "cm_volstat.h" #include "cm_dcache.h" #include "cm_access.h" #include "cm_utils.h" Index: openafs/src/WINNT/afsd/afsd_init.c diff -c openafs/src/WINNT/afsd/afsd_init.c:1.79.2.12 openafs/src/WINNT/afsd/afsd_init.c:1.79.2.14 *** openafs/src/WINNT/afsd/afsd_init.c:1.79.2.12 Mon Apr 16 20:06:25 2007 --- openafs/src/WINNT/afsd/afsd_init.c Fri Jun 22 10:12:39 2007 *************** *** 997,1044 **** afsi_log("RX Process Statistics gathering is enabled"); dummyLen = sizeof(DWORD); - code = RegQueryValueEx(parmKey, "daemonCheckDownInterval", NULL, NULL, - (BYTE *) &dwValue, &dummyLen); - if (code == ERROR_SUCCESS) - cm_daemonCheckDownInterval = dwValue; - afsi_log("daemonCheckDownInterval is %d", cm_daemonCheckDownInterval); - - dummyLen = sizeof(DWORD); - code = RegQueryValueEx(parmKey, "daemonCheckUpInterval", NULL, NULL, - (BYTE *) &dwValue, &dummyLen); - if (code == ERROR_SUCCESS) - cm_daemonCheckUpInterval = dwValue; - afsi_log("daemonCheckUpInterval is %d", cm_daemonCheckUpInterval); - - dummyLen = sizeof(DWORD); - code = RegQueryValueEx(parmKey, "daemonCheckVolInterval", NULL, NULL, - (BYTE *) &dwValue, &dummyLen); - if (code == ERROR_SUCCESS) - cm_daemonCheckVolInterval = dwValue; - afsi_log("daemonCheckVolInterval is %d", cm_daemonCheckVolInterval); - - dummyLen = sizeof(DWORD); - code = RegQueryValueEx(parmKey, "daemonCheckCBInterval", NULL, NULL, - (BYTE *) &dwValue, &dummyLen); - if (code == ERROR_SUCCESS) - cm_daemonCheckCBInterval = dwValue; - afsi_log("daemonCheckCBInterval is %d", cm_daemonCheckCBInterval); - - dummyLen = sizeof(DWORD); - code = RegQueryValueEx(parmKey, "daemonCheckLockInterval", NULL, NULL, - (BYTE *) &dwValue, &dummyLen); - if (code == ERROR_SUCCESS) - cm_daemonCheckLockInterval = dwValue; - afsi_log("daemonCheckLockInterval is %d", cm_daemonCheckLockInterval); - - dummyLen = sizeof(DWORD); - code = RegQueryValueEx(parmKey, "daemonCheckTokenInterval", NULL, NULL, - (BYTE *) &dwValue, &dummyLen); - if (code == ERROR_SUCCESS) - cm_daemonTokenCheckInterval = dwValue; - afsi_log("daemonCheckTokenInterval is %d", cm_daemonTokenCheckInterval); - - dummyLen = sizeof(DWORD); code = RegQueryValueEx(parmKey, "CallBackPort", NULL, NULL, (BYTE *) &dwValue, &dummyLen); if (code == ERROR_SUCCESS) { --- 997,1002 ---- *************** *** 1245,1251 **** osi_Log0(afsd_logp, "Loading Root Volume from cell"); do { code = cm_GetVolumeByName(cm_data.rootCellp, cm_rootVolumeName, cm_rootUserp, ! &req, CM_FLAG_CREATE, &cm_data.rootVolumep); afsi_log("cm_GetVolumeByName code %x root vol %x", code, (code ? (cm_volume_t *)-1 : cm_data.rootVolumep)); } while (code && --attempts); --- 1203,1209 ---- osi_Log0(afsd_logp, "Loading Root Volume from cell"); do { code = cm_GetVolumeByName(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, (code ? (cm_volume_t *)-1 : cm_data.rootVolumep)); } while (code && --attempts); Index: openafs/src/WINNT/afsd/afsd_service.c diff -c openafs/src/WINNT/afsd/afsd_service.c:1.52.4.9 openafs/src/WINNT/afsd/afsd_service.c:1.52.4.13 *** openafs/src/WINNT/afsd/afsd_service.c:1.52.4.9 Mon Dec 11 23:01:26 2006 --- openafs/src/WINNT/afsd/afsd_service.c Fri Jul 6 19:22:03 2007 *************** *** 76,81 **** --- 76,83 ---- buf_ForceTrace(TRUE); afsi_log("--- begin dump ---"); + cm_DumpCells(afsi_file, "a", 0); + cm_DumpVolumes(afsi_file, "a", 0); cm_DumpSCache(afsi_file, "a", 0); #ifdef keisa cm_dnlcDump(afsi_file, "a"); *************** *** 85,92 **** afsi_log("--- end dump ---"); #ifdef DEBUG ! if (IsDebuggerPresent()) ! DebugBreak(); #endif SetEvent(WaitToTerminate); --- 87,94 ---- afsi_log("--- end dump ---"); #ifdef DEBUG ! if (IsDebuggerPresent()) ! DebugBreak(); #endif SetEvent(WaitToTerminate); *************** *** 309,324 **** case PBT_APMQUERYSUSPEND: afsi_log("SERVICE_CONTROL_APMQUERYSUSPEND"); /* Write all dirty buffers back to server */ ! if ( !lana_OnlyLoopback() ) buf_CleanAndReset(); afsi_log("SERVICE_CONTROL_APMQUERYSUSPEND buf_CleanAndReset complete"); dwRet = NO_ERROR; break; case PBT_APMQUERYSTANDBY: afsi_log("SERVICE_CONTROL_APMQUERYSTANDBY"); /* Write all dirty buffers back to server */ ! if ( !lana_OnlyLoopback() ) buf_CleanAndReset(); afsi_log("SERVICE_CONTROL_APMQUERYSTANDBY buf_CleanAndReset complete"); dwRet = NO_ERROR; break; --- 311,330 ---- case PBT_APMQUERYSUSPEND: afsi_log("SERVICE_CONTROL_APMQUERYSUSPEND"); /* Write all dirty buffers back to server */ ! if ( !lana_OnlyLoopback() ) { buf_CleanAndReset(); + cm_SuspendSCache(); + } afsi_log("SERVICE_CONTROL_APMQUERYSUSPEND buf_CleanAndReset complete"); dwRet = NO_ERROR; break; case PBT_APMQUERYSTANDBY: afsi_log("SERVICE_CONTROL_APMQUERYSTANDBY"); /* Write all dirty buffers back to server */ ! if ( !lana_OnlyLoopback() ) { buf_CleanAndReset(); + cm_SuspendSCache(); + } afsi_log("SERVICE_CONTROL_APMQUERYSTANDBY buf_CleanAndReset complete"); dwRet = NO_ERROR; break; *************** *** 327,341 **** case PBT_APMSUSPEND: afsi_log("SERVICE_CONTROL_APMSUSPEND"); powerStateSuspended = 1; ! if (osVersion.dwMajorVersion >= 6) smb_StopListeners(); dwRet = NO_ERROR; break; case PBT_APMSTANDBY: afsi_log("SERVICE_CONTROL_APMSTANDBY"); powerStateSuspended = 1; ! if (osVersion.dwMajorVersion >= 6) smb_StopListeners(); dwRet = NO_ERROR; break; case PBT_APMRESUMECRITICAL: --- 333,351 ---- case PBT_APMSUSPEND: afsi_log("SERVICE_CONTROL_APMSUSPEND"); powerStateSuspended = 1; ! if (osVersion.dwMajorVersion >= 6) { ! cm_SuspendSCache(); smb_StopListeners(); + } dwRet = NO_ERROR; break; case PBT_APMSTANDBY: afsi_log("SERVICE_CONTROL_APMSTANDBY"); powerStateSuspended = 1; ! if (osVersion.dwMajorVersion >= 6) { ! cm_SuspendSCache(); smb_StopListeners(); + } dwRet = NO_ERROR; break; case PBT_APMRESUMECRITICAL: *************** *** 1231,1236 **** --- 1241,1249 ---- } } + /* Perform Volume Status Notification Initialization */ + cm_VolStatus_Initialization(); + #ifdef JUMP MainThreadId = GetCurrentThreadId(); jmpret = setjmp(notifier_jmp); *************** *** 1350,1355 **** --- 1363,1371 ---- LogEvent(EVENTLOG_INFORMATION_TYPE, MSG_SERVICE_RUNNING); } + /* Notify any volume status handlers that we have started */ + cm_VolStatus_Service_Started(); + /* allow an exit to be called when started */ hHookDll = LoadLibrary(AFSD_HOOK_DLL); if (hHookDll) *************** *** 1459,1464 **** --- 1475,1486 ---- PowerNotificationThreadExit(); #endif + /* Notify any Volume Status Handlers that we are stopped */ + cm_VolStatus_Service_Stopped(); + + /* Cleanup any Volume Status Notification Handler */ + cm_VolStatus_Finalize(); + /* allow an exit to be called after stopping the service */ hHookDll = LoadLibrary(AFSD_HOOK_DLL); if (hHookDll) Index: openafs/src/WINNT/afsd/cm.h diff -c openafs/src/WINNT/afsd/cm.h:1.17.2.2 openafs/src/WINNT/afsd/cm.h:1.17.2.4 *** openafs/src/WINNT/afsd/cm.h:1.17.2.2 Mon Jan 15 14:52:19 2007 --- openafs/src/WINNT/afsd/cm.h Thu Jul 5 15:22:15 2007 *************** *** 300,303 **** --- 300,309 ---- #define CM_ERROR_TOOFEWBUFS (CM_ERROR_BASE+50) #define CM_ERROR_TOOMANYBUFS (CM_ERROR_BASE+51) #define CM_ERROR_BAD_LEVEL (CM_ERROR_BASE+52) + #define CM_ERROR_NOT_A_DFSLINK (CM_ERROR_BASE+53) + + /* Used by cm_FollowMountPoint and cm_GetVolumeByName */ + #define RWVOL 0 + #define ROVOL 1 + #define BACKVOL 2 #endif /* __CM_H_ENV__ */ Index: openafs/src/WINNT/afsd/cm_buf.c diff -c openafs/src/WINNT/afsd/cm_buf.c:1.31.2.15 openafs/src/WINNT/afsd/cm_buf.c:1.31.2.16 *** openafs/src/WINNT/afsd/cm_buf.c:1.31.2.15 Sun Feb 4 22:41:41 2007 --- openafs/src/WINNT/afsd/cm_buf.c Sun Jun 10 13:00:07 2007 *************** *** 316,322 **** cm_data.buf_hashSize = osi_PrimeLessThan((afs_uint32)(cm_data.buf_nbuffers/7 + 1)); /* create hash table */ ! memset((void *)cm_data.buf_hashTablepp, 0, cm_data.buf_hashSize * sizeof(cm_buf_t *)); /* another hash table */ memset((void *)cm_data.buf_fileHashTablepp, 0, cm_data.buf_hashSize * sizeof(cm_buf_t *)); --- 316,322 ---- cm_data.buf_hashSize = osi_PrimeLessThan((afs_uint32)(cm_data.buf_nbuffers/7 + 1)); /* create hash table */ ! memset((void *)cm_data.buf_scacheHashTablepp, 0, cm_data.buf_hashSize * sizeof(cm_buf_t *)); /* another hash table */ memset((void *)cm_data.buf_fileHashTablepp, 0, cm_data.buf_hashSize * sizeof(cm_buf_t *)); *************** *** 552,558 **** cm_buf_t *bp; i = BUF_HASH(&scp->fid, offsetp); ! for(bp = cm_data.buf_hashTablepp[i]; bp; bp=bp->hashp) { if (cm_FidCmp(&scp->fid, &bp->fid) == 0 && offsetp->LowPart == bp->offset.LowPart && offsetp->HighPart == bp->offset.HighPart) { --- 552,558 ---- cm_buf_t *bp; i = BUF_HASH(&scp->fid, offsetp); ! for(bp = cm_data.buf_scacheHashTablepp[i]; bp; bp=bp->hashp) { if (cm_FidCmp(&scp->fid, &bp->fid) == 0 && offsetp->LowPart == bp->offset.LowPart && offsetp->HighPart == bp->offset.HighPart) { *************** *** 691,697 **** /* Remove from hash */ i = BUF_HASH(&bp->fid, &bp->offset); ! lbpp = &(cm_data.buf_hashTablepp[i]); for(tbp = *lbpp; tbp; lbpp = &tbp->hashp, tbp = *lbpp) { if (tbp == bp) break; } --- 691,697 ---- /* Remove from hash */ i = BUF_HASH(&bp->fid, &bp->offset); ! lbpp = &(cm_data.buf_scacheHashTablepp[i]); for(tbp = *lbpp; tbp; lbpp = &tbp->hashp, tbp = *lbpp) { if (tbp == bp) break; } *************** *** 864,871 **** #endif bp->offset = *offsetp; i = BUF_HASH(&scp->fid, offsetp); ! bp->hashp = cm_data.buf_hashTablepp[i]; ! cm_data.buf_hashTablepp[i] = bp; i = BUF_FILEHASH(&scp->fid); nextBp = cm_data.buf_fileHashTablepp[i]; bp->fileHashp = nextBp; --- 864,871 ---- #endif bp->offset = *offsetp; i = BUF_HASH(&scp->fid, offsetp); ! bp->hashp = cm_data.buf_scacheHashTablepp[i]; ! cm_data.buf_scacheHashTablepp[i] = bp; i = BUF_FILEHASH(&scp->fid); nextBp = cm_data.buf_fileHashTablepp[i]; bp->fileHashp = nextBp; *************** *** 1242,1248 **** lock_ObtainWrite(&buf_globalLock); for(i=0; ihashp) { if ((bp->flags & CM_BUF_DIRTY) == CM_BUF_DIRTY) { buf_HoldLocked(bp); lock_ReleaseWrite(&buf_globalLock); --- 1242,1248 ---- lock_ObtainWrite(&buf_globalLock); for(i=0; ihashp) { if ((bp->flags & CM_BUF_DIRTY) == CM_BUF_DIRTY) { buf_HoldLocked(bp); lock_ReleaseWrite(&buf_globalLock); *************** *** 1602,1608 **** } #endif /* TESTING */ ! /* dump the contents of the buf_hashTablepp. */ int cm_DumpBufHashTable(FILE *outputFile, char *cookie, int lock) { int zilch; --- 1602,1608 ---- } #endif /* TESTING */ ! /* dump the contents of the buf_scacheHashTablepp. */ int cm_DumpBufHashTable(FILE *outputFile, char *cookie, int lock) { int zilch; *************** *** 1610,1616 **** char output[1024]; afs_uint32 i; ! if (cm_data.buf_hashTablepp == NULL) return -1; if (lock) --- 1610,1616 ---- char output[1024]; afs_uint32 i; ! if (cm_data.buf_scacheHashTablepp == NULL) return -1; if (lock) *************** *** 1622,1628 **** for (i = 0; i < cm_data.buf_hashSize; i++) { ! for (bp = cm_data.buf_hashTablepp[i]; bp; bp=bp->hashp) { StringCbPrintfA(output, sizeof(output), "%s bp=0x%08X, hash=%d, fid (cell=%d, volume=%d, " --- 1622,1628 ---- for (i = 0; i < cm_data.buf_hashSize; i++) { ! for (bp = cm_data.buf_scacheHashTablepp[i]; bp; bp=bp->hashp) { StringCbPrintfA(output, sizeof(output), "%s bp=0x%08X, hash=%d, fid (cell=%d, volume=%d, " Index: openafs/src/WINNT/afsd/cm_callback.c diff -c openafs/src/WINNT/afsd/cm_callback.c:1.41.4.11 openafs/src/WINNT/afsd/cm_callback.c:1.41.4.17 *** openafs/src/WINNT/afsd/cm_callback.c:1.41.4.11 Wed Feb 7 12:35:16 2007 --- openafs/src/WINNT/afsd/cm_callback.c Sat Jul 7 09:38:33 2007 *************** *** 165,171 **** * * The callp parameter is currently unused. */ ! void cm_RevokeCallback(struct rx_call *callp, AFSFid *fidp) { cm_fid_t tfid; cm_scache_t *scp; --- 165,171 ---- * * The callp parameter is currently unused. */ ! void cm_RevokeCallback(struct rx_call *callp, cm_cell_t * cellp, AFSFid *fidp) { cm_fid_t tfid; cm_scache_t *scp; *************** *** 195,204 **** /* do all in the hash bucket, since we don't know how many we'll find with * varying cells. */ ! for (scp = cm_data.hashTablep[hash]; scp; scp=scp->nextp) { if (scp->fid.volume == tfid.volume && scp->fid.vnode == tfid.vnode && scp->fid.unique == tfid.unique && scp->cbExpires > 0 && scp->cbServerp != NULL) { --- 195,205 ---- /* do all in the hash bucket, since we don't know how many we'll find with * varying cells. */ ! for (scp = cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) { if (scp->fid.volume == tfid.volume && scp->fid.vnode == tfid.vnode && scp->fid.unique == tfid.unique && + (cellp == NULL || scp->fid.cell == cellp->cellID) && scp->cbExpires > 0 && scp->cbServerp != NULL) { *************** *** 206,215 **** --- 207,219 ---- lock_ReleaseWrite(&cm_scacheLock); osi_Log4(afsd_logp, "RevokeCallback Discarding SCache scp 0x%p vol %u vn %u uniq %u", scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique); + lock_ObtainMutex(&scp->mx); cm_DiscardSCache(scp); lock_ReleaseMutex(&scp->mx); + cm_CallbackNotifyChange(scp); + lock_ObtainWrite(&cm_scacheLock); cm_ReleaseSCacheNoLock(scp); } *************** *** 225,231 **** * * Called with no locks held. */ ! void cm_RevokeVolumeCallback(struct rx_call *callp, AFSFid *fidp) { long hash; cm_scache_t *scp; --- 229,235 ---- * * Called with no locks held. */ ! void cm_RevokeVolumeCallback(struct rx_call *callp, cm_cell_t *cellp, AFSFid *fidp) { long hash; cm_scache_t *scp; *************** *** 242,261 **** tfid.volume = fidp->Volume; cm_RecordRacingRevoke(&tfid, CM_RACINGFLAG_CANCELVOL); - lock_ObtainWrite(&cm_scacheLock); ! for (hash = 0; hash < cm_data.hashTableSize; hash++) { ! for(scp=cm_data.hashTablep[hash]; scp; scp=scp->nextp) { if (scp->fid.volume == fidp->Volume && scp->cbExpires > 0 && scp->cbServerp != NULL) { cm_HoldSCacheNoLock(scp); lock_ReleaseWrite(&cm_scacheLock); lock_ObtainMutex(&scp->mx); osi_Log4(afsd_logp, "RevokeVolumeCallback Discarding SCache scp 0x%p vol %u vn %u uniq %u", scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique); cm_DiscardSCache(scp); lock_ReleaseMutex(&scp->mx); cm_CallbackNotifyChange(scp); lock_ObtainWrite(&cm_scacheLock); cm_ReleaseSCacheNoLock(scp); --- 246,267 ---- tfid.volume = fidp->Volume; cm_RecordRacingRevoke(&tfid, CM_RACINGFLAG_CANCELVOL); lock_ObtainWrite(&cm_scacheLock); ! for (hash = 0; hash < cm_data.scacheHashTableSize; hash++) { ! for(scp=cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) { if (scp->fid.volume == fidp->Volume && + (cellp == NULL || scp->fid.cell == cellp->cellID) && scp->cbExpires > 0 && scp->cbServerp != NULL) { cm_HoldSCacheNoLock(scp); lock_ReleaseWrite(&cm_scacheLock); + lock_ObtainMutex(&scp->mx); osi_Log4(afsd_logp, "RevokeVolumeCallback Discarding SCache scp 0x%p vol %u vn %u uniq %u", scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique); cm_DiscardSCache(scp); lock_ReleaseMutex(&scp->mx); + cm_CallbackNotifyChange(scp); lock_ObtainWrite(&cm_scacheLock); cm_ReleaseSCacheNoLock(scp); *************** *** 343,354 **** --- 349,366 ---- struct rx_peer *peerp; unsigned long host = 0; unsigned short port = 0; + cm_server_t *tsp = NULL; + cm_cell_t * cellp = NULL; MUTEX_ENTER(&callp->lock); if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) { host = rx_HostOf(peerp); port = rx_PortOf(peerp); + + tsp = cm_FindServerByIP(host, CM_SERVER_FILE); + if (tsp) + cellp = tsp->cellp; } osi_Log2(afsd_logp, "SRXAFSCB_CallBack from host 0x%x port %d", *************** *** 361,369 **** if (tfidp->Volume == 0) continue; /* means don't do anything */ else if (tfidp->Vnode == 0) ! cm_RevokeVolumeCallback(callp, tfidp); else ! cm_RevokeCallback(callp, tfidp); } MUTEX_EXIT(&callp->lock); --- 373,381 ---- if (tfidp->Volume == 0) continue; /* means don't do anything */ else if (tfidp->Vnode == 0) ! cm_RevokeVolumeCallback(callp, cellp, tfidp); else ! cm_RevokeCallback(callp, cellp, tfidp); } MUTEX_EXIT(&callp->lock); *************** *** 450,457 **** * are "rare," hopefully this won't be a problem. */ lock_ObtainWrite(&cm_scacheLock); ! for (hash = 0; hash < cm_data.hashTableSize; hash++) { ! for (scp=cm_data.hashTablep[hash]; scp; scp=scp->nextp) { cm_HoldSCacheNoLock(scp); lock_ReleaseWrite(&cm_scacheLock); lock_ObtainMutex(&scp->mx); --- 462,469 ---- * are "rare," hopefully this won't be a problem. */ lock_ObtainWrite(&cm_scacheLock); ! for (hash = 0; hash < cm_data.scacheHashTableSize; hash++) { ! for (scp=cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) { cm_HoldSCacheNoLock(scp); lock_ReleaseWrite(&cm_scacheLock); lock_ObtainMutex(&scp->mx); *************** *** 482,488 **** /* we're done with the server structure */ cm_PutServer(tsp); ! } } MUTEX_EXIT(&callp->lock); return 0; --- 494,500 ---- /* we're done with the server structure */ cm_PutServer(tsp); ! } } MUTEX_EXIT(&callp->lock); return 0; *************** *** 693,700 **** ntohl(host), ntohs(port)); lock_ObtainRead(&cm_scacheLock); ! for (i = 0; i < cm_data.hashTableSize; i++) { ! for (scp = cm_data.hashTablep[i]; scp; scp = scp->nextp) { if (index == 0) goto searchDone; index--; --- 705,712 ---- ntohl(host), ntohs(port)); lock_ObtainRead(&cm_scacheLock); ! for (i = 0; i < cm_data.scacheHashTableSize; i++) { ! for (scp = cm_data.scacheHashTablep[i]; scp; scp = scp->nextp) { if (index == 0) goto searchDone; index--; *************** *** 799,806 **** ntohl(host), ntohs(port)); lock_ObtainRead(&cm_scacheLock); ! for (i = 0; i < cm_data.hashTableSize; i++) { ! for (scp = cm_data.hashTablep[i]; scp; scp = scp->nextp) { if (index == 0) goto searchDone; index--; --- 811,818 ---- ntohl(host), ntohs(port)); lock_ObtainRead(&cm_scacheLock); ! for (i = 0; i < cm_data.scacheHashTableSize; i++) { ! for (scp = cm_data.scacheHashTablep[i]; scp; scp = scp->nextp) { if (index == 0) goto searchDone; index--; *************** *** 1522,1528 **** cm_racingRevokes_t *revp; /* where we are */ cm_racingRevokes_t *nrevp; /* where we'll be next */ int freeFlag; ! cm_server_t * serverp = 0; int discardScp = 0; lock_ObtainWrite(&cm_callbackLock); --- 1534,1540 ---- cm_racingRevokes_t *revp; /* where we are */ cm_racingRevokes_t *nrevp; /* where we'll be next */ int freeFlag; ! cm_server_t * serverp = NULL; int discardScp = 0; lock_ObtainWrite(&cm_callbackLock); *************** *** 1603,1609 **** lock_ReleaseMutex(&scp->mx); cm_CallbackNotifyChange(scp); lock_ObtainMutex(&scp->mx); ! } if ( serverp ) { lock_ObtainWrite(&cm_serverLock); --- 1615,1621 ---- lock_ReleaseMutex(&scp->mx); cm_CallbackNotifyChange(scp); lock_ObtainMutex(&scp->mx); ! } if ( serverp ) { lock_ObtainWrite(&cm_serverLock); *************** *** 1697,1703 **** osi_Log4(afsd_logp, "CALL FetchStatus scp 0x%p vol %u vn %u uniq %u", scp, sfid.volume, sfid.vnode, sfid.unique); do { ! code = cm_Conn(&sfid, userp, reqp, &connp); if (code) continue; --- 1709,1715 ---- osi_Log4(afsd_logp, "CALL FetchStatus scp 0x%p vol %u vn %u uniq %u", scp, sfid.volume, sfid.vnode, sfid.unique); do { ! code = cm_ConnFromFID(&sfid, userp, reqp, &connp); if (code) continue; *************** *** 1755,1762 **** now = osi_Time(); lock_ObtainWrite(&cm_scacheLock); ! for (i=0; inextp) { cm_HoldSCacheNoLock(scp); if (scp->cbExpires > 0 && (scp->cbServerp == NULL || now > scp->cbExpires)) { lock_ReleaseWrite(&cm_scacheLock); --- 1767,1774 ---- now = osi_Time(); lock_ObtainWrite(&cm_scacheLock); ! for (i=0; inextp) { cm_HoldSCacheNoLock(scp); if (scp->cbExpires > 0 && (scp->cbServerp == NULL || now > scp->cbExpires)) { lock_ReleaseWrite(&cm_scacheLock); *************** *** 1776,1778 **** --- 1788,1827 ---- osi_Log0(afsd_logp, "CheckCBExpiration Complete"); } + + void + cm_GiveUpAllCallbacks(cm_server_t *tsp) + { + long code; + cm_conn_t *connp; + struct rx_connection * rxconnp; + + if (tsp->type == CM_SERVER_FILE && !(tsp->flags & CM_SERVERFLAG_DOWN)) { + code = cm_ConnByServer(tsp, cm_rootUserp, &connp); + if (code == 0) { + rxconnp = cm_GetRxConn(connp); + rx_SetConnDeadTime(rxconnp, 10); + code = RXAFS_GiveUpAllCallBacks(rxconnp); + rx_SetConnDeadTime(rxconnp, ConnDeadtimeout); + rx_PutConnection(rxconnp); + } + } + } + + void + cm_GiveUpAllCallbacksAllServers(void) + { + cm_server_t *tsp; + + lock_ObtainWrite(&cm_serverLock); + for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) { + cm_GetServerNoLock(tsp); + lock_ReleaseWrite(&cm_serverLock); + cm_GiveUpAllCallbacks(tsp); + lock_ObtainWrite(&cm_serverLock); + cm_PutServerNoLock(tsp); + } + lock_ReleaseWrite(&cm_serverLock); + } + + Index: openafs/src/WINNT/afsd/cm_callback.h diff -c openafs/src/WINNT/afsd/cm_callback.h:1.7 openafs/src/WINNT/afsd/cm_callback.h:1.7.4.2 *** openafs/src/WINNT/afsd/cm_callback.h:1.7 Sat Nov 5 01:47:46 2005 --- openafs/src/WINNT/afsd/cm_callback.h Thu Jun 28 00:50:15 2007 *************** *** 68,71 **** --- 68,75 ---- extern void cm_CallbackNotifyChange(cm_scache_t *scp); + extern void cm_GiveUpAllCallbacks(cm_server_t *tsp); + + extern void cm_GiveUpAllCallbacksAllServers(void); + #endif /* _CM_CALLBACK_H_ENV__ */ Index: openafs/src/WINNT/afsd/cm_cell.c diff -c openafs/src/WINNT/afsd/cm_cell.c:1.23.2.1 openafs/src/WINNT/afsd/cm_cell.c:1.23.2.6 *** openafs/src/WINNT/afsd/cm_cell.c:1.23.2.1 Sat Oct 21 16:47:48 2006 --- openafs/src/WINNT/afsd/cm_cell.c Fri Jun 22 18:16:39 2007 *************** *** 46,52 **** tsp = cm_NewServer(addrp, CM_SERVER_VLDB, cellp); /* Insert the vlserver into a sorted list, sorted by server rank */ ! tsrp = cm_NewServerRef(tsp); cm_InsertServerList(&cellp->vlServersp, tsrp); /* drop the allocation reference */ lock_ObtainWrite(&cm_serverLock); --- 46,52 ---- tsp = cm_NewServer(addrp, CM_SERVER_VLDB, cellp); /* Insert the vlserver into a sorted list, sorted by server rank */ ! tsrp = cm_NewServerRef(tsp, 0); cm_InsertServerList(&cellp->vlServersp, tsrp); /* drop the allocation reference */ lock_ObtainWrite(&cm_serverLock); *************** *** 79,85 **** ) { /* must empty cp->vlServersp */ if (cp->vlServersp) { ! cm_FreeServerList(&cp->vlServersp); cp->vlServersp = NULL; } --- 79,85 ---- ) { /* must empty cp->vlServersp */ if (cp->vlServersp) { ! cm_FreeServerList(&cp->vlServersp, CM_FREESERVERLIST_DELETE); cp->vlServersp = NULL; } *************** *** 115,145 **** } /* load up a cell structure from the cell database, afsdcell.ini */ ! cm_cell_t *cm_GetCell(char *namep, long flags) { return cm_GetCell_Gen(namep, NULL, flags); } ! cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags) { ! cm_cell_t *cp; long code; char fullname[200]=""; if (!strcmp(namep,SMB_IOCTL_FILENAME_NOSLASH)) return NULL; ! lock_ObtainWrite(&cm_cellLock); ! for (cp = cm_data.allCellsp; cp; cp=cp->nextp) { if (stricmp(namep, cp->name) == 0) { strcpy(fullname, cp->name); break; } } if (cp) { ! cp = cm_UpdateCell(cp); } else if (flags & CM_FLAG_CREATE) { if ( cm_data.currentCells >= cm_data.maxCells ) osi_panic("Exceeded Max Cells", __FILE__, __LINE__); --- 115,166 ---- } /* load up a cell structure from the cell database, afsdcell.ini */ ! cm_cell_t *cm_GetCell(char *namep, afs_uint32 flags) { return cm_GetCell_Gen(namep, NULL, flags); } ! cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags) { ! cm_cell_t *cp, *cp2; long code; char fullname[200]=""; + int hasWriteLock = 0; + afs_uint32 hash; if (!strcmp(namep,SMB_IOCTL_FILENAME_NOSLASH)) return NULL; ! hash = CM_CELL_NAME_HASH(namep); ! ! lock_ObtainRead(&cm_cellLock); ! for (cp = cm_data.cellNameHashTablep[hash]; cp; cp=cp->nameNextp) { if (stricmp(namep, cp->name) == 0) { strcpy(fullname, cp->name); break; } } + lock_ReleaseRead(&cm_cellLock); if (cp) { ! cm_UpdateCell(cp); } else if (flags & CM_FLAG_CREATE) { + lock_ObtainWrite(&cm_cellLock); + hasWriteLock = 1; + + /* when we dropped the lock the cell could have been added + * to the list so check again while holding the write lock + */ + for (cp = cm_data.cellNameHashTablep[hash]; cp; cp=cp->nameNextp) { + if (stricmp(namep, cp->name) == 0) { + strcpy(fullname, cp->name); + break; + } + } + + if (cp) + goto done; + if ( cm_data.currentCells >= cm_data.maxCells ) osi_panic("Exceeded Max Cells", __FILE__, __LINE__); *************** *** 181,186 **** --- 202,226 ---- cp->timeout = time(0) + 7200; /* two hour timeout */ } + /* we have now been given the fullname of the cell. It may + * be that we already have a cell with that name. If so, + * we should use it instead of completing the allocation + * of a new cm_cell_t + */ + hash = CM_CELL_NAME_HASH(fullname); + for (cp2 = cm_data.cellNameHashTablep[hash]; cp2; cp2=cp2->nameNextp) { + if (stricmp(fullname, cp2->name) == 0) { + break; + } + } + + if (cp2) { + cm_FreeServerList(&cp->vlServersp, CM_FREESERVERLIST_DELETE); + cp = cp2; + goto done; + } + + /* randomise among those vlservers having the same rank*/ cm_RandomizeServer(&cp->vlServersp); *************** *** 191,227 **** strncpy(cp->name, fullname, CELL_MAXNAMELEN); cp->name[CELL_MAXNAMELEN-1] = '\0'; - /* thread on global list */ - cp->nextp = cm_data.allCellsp; - cm_data.allCellsp = cp; - /* the cellID cannot be 0 */ cp->cellID = ++cm_data.currentCells; } done: /* fullname is not valid if cp == NULL */ if (cp && newnamep) strcpy(newnamep, fullname); - lock_ReleaseWrite(&cm_cellLock); return cp; } cm_cell_t *cm_FindCellByID(afs_int32 cellID) { cm_cell_t *cp; ! lock_ObtainWrite(&cm_cellLock); ! for (cp = cm_data.allCellsp; cp; cp=cp->nextp) { if (cellID == cp->cellID) break; } if (cp) ! cp = cm_UpdateCell(cp); - lock_ReleaseWrite(&cm_cellLock); return cp; } --- 231,282 ---- strncpy(cp->name, fullname, CELL_MAXNAMELEN); cp->name[CELL_MAXNAMELEN-1] = '\0'; /* the cellID cannot be 0 */ cp->cellID = ++cm_data.currentCells; + + /* append cell to global list */ + if (cm_data.allCellsp == NULL) { + cm_data.allCellsp = cp; + } else { + for (cp2 = cm_data.allCellsp; cp2->allNextp; cp2=cp2->allNextp) + ; + cp2->allNextp = cp; + } + cp->allNextp = NULL; + + cm_AddCellToNameHashTable(cp); + cm_AddCellToIDHashTable(cp); } done: + if (hasWriteLock) + lock_ReleaseWrite(&cm_cellLock); + /* fullname is not valid if cp == NULL */ if (cp && newnamep) strcpy(newnamep, fullname); return cp; } cm_cell_t *cm_FindCellByID(afs_int32 cellID) { cm_cell_t *cp; + afs_uint32 hash; + + lock_ObtainRead(&cm_cellLock); + + hash = CM_CELL_ID_HASH(cellID); ! for (cp = cm_data.cellIDHashTablep[hash]; cp; cp=cp->idNextp) { if (cellID == cp->cellID) break; } + lock_ReleaseRead(&cm_cellLock); if (cp) ! cm_UpdateCell(cp); return cp; } *************** *** 231,237 **** cm_cell_t * cellp; afs_uint32 count; ! for (cellp = cm_data.allCellsp, count = 0; cellp; cellp=cellp->nextp, count++) { if ( cellp->magic != CM_CELL_MAGIC ) { afsi_log("cm_ValidateCell failure: cellp->magic != CM_CELL_MAGIC"); fprintf(stderr, "cm_ValidateCell failure: cellp->magic != CM_CELL_MAGIC\n"); --- 286,292 ---- cm_cell_t * cellp; afs_uint32 count; ! for (cellp = cm_data.allCellsp, count = 0; cellp; cellp=cellp->allNextp, count++) { if ( cellp->magic != CM_CELL_MAGIC ) { afsi_log("cm_ValidateCell failure: cellp->magic != CM_CELL_MAGIC"); fprintf(stderr, "cm_ValidateCell failure: cellp->magic != CM_CELL_MAGIC\n"); *************** *** 260,266 **** { cm_cell_t * cellp; ! for (cellp = cm_data.allCellsp; cellp; cellp=cellp->nextp) lock_FinalizeMutex(&cellp->mx); return 0; --- 315,321 ---- { cm_cell_t * cellp; ! for (cellp = cm_data.allCellsp; cellp; cellp=cellp->allNextp) lock_FinalizeMutex(&cellp->mx); return 0; *************** *** 280,285 **** --- 335,342 ---- cm_data.allCellsp = NULL; cm_data.currentCells = 0; cm_data.maxCells = maxCells; + memset(cm_data.cellNameHashTablep, 0, sizeof(cm_cell_t *) * cm_data.cellHashTableSize); + memset(cm_data.cellIDHashTablep, 0, sizeof(cm_cell_t *) * cm_data.cellHashTableSize); #ifdef AFS_FREELANCE_CLIENT /* Generate a dummy entry for the Freelance cell whether or not *************** *** 296,302 **** strncpy(cellp->name, "Freelance.Local.Cell", CELL_MAXNAMELEN); /*safe*/ /* thread on global list */ ! cellp->nextp = cm_data.allCellsp; cm_data.allCellsp = cellp; cellp->cellID = AFS_FAKE_ROOT_CELL_ID; --- 353,359 ---- strncpy(cellp->name, "Freelance.Local.Cell", CELL_MAXNAMELEN); /*safe*/ /* thread on global list */ ! cellp->allNextp = cm_data.allCellsp; cm_data.allCellsp = cellp; cellp->cellID = AFS_FAKE_ROOT_CELL_ID; *************** *** 304,310 **** cellp->flags = CM_CELLFLAG_FREELANCE; #endif } else { ! for (cellp = cm_data.allCellsp; cellp; cellp=cellp->nextp) { lock_InitializeMutex(&cellp->mx, "cm_cell_t mutex"); cellp->vlServersp = NULL; } --- 361,367 ---- cellp->flags = CM_CELLFLAG_FREELANCE; #endif } else { ! for (cellp = cm_data.allCellsp; cellp; cellp=cellp->allNextp) { lock_InitializeMutex(&cellp->mx, "cm_cell_t mutex"); cellp->vlServersp = NULL; } *************** *** 331,333 **** --- 388,494 ---- } } + int cm_DumpCells(FILE *outputFile, char *cookie, int lock) + { + cm_cell_t *cellp; + int zilch; + char output[1024]; + + if (lock) + lock_ObtainRead(&cm_cellLock); + + sprintf(output, "%s - dumping cells - cm_data.currentCells=%d, cm_data.maxCells=%d\r\n", + cookie, cm_data.currentCells, cm_data.maxCells); + WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); + + for (cellp = cm_data.allCellsp; cellp; cellp=cellp->allNextp) { + sprintf(output, "%s cellp=0x%p,name=%s ID=%d flags=0x%x\r\n", + cookie, cellp, cellp->name, cellp->cellID, cellp->flags); + WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); + } + + sprintf(output, "%s - Done dumping cells.\r\n", cookie); + WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); + + if (lock) + lock_ReleaseRead(&cm_cellLock); + + return(0); + } + + /* call with volume write-locked and mutex held */ + void cm_AddCellToNameHashTable(cm_cell_t *cellp) + { + int i; + + if (cellp->flags & CM_CELLFLAG_IN_NAMEHASH) + return; + + i = CM_CELL_NAME_HASH(cellp->name); + + cellp->nameNextp = cm_data.cellNameHashTablep[i]; + cm_data.cellNameHashTablep[i] = cellp; + cellp->flags |= CM_CELLFLAG_IN_NAMEHASH; + } + + /* call with cell write-locked and mutex held */ + void cm_RemoveCellFromNameHashTable(cm_cell_t *cellp) + { + cm_cell_t **lcellpp; + cm_cell_t *tcellp; + int i; + + if (cellp->flags & CM_CELLFLAG_IN_NAMEHASH) { + /* hash it out first */ + i = CM_CELL_NAME_HASH(cellp->name); + for (lcellpp = &cm_data.cellNameHashTablep[i], tcellp = cm_data.cellNameHashTablep[i]; + tcellp; + lcellpp = &tcellp->nameNextp, tcellp = tcellp->nameNextp) { + if (tcellp == cellp) { + *lcellpp = cellp->nameNextp; + cellp->flags &= ~CM_CELLFLAG_IN_NAMEHASH; + cellp->nameNextp = NULL; + break; + } + } + } + } + + /* call with cell write-locked and mutex held */ + void cm_AddCellToIDHashTable(cm_cell_t *cellp) + { + int i; + + if (cellp->flags & CM_CELLFLAG_IN_IDHASH) + return; + + i = CM_CELL_ID_HASH(cellp->cellID); + + cellp->idNextp = cm_data.cellIDHashTablep[i]; + cm_data.cellIDHashTablep[i] = cellp; + cellp->flags |= CM_CELLFLAG_IN_IDHASH; + } + + /* call with cell write-locked and mutex held */ + void cm_RemoveCellFromIDHashTable(cm_cell_t *cellp) + { + cm_cell_t **lcellpp; + cm_cell_t *tcellp; + int i; + + if (cellp->flags & CM_CELLFLAG_IN_IDHASH) { + /* hash it out first */ + i = CM_CELL_ID_HASH(cellp->cellID); + for (lcellpp = &cm_data.cellIDHashTablep[i], tcellp = cm_data.cellIDHashTablep[i]; + tcellp; + lcellpp = &tcellp->idNextp, tcellp = tcellp->idNextp) { + if (tcellp == cellp) { + *lcellpp = cellp->idNextp; + cellp->flags &= ~CM_CELLFLAG_IN_IDHASH; + cellp->idNextp = NULL; + break; + } + } + } + } + Index: openafs/src/WINNT/afsd/cm_cell.h diff -c openafs/src/WINNT/afsd/cm_cell.h:1.7.6.1 openafs/src/WINNT/afsd/cm_cell.h:1.7.6.5 *** openafs/src/WINNT/afsd/cm_cell.h:1.7.6.1 Sat Oct 21 16:47:48 2006 --- openafs/src/WINNT/afsd/cm_cell.h Wed Jun 27 20:34:26 2007 *************** *** 10,17 **** #ifndef __CELL_H_ENV_ #define __CELL_H_ENV_ 1 - #include "cm_server.h" - #define CELL_MAXNAMELEN 256 #define CM_CELL_MAGIC ('C' | 'E' <<8 | 'L'<<16 | 'L'<<24) --- 10,15 ---- *************** *** 20,26 **** typedef struct cm_cell { afs_uint32 magic; afs_int32 cellID; /* cell ID */ ! struct cm_cell *nextp; /* locked by cm_cellLock */ char name[CELL_MAXNAMELEN]; /* cell name; never changes */ cm_serverRef_t *vlServersp; /* locked by cm_serverLock */ osi_mutex_t mx; /* mutex locking fields (flags) */ --- 18,26 ---- typedef struct cm_cell { afs_uint32 magic; afs_int32 cellID; /* cell ID */ ! struct cm_cell *allNextp; /* locked by cm_cellLock */ ! struct cm_cell *nameNextp; /* locked by cm_cellLock */ ! struct cm_cell *idNextp; /* locked by cm_cellLock */ char name[CELL_MAXNAMELEN]; /* cell name; never changes */ cm_serverRef_t *vlServersp; /* locked by cm_serverLock */ osi_mutex_t mx; /* mutex locking fields (flags) */ *************** *** 29,38 **** } cm_cell_t; /* These are bit flag values */ ! #define CM_CELLFLAG_SUID 1 /* setuid flag; not yet used */ ! #define CM_CELLFLAG_DNS 2 /* cell servers are from DNS */ ! #define CM_CELLFLAG_VLSERVER_INVALID 4 /* cell servers are invalid */ ! #define CM_CELLFLAG_FREELANCE 8 /* local freelance fake cell */ extern void cm_InitCell(int newFile, long maxCells); --- 29,44 ---- } cm_cell_t; /* These are bit flag values */ ! #define CM_CELLFLAG_SUID 1 /* setuid flag; not yet used */ ! #define CM_CELLFLAG_DNS 2 /* cell servers are from DNS */ ! #define CM_CELLFLAG_VLSERVER_INVALID 4 /* cell servers are invalid */ ! #define CM_CELLFLAG_FREELANCE 8 /* local freelance fake cell */ ! #define CM_CELLFLAG_IN_NAMEHASH 0x10 ! #define CM_CELLFLAG_IN_IDHASH 0x20 ! ! #define CM_CELL_NAME_HASH(name) (SDBMHash(name) % cm_data.cellHashTableSize) ! ! #define CM_CELL_ID_HASH(id) ((unsigned long) id % cm_data.cellHashTableSize) extern void cm_InitCell(int newFile, long maxCells); *************** *** 40,55 **** extern long cm_ValidateCell(void); ! extern cm_cell_t *cm_GetCell(char *namep, long flags); ! extern cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags); extern cm_cell_t *cm_FindCellByID(afs_int32 cellID); ! extern void cm_ChangeRankCellVLServer(cm_server_t *tsp); extern osi_rwlock_t cm_cellLock; extern cm_cell_t *cm_allCellsp; #endif /* __CELL_H_ENV_ */ --- 46,67 ---- extern long cm_ValidateCell(void); ! extern cm_cell_t *cm_GetCell(char *namep, afs_uint32 flags); ! extern cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags); extern cm_cell_t *cm_FindCellByID(afs_int32 cellID); ! extern void cm_ChangeRankCellVLServer(cm_server_t *tsp); extern osi_rwlock_t cm_cellLock; extern cm_cell_t *cm_allCellsp; + extern int cm_DumpCells(FILE *, char *, int); + + extern void cm_AddCellToNameHashTable(cm_cell_t * cellp); + + extern void cm_AddCellToIDHashTable(cm_cell_t * cellp); + #endif /* __CELL_H_ENV_ */ Index: openafs/src/WINNT/afsd/cm_config.c diff -c openafs/src/WINNT/afsd/cm_config.c:1.26 openafs/src/WINNT/afsd/cm_config.c:1.26.4.1 *** openafs/src/WINNT/afsd/cm_config.c:1.26 Mon Dec 19 07:42:23 2005 --- openafs/src/WINNT/afsd/cm_config.c Wed Jun 27 20:34:26 2007 *************** *** 7,16 **** * directory or online at http://www.openafs.org/dl/license10.html */ - #include - #include - #include - #ifndef DJGPP #include #include --- 7,12 ---- *************** *** 25,35 **** --- 21,38 ---- #include "afsd.h" #include #include + + #include + #include + #include + #ifdef AFS_AFSDB_ENV #include "cm_dns.h" #include #endif + + /* TODO: these should be pulled in from dirpath.h */ #if !defined(DJGPP) && !defined(AFS_WIN95_ENV) #define AFS_THISCELL "ThisCell" Index: openafs/src/WINNT/afsd/cm_conn.c diff -c openafs/src/WINNT/afsd/cm_conn.c:1.49.2.13 openafs/src/WINNT/afsd/cm_conn.c:1.49.2.19 *** openafs/src/WINNT/afsd/cm_conn.c:1.49.2.13 Sat Apr 14 14:49:36 2007 --- openafs/src/WINNT/afsd/cm_conn.c Mon Jun 25 00:59:40 2007 *************** *** 119,132 **** if (!fidp) { *serversppp = NULL; ! return 0; } cellp = cm_FindCellByID(fidp->cell); ! if (!cellp) return CM_ERROR_NOSUCHCELL; ! code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, &volp); ! if (code) return code; *serversppp = cm_GetVolServers(volp, fidp->volume); --- 119,134 ---- if (!fidp) { *serversppp = NULL; ! return CM_ERROR_INVAL; } cellp = cm_FindCellByID(fidp->cell); ! if (!cellp) ! return CM_ERROR_NOSUCHCELL; ! code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, CM_GETVOL_FLAG_CREATE, &volp); ! if (code) ! return code; *serversppp = cm_GetVolServers(volp, fidp->volume); *************** *** 139,150 **** * and if we're going to retry, determine whether failover is appropriate, * and whether timed backoff is appropriate. * ! * If the error code is from cm_Conn() or friends, it will be a CM_ERROR code. * Otherwise it will be an RPC code. This may be a UNIX code (e.g. EDQUOT), or * it may be an RX code, or it may be a special code (e.g. VNOVOL), or it may * be a security code (e.g. RXKADEXPIRED). * ! * If the error code is from cm_Conn() or friends, connp will be NULL. * * For VLDB calls, fidp will be NULL. * --- 141,152 ---- * and if we're going to retry, determine whether failover is appropriate, * and whether timed backoff is appropriate. * ! * If the error code is from cm_ConnFromFID() or friends, it will be a CM_ERROR code. * Otherwise it will be an RPC code. This may be a UNIX code (e.g. EDQUOT), or * it may be an RX code, or it may be a special code (e.g. VNOVOL), or it may * be a security code (e.g. RXKADEXPIRED). * ! * If the error code is from cm_ConnFromFID() or friends, connp will be NULL. * * For VLDB calls, fidp will be NULL. * *************** *** 162,167 **** --- 164,171 ---- cm_serverRef_t *tsrp; cm_cell_t *cellp = NULL; cm_ucell_t *ucellp; + cm_volume_t * volp = NULL; + cm_vol_state_t *statep = NULL; int retry = 0; int free_svr_list = 0; int dead_session; *************** *** 210,227 **** /* leave 5 seconds margin for sleep */ timeLeft = HardDeadtimeout - timeUsed; if (errorCode == CM_ERROR_TIMEDOUT) { if (timeLeft > 5 ) { thrd_Sleep(3000); - if (cellp == NULL && serverp) - cellp = serverp->cellp; - if (cellp == NULL && serversp) { - struct cm_serverRef * refp; - for ( refp=serversp ; cellp == NULL && refp != NULL; refp=refp->next) { - if ( refp->server ) - cellp = refp->server->cellp; - } - } cm_CheckServers(CM_FLAG_CHECKDOWNSERVERS, cellp); retry = 1; } --- 214,238 ---- /* leave 5 seconds margin for sleep */ timeLeft = HardDeadtimeout - timeUsed; + /* get a pointer to the cell */ + if (errorCode) { + if (cellp == NULL && serverp) + cellp = serverp->cellp; + if (cellp == NULL && serversp) { + struct cm_serverRef * refp; + for ( refp=serversp ; cellp == NULL && refp != NULL; refp=refp->next) { + if ( refp->server ) + cellp = refp->server->cellp; + } + } + if (cellp == NULL && fidp) { + cellp = cm_FindCellByID(fidp->cell); + } + } + if (errorCode == CM_ERROR_TIMEDOUT) { if (timeLeft > 5 ) { thrd_Sleep(3000); cm_CheckServers(CM_FLAG_CHECKDOWNSERVERS, cellp); retry = 1; } *************** *** 253,327 **** } else if (errorCode == CM_ERROR_ALLOFFLINE) { ! if (timeLeft > 7) { ! osi_Log0(afsd_logp, "cm_Analyze passed CM_ERROR_ALLOFFLINE."); thrd_Sleep(5000); - - if (fidp) { /* Not a VLDB call */ - if (!serversp) { - code = cm_GetServerList(fidp, userp, reqp, &serverspp); - if (code == 0) { - serversp = *serverspp; - free_svr_list = 1; - } - } - if (serversp) { - lock_ObtainWrite(&cm_serverLock); - for (tsrp = serversp; tsrp; tsrp=tsrp->next) - tsrp->status = not_busy; - lock_ReleaseWrite(&cm_serverLock); - if (free_svr_list) { - cm_FreeServerList(&serversp); - *serverspp = serversp; - } - retry = 1; - } ! cm_ForceUpdateVolume(fidp, userp, reqp); ! } else { /* VLDB call */ ! if (serversp) { ! lock_ObtainWrite(&cm_serverLock); ! for (tsrp = serversp; tsrp; tsrp=tsrp->next) ! tsrp->status = not_busy; ! lock_ReleaseWrite(&cm_serverLock); ! if (free_svr_list) { ! cm_FreeServerList(&serversp); ! *serverspp = serversp; ! } ! } ! } } } - - /* if all servers are busy, mark them non-busy and start over */ else if (errorCode == CM_ERROR_ALLBUSY) { osi_Log0(afsd_logp, "cm_Analyze passed CM_ERROR_ALLBUSY."); if (timeLeft > 7) { thrd_Sleep(5000); ! if (!serversp) { ! code = cm_GetServerList(fidp, userp, reqp, &serverspp); if (code == 0) { ! serversp = *serverspp; ! free_svr_list = 1; } } - lock_ObtainWrite(&cm_serverLock); - for (tsrp = serversp; tsrp; tsrp=tsrp->next) { - if (tsrp->status == busy) - tsrp->status = not_busy; - } - lock_ReleaseWrite(&cm_serverLock); - if (free_svr_list) { - cm_FreeServerList(&serversp); - *serverspp = serversp; - } - retry = 1; } } /* special codes: VBUSY and VRESTARTING */ else if (errorCode == VBUSY || errorCode == VRESTARTING) { ! if (!serversp) { code = cm_GetServerList(fidp, userp, reqp, &serverspp); if (code == 0) { serversp = *serverspp; --- 264,368 ---- } else if (errorCode == CM_ERROR_ALLOFFLINE) { ! osi_Log0(afsd_logp, "cm_Analyze passed CM_ERROR_ALLOFFLINE."); ! /* Volume instances marked offline will be restored by the ! * background daemon thread as they become available ! */ ! if (timeLeft > 7 && fidp) { ! cm_volume_t *volp; ! cm_vol_state_t *statep; ! thrd_Sleep(5000); ! code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, ! CM_GETVOL_FLAG_NO_LRU_UPDATE, ! &volp); ! if (code == 0) { ! if (fidp->volume == volp->rw.ID) ! statep = &volp->rw; ! else if (fidp->volume == volp->ro.ID) ! statep = &volp->ro; ! else if (fidp->volume == volp->bk.ID) ! statep = &volp->bk; ! ! if (statep->state != vl_offline) { ! retry = 1; ! } else { ! if (cm_CheckOfflineVolume(volp, statep->ID)) ! retry = 1; ! } ! ! cm_PutVolume(volp); ! } } } else if (errorCode == CM_ERROR_ALLBUSY) { + /* Volumes that are busy cannot be determined to be non-busy + * without actually attempting to access them. + */ osi_Log0(afsd_logp, "cm_Analyze passed CM_ERROR_ALLBUSY."); if (timeLeft > 7) { + thrd_Sleep(5000); ! ! if (fidp) { /* File Server query */ ! code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, ! CM_GETVOL_FLAG_NO_LRU_UPDATE, ! &volp); if (code == 0) { ! if (fidp->volume == volp->rw.ID) ! statep = &volp->rw; ! else if (fidp->volume == volp->ro.ID) ! statep = &volp->ro; ! else if (fidp->volume == volp->bk.ID) ! statep = &volp->bk; ! ! if (statep->state != vl_offline && statep->state != vl_busy) { ! retry = 1; ! } else { ! if (!serversp) { ! code = cm_GetServerList(fidp, userp, reqp, &serverspp); ! if (code == 0) { ! serversp = *serverspp; ! free_svr_list = 1; ! } ! } ! lock_ObtainWrite(&cm_serverLock); ! for (tsrp = serversp; tsrp; tsrp=tsrp->next) { ! if (tsrp->status == srv_busy) { ! tsrp->status = srv_not_busy; ! } ! } ! lock_ReleaseWrite(&cm_serverLock); ! if (free_svr_list) { ! cm_FreeServerList(&serversp, 0); ! *serverspp = serversp; ! } ! ! cm_UpdateVolumeStatus(volp, statep->ID); ! retry = 1; ! } ! ! cm_PutVolume(volp); ! } ! } else { /* VL Server query */ ! if (serversp) { ! lock_ObtainWrite(&cm_serverLock); ! for (tsrp = serversp; tsrp; tsrp=tsrp->next) { ! if (tsrp->status == srv_busy) { ! tsrp->status = srv_not_busy; ! } ! } ! lock_ReleaseWrite(&cm_serverLock); ! retry = 1; } } } } /* special codes: VBUSY and VRESTARTING */ else if (errorCode == VBUSY || errorCode == VRESTARTING) { ! if (!serversp && fidp) { code = cm_GetServerList(fidp, userp, reqp, &serverspp); if (code == 0) { serversp = *serverspp; *************** *** 330,344 **** } lock_ObtainWrite(&cm_serverLock); for (tsrp = serversp; tsrp; tsrp=tsrp->next) { ! if (tsrp->server == serverp ! && tsrp->status == not_busy) { ! tsrp->status = busy; break; } } lock_ReleaseWrite(&cm_serverLock); if (free_svr_list) { ! cm_FreeServerList(&serversp); *serverspp = serversp; } retry = 1; --- 371,403 ---- } lock_ObtainWrite(&cm_serverLock); for (tsrp = serversp; tsrp; tsrp=tsrp->next) { ! 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, ! CM_GETVOL_FLAG_NO_LRU_UPDATE, ! &volp); ! if (code == 0) { ! if (fidp->volume == volp->rw.ID) ! statep = &volp->rw; ! else if (fidp->volume == volp->ro.ID) ! statep = &volp->ro; ! else if (fidp->volume == volp->bk.ID) ! statep = &volp->bk; ! } ! ! cm_PutVolume(volp); ! } break; } } lock_ReleaseWrite(&cm_serverLock); + + if (statep) + cm_UpdateVolumeStatus(volp, statep->ID); + if (free_svr_list) { ! cm_FreeServerList(&serversp, 0); *serverspp = serversp; } retry = 1; *************** *** 405,411 **** #endif /* Mark server offline for this volume */ ! if (!serversp) { code = cm_GetServerList(fidp, userp, reqp, &serverspp); if (code == 0) { serversp = *serverspp; --- 464,470 ---- #endif /* Mark server offline for this volume */ ! if (!serversp && fidp) { code = cm_GetServerList(fidp, userp, reqp, &serverspp); if (code == 0) { serversp = *serverspp; *************** *** 413,423 **** } } for (tsrp = serversp; tsrp; tsrp=tsrp->next) { ! if (tsrp->server == serverp) ! tsrp->status = offline; } if (free_svr_list) { ! cm_FreeServerList(&serversp); *serverspp = serversp; } if ( timeLeft > 2 ) --- 472,490 ---- } } for (tsrp = serversp; tsrp; tsrp=tsrp->next) { ! if (tsrp->server == serverp) { ! /* REDIRECT */ ! if (errorCode == VNOVOL || errorCode == VMOVED) { ! tsrp->status = srv_deleted; ! if (fidp) { ! cm_ForceUpdateVolume(fidp, userp, reqp); ! } ! } else ! tsrp->status = srv_offline; ! } } if (free_svr_list) { ! cm_FreeServerList(&serversp, 0); *serverspp = serversp; } if ( timeLeft > 2 ) *************** *** 666,675 **** lock_ReleaseWrite(&cm_serverLock); if (!(tsp->flags & CM_SERVERFLAG_DOWN)) { allDown = 0; ! if (tsrp->status == busy) { allOffline = 0; someBusy = 1; ! } else if (tsrp->status == offline) { allBusy = 0; someOffline = 1; } else { --- 733,744 ---- lock_ReleaseWrite(&cm_serverLock); if (!(tsp->flags & CM_SERVERFLAG_DOWN)) { allDown = 0; ! if (tsrp->status == srv_deleted) { ! /* skip this entry. no longer valid. */; ! } else if (tsrp->status == srv_busy) { allOffline = 0; someBusy = 1; ! } else if (tsrp->status == srv_offline) { allBusy = 0; someOffline = 1; } else { *************** *** 870,879 **** cm_GetServerNoLock(tsp); if (!(tsp->flags & CM_SERVERFLAG_DOWN)) { allDown = 0; ! if (tsrp->status == busy) { allOffline = 0; someBusy = 1; ! } else if (tsrp->status == offline) { allBusy = 0; someOffline = 1; } else { --- 939,948 ---- cm_GetServerNoLock(tsp); if (!(tsp->flags & CM_SERVERFLAG_DOWN)) { allDown = 0; ! if (tsrp->status == srv_busy) { allOffline = 0; someBusy = 1; ! } else if (tsrp->status == srv_offline) { allBusy = 0; someOffline = 1; } else { *************** *** 884,890 **** cm_PutServerNoLock(tsp); } lock_ReleaseWrite(&cm_serverLock); ! cm_FreeServerList(serverspp); if (allDown) return 0; --- 953,959 ---- cm_PutServerNoLock(tsp); } lock_ReleaseWrite(&cm_serverLock); ! cm_FreeServerList(serverspp, 0); if (allDown) return 0; *************** *** 896,919 **** return 1; } ! long cm_Conn(struct cm_fid *fidp, struct cm_user *userp, cm_req_t *reqp, ! cm_conn_t **connpp) { long code; cm_serverRef_t **serverspp; code = cm_GetServerList(fidp, userp, reqp, &serverspp); if (code) { - *connpp = NULL; return code; } code = cm_ConnByMServers(*serverspp, userp, reqp, connpp); ! cm_FreeServerList(serverspp); return code; } ! extern struct rx_connection * cm_GetRxConn(cm_conn_t *connp) { struct rx_connection * rxconn; --- 965,1010 ---- return 1; } ! /* ! * The returned cm_conn_t ** object is released in the subsequent call ! * to cm_Analyze(). ! */ ! long cm_ConnFromFID(struct cm_fid *fidp, struct cm_user *userp, cm_req_t *reqp, ! cm_conn_t **connpp) { long code; cm_serverRef_t **serverspp; + *connpp = NULL; + code = cm_GetServerList(fidp, userp, reqp, &serverspp); if (code) { return code; } code = cm_ConnByMServers(*serverspp, userp, reqp, connpp); ! cm_FreeServerList(serverspp, 0); ! return code; ! } ! ! ! long cm_ConnFromVolume(struct cm_volume *volp, unsigned long volid, struct cm_user *userp, cm_req_t *reqp, ! cm_conn_t **connpp) ! { ! long code; ! cm_serverRef_t **serverspp; ! ! *connpp = NULL; ! ! serverspp = cm_GetVolServers(volp, volid); ! ! code = cm_ConnByMServers(*serverspp, userp, reqp, connpp); ! cm_FreeServerList(serverspp, 0); return code; } ! ! extern struct rx_connection * cm_GetRxConn(cm_conn_t *connp) { struct rx_connection * rxconn; Index: openafs/src/WINNT/afsd/cm_conn.h diff -c openafs/src/WINNT/afsd/cm_conn.h:1.13.4.7 openafs/src/WINNT/afsd/cm_conn.h:1.13.4.8 *** openafs/src/WINNT/afsd/cm_conn.h:1.13.4.7 Sat Mar 10 10:50:07 2007 --- openafs/src/WINNT/afsd/cm_conn.h Sun Jun 10 13:00:07 2007 *************** *** 113,121 **** extern long cm_ConnByServer(struct cm_server *, struct cm_user *, cm_conn_t **); ! extern long cm_Conn(struct cm_fid *, struct cm_user *, struct cm_req *, cm_conn_t **); extern void cm_PutConn(cm_conn_t *connp); extern void cm_GCConnections(cm_server_t *serverp); --- 113,125 ---- extern long cm_ConnByServer(struct cm_server *, struct cm_user *, cm_conn_t **); ! extern long cm_ConnFromFID(struct cm_fid *, struct cm_user *, struct cm_req *, cm_conn_t **); + extern long cm_ConnFromVolume(struct cm_volume *volp, unsigned long volid, + struct cm_user *userp, cm_req_t *reqp, + cm_conn_t **connpp); + extern void cm_PutConn(cm_conn_t *connp); extern void cm_GCConnections(cm_server_t *serverp); Index: openafs/src/WINNT/afsd/cm_daemon.c diff -c openafs/src/WINNT/afsd/cm_daemon.c:1.16.4.11 openafs/src/WINNT/afsd/cm_daemon.c:1.16.4.16 *** openafs/src/WINNT/afsd/cm_daemon.c:1.16.4.11 Sat Mar 10 10:50:07 2007 --- openafs/src/WINNT/afsd/cm_daemon.c Thu Jul 5 15:22:15 2007 *************** *** 36,41 **** --- 36,42 ---- long cm_daemonCheckCBInterval = 60; long cm_daemonCheckLockInterval = 60; long cm_daemonTokenCheckInterval = 180; + long cm_daemonCheckOfflineVolInterval = 600; osi_rwlock_t cm_daemonLock; *************** *** 58,68 **** while (daemon_ShutdownFlag == 0) { DWORD Result = NotifyAddrChange(NULL,NULL); if (Result == NO_ERROR && daemon_ShutdownFlag == 0) { - osi_Log0(afsd_logp, "cm_IpAddrDaemon CheckDownServers"); Sleep(2500); cm_ForceNewConnectionsAllServers(); ! cm_CheckServers(CM_FLAG_CHECKUPSERVERS | CM_FLAG_CHECKDOWNSERVERS, NULL); smb_CheckVCs(); } } } --- 59,71 ---- while (daemon_ShutdownFlag == 0) { DWORD Result = NotifyAddrChange(NULL,NULL); if (Result == NO_ERROR && daemon_ShutdownFlag == 0) { Sleep(2500); + osi_Log0(afsd_logp, "cm_IpAddrDaemon CheckDownServers"); + cm_CheckServers(CM_FLAG_CHECKVLDBSERVERS | CM_FLAG_CHECKUPSERVERS | CM_FLAG_CHECKDOWNSERVERS, NULL); cm_ForceNewConnectionsAllServers(); ! cm_CheckServers(CM_FLAG_CHECKFILESERVERS | CM_FLAG_CHECKUPSERVERS | CM_FLAG_CHECKDOWNSERVERS, NULL); smb_CheckVCs(); + cm_VolStatus_Network_Addr_Change(); } } } *************** *** 244,283 **** return; dummyLen = sizeof(DWORD); ! code = RegQueryValueEx(parmKey, "DownServerCheckInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS) cm_daemonCheckDownInterval = dummy; ! dummyLen = sizeof(DWORD); ! code = RegQueryValueEx(parmKey, "UpServerCheckInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS) cm_daemonCheckUpInterval = dummy; ! dummyLen = sizeof(DWORD); ! code = RegQueryValueEx(parmKey, "VolumeCheckInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS) cm_daemonCheckVolInterval = dummy; ! dummyLen = sizeof(DWORD); ! code = RegQueryValueEx(parmKey, "CallbackCheckInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS) cm_daemonCheckCBInterval = dummy; ! dummyLen = sizeof(DWORD); ! code = RegQueryValueEx(parmKey, "LockCheckInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS) cm_daemonCheckLockInterval = dummy; ! dummyLen = sizeof(DWORD); ! code = RegQueryValueEx(parmKey, "TokenCheckInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS) cm_daemonTokenCheckInterval = dummy; RegCloseKey(parmKey); } --- 247,299 ---- return; dummyLen = sizeof(DWORD); ! code = RegQueryValueEx(parmKey, "daemonCheckDownInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS) cm_daemonCheckDownInterval = dummy; ! afsi_log("daemonCheckDownInterval is %d", cm_daemonCheckDownInterval); ! dummyLen = sizeof(DWORD); ! code = RegQueryValueEx(parmKey, "daemonCheckUpInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS) cm_daemonCheckUpInterval = dummy; ! afsi_log("daemonCheckUpInterval is %d", cm_daemonCheckUpInterval); ! dummyLen = sizeof(DWORD); ! code = RegQueryValueEx(parmKey, "daemonCheckVolInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS) cm_daemonCheckVolInterval = dummy; ! afsi_log("daemonCheckVolInterval is %d", cm_daemonCheckVolInterval); ! dummyLen = sizeof(DWORD); ! code = RegQueryValueEx(parmKey, "daemonCheckCBInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS) cm_daemonCheckCBInterval = dummy; ! afsi_log("daemonCheckCBInterval is %d", cm_daemonCheckCBInterval); ! dummyLen = sizeof(DWORD); ! code = RegQueryValueEx(parmKey, "daemonCheckLockInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS) cm_daemonCheckLockInterval = dummy; ! afsi_log("daemonCheckLockInterval is %d", cm_daemonCheckLockInterval); ! dummyLen = sizeof(DWORD); ! code = RegQueryValueEx(parmKey, "daemonCheckTokenInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS) cm_daemonTokenCheckInterval = dummy; + afsi_log("daemonCheckTokenInterval is %d", cm_daemonTokenCheckInterval); + + dummyLen = sizeof(DWORD); + code = RegQueryValueEx(parmKey, "daemonCheckOfflineVolInterval", NULL, NULL, + (BYTE *) &dummy, &dummyLen); + if (code == ERROR_SUCCESS) + cm_daemonCheckOfflineVolInterval = dummy; + afsi_log("daemonCheckOfflineVolInterval is %d", cm_daemonCheckOfflineVolInterval); RegCloseKey(parmKey); } *************** *** 292,297 **** --- 308,314 ---- time_t lastDownServerCheck; time_t lastUpServerCheck; time_t lastTokenCacheCheck; + time_t lastBusyVolCheck; char thostName[200]; unsigned long code; struct hostent *thp; *************** *** 331,336 **** --- 348,354 ---- lastDownServerCheck = now - cm_daemonCheckDownInterval/2 + (rand() % cm_daemonCheckDownInterval); lastUpServerCheck = now - cm_daemonCheckUpInterval/2 + (rand() % cm_daemonCheckUpInterval); lastTokenCacheCheck = now - cm_daemonTokenCheckInterval/2 + (rand() % cm_daemonTokenCheckInterval); + lastBusyVolCheck = now - cm_daemonCheckOfflineVolInterval/2 * (rand() % cm_daemonCheckOfflineVolInterval); while (daemon_ShutdownFlag == 0) { /* check to see if the listener threads halted due to network *************** *** 384,389 **** --- 402,413 ---- now = osi_Time(); } + if (now > lastBusyVolCheck + cm_daemonCheckOfflineVolInterval) { + lastVolCheck = now; + cm_CheckOfflineVolumes(); + now = osi_Time(); + } + if (now > lastCBExpirationCheck + cm_daemonCheckCBInterval) { lastCBExpirationCheck = now; cm_CheckCBExpiration(); Index: openafs/src/WINNT/afsd/cm_dcache.c diff -c openafs/src/WINNT/afsd/cm_dcache.c:1.30.2.14 openafs/src/WINNT/afsd/cm_dcache.c:1.30.2.15 *** openafs/src/WINNT/afsd/cm_dcache.c:1.30.2.14 Wed Feb 7 12:35:16 2007 --- openafs/src/WINNT/afsd/cm_dcache.c Sun Jun 10 13:00:07 2007 *************** *** 149,155 **** /* now we're ready to do the store operation */ do { ! code = cm_Conn(&scp->fid, userp, reqp, &connp); if (code) continue; --- 149,155 ---- /* now we're ready to do the store operation */ do { ! code = cm_ConnFromFID(&scp->fid, userp, reqp, &connp); if (code) continue; *************** *** 356,362 **** /* now we're ready to do the store operation */ do { ! code = cm_Conn(&scp->fid, userp, reqp, &connp); if (code) continue; --- 356,362 ---- /* now we're ready to do the store operation */ do { ! code = cm_ConnFromFID(&scp->fid, userp, reqp, &connp); if (code) continue; *************** *** 1429,1435 **** /* now make the call */ do { ! code = cm_Conn(&scp->fid, up, reqp, &connp); if (code) continue; --- 1429,1435 ---- /* now make the call */ do { ! code = cm_ConnFromFID(&scp->fid, up, reqp, &connp); if (code) continue; Index: openafs/src/WINNT/afsd/cm_dns.c diff -c openafs/src/WINNT/afsd/cm_dns.c:1.12 openafs/src/WINNT/afsd/cm_dns.c:1.12.4.1 *** openafs/src/WINNT/afsd/cm_dns.c:1.12 Sat Nov 5 01:47:46 2005 --- openafs/src/WINNT/afsd/cm_dns.c Mon Jul 2 20:35:13 2007 *************** *** 707,712 **** --- 707,717 ---- struct sockaddr_in vlSockAddr; char query[1024]; + #ifdef AFS_FREELANCE_CLIENT + if ( stricmp(cellName, "Freelance.Local.Root") == 0 ) + return -1; + #endif /* AFS_FREELANCE_CLIENT */ + *numServers = 0; *ttl = 0; Index: openafs/src/WINNT/afsd/cm_freelance.c diff -c openafs/src/WINNT/afsd/cm_freelance.c:1.33.2.1 openafs/src/WINNT/afsd/cm_freelance.c:1.33.2.2 *** openafs/src/WINNT/afsd/cm_freelance.c:1.33.2.1 Sat Jun 24 16:41:54 2006 --- openafs/src/WINNT/afsd/cm_freelance.c Sun Jun 10 13:00:07 2007 *************** *** 157,163 **** cm_data.fakeDirVersion = cm_data.rootSCachep->dataVersion; // yj: first we make a call to cm_initLocalMountPoints ! // to read all the local mount points from an ini file cm_InitLocalMountPoints(); // then we make a call to InitFakeRootDir to create --- 157,163 ---- cm_data.fakeDirVersion = cm_data.rootSCachep->dataVersion; // yj: first we make a call to cm_initLocalMountPoints ! // to read all the local mount points from the registry cm_InitLocalMountPoints(); // then we make a call to InitFakeRootDir to create *************** *** 358,364 **** int cm_FakeRootFid(cm_fid_t *fidp) { fidp->cell = AFS_FAKE_ROOT_CELL_ID; /* root cell */ ! fidp->volume = AFS_FAKE_ROOT_VOL_ID; /* root.afs ? */ fidp->vnode = 0x1; fidp->unique = 0x1; return 0; --- 358,364 ---- int cm_FakeRootFid(cm_fid_t *fidp) { fidp->cell = AFS_FAKE_ROOT_CELL_ID; /* root cell */ ! fidp->volume = AFS_FAKE_ROOT_VOL_ID; /* root.afs ? */ fidp->vnode = 0x1; fidp->unique = 0x1; return 0; *************** *** 404,410 **** lock_ObtainMutex(&cm_Freelance_Lock); /* always scache then freelance lock */ for (i=0; inextp) { if (scp->fid.volume == aFid.volume && scp->fid.vnode == aFid.vnode && scp->fid.unique == aFid.unique --- 404,410 ---- lock_ObtainMutex(&cm_Freelance_Lock); /* always scache then freelance lock */ for (i=0; inextp) { if (scp->fid.volume == aFid.volume && scp->fid.vnode == aFid.vnode && scp->fid.unique == aFid.unique *************** *** 421,427 **** cm_ReleaseSCacheNoLock(scp); // take the scp out of the hash ! for (lscpp = &cm_data.hashTablep[hash], tscp = cm_data.hashTablep[hash]; tscp; lscpp = &tscp->nextp, tscp = tscp->nextp) { if (tscp == scp) { --- 421,427 ---- cm_ReleaseSCacheNoLock(scp); // take the scp out of the hash ! for (lscpp = &cm_data.scacheHashTablep[hash], tscp = cm_data.scacheHashTablep[hash]; tscp; lscpp = &tscp->nextp, tscp = tscp->nextp) { if (tscp == scp) { *************** *** 467,473 **** } ! // yj: open up the ini file and read all the local mount // points that are stored there. Part of the initialization // process for the freelance client. /* to be called while holding freelance lock unless during init. */ --- 467,473 ---- } ! // yj: open up the registry and read all the local mount // points that are stored there. Part of the initialization // process for the freelance client. /* to be called while holding freelance lock unless during init. */ *************** *** 518,524 **** if (code == 0) { cm_FreelanceAddMount(&rootCellName[1], &rootCellName[1], "root.cell.", 0, NULL); cm_FreelanceAddMount(rootCellName, &rootCellName[1], "root.cell.", 1, NULL); ! dwMountPoints = 2; } } --- 518,525 ---- if (code == 0) { cm_FreelanceAddMount(&rootCellName[1], &rootCellName[1], "root.cell.", 0, NULL); cm_FreelanceAddMount(rootCellName, &rootCellName[1], "root.cell.", 1, NULL); ! cm_FreelanceAddMount(".root", &rootCellName[1], "root.afs.", 1, NULL); ! dwMountPoints = 3; } } *************** *** 719,724 **** --- 720,726 ---- if (code == 0) { cm_FreelanceAddMount(&rootCellName[1], &rootCellName[1], "root.cell.", 0, NULL); cm_FreelanceAddMount(rootCellName, &rootCellName[1], "root.cell.", 1, NULL); + cm_FreelanceAddMount(".root", &rootCellName[1], "root.afs.", 1, NULL); } return 0; } Index: openafs/src/WINNT/afsd/cm_ioctl.c diff -c openafs/src/WINNT/afsd/cm_ioctl.c:1.73.2.12 openafs/src/WINNT/afsd/cm_ioctl.c:1.73.2.18 *** openafs/src/WINNT/afsd/cm_ioctl.c:1.73.2.12 Sat Apr 14 14:49:36 2007 --- openafs/src/WINNT/afsd/cm_ioctl.c Sat Jun 30 00:44:23 2007 *************** *** 32,38 **** #include #include "smb.h" - #include "cm_server.h" #ifndef DJGPP #include --- 32,37 ---- *************** *** 137,144 **** #endif lock_ObtainWrite(&cm_scacheLock); ! for (i=0; inextp) { if (scp->fid.volume == volume && scp->fid.cell == cell) { cm_HoldSCacheNoLock(scp); lock_ReleaseWrite(&cm_scacheLock); --- 136,143 ---- #endif lock_ObtainWrite(&cm_scacheLock); ! for (i=0; inextp) { if (scp->fid.volume == volume && scp->fid.cell == cell) { cm_HoldSCacheNoLock(scp); lock_ReleaseWrite(&cm_scacheLock); *************** *** 165,172 **** int hash; lock_ObtainWrite(&cm_scacheLock); ! for (hash=0; hash < cm_data.hashTableSize; hash++) { ! for (scp=cm_data.hashTablep[hash]; scp; scp=scp->nextp) { cm_HoldSCacheNoLock(scp); lock_ReleaseWrite(&cm_scacheLock); lock_ObtainMutex(&scp->mx); --- 164,171 ---- int hash; lock_ObtainWrite(&cm_scacheLock); ! for (hash=0; hash < cm_data.scacheHashTableSize; hash++) { ! for (scp=cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) { cm_HoldSCacheNoLock(scp); lock_ReleaseWrite(&cm_scacheLock); lock_ObtainMutex(&scp->mx); *************** *** 238,244 **** and it returns the correct (full) path. therefore, there is no drive letter, and the path is absolute. */ code = cm_NameI(cm_data.rootSCachep, relativePath, ! CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, "", reqp, scpp); if (code) { --- 237,243 ---- and it returns the correct (full) path. therefore, there is no drive letter, and the path is absolute. */ code = cm_NameI(cm_data.rootSCachep, relativePath, ! CM_FLAG_CASEFOLD, userp, "", reqp, scpp); if (code) { *************** *** 332,338 **** return code; } ! code = cm_NameI(substRootp, relativePath, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, NULL, reqp, scpp); if (code) { cm_ReleaseSCache(substRootp); --- 331,338 ---- return code; } ! code = cm_NameI(substRootp, relativePath, ! CM_FLAG_CASEFOLD, userp, NULL, reqp, scpp); if (code) { cm_ReleaseSCache(substRootp); *************** *** 543,549 **** do { acl.AFSOpaque_val = ioctlp->outDatap; acl.AFSOpaque_len = 0; ! code = cm_Conn(&scp->fid, userp, &req, &connp); if (code) continue; callp = cm_GetRxConn(connp); --- 543,549 ---- do { acl.AFSOpaque_val = ioctlp->outDatap; acl.AFSOpaque_len = 0; ! code = cm_ConnFromFID(&scp->fid, userp, &req, &connp); if (code) continue; callp = cm_GetRxConn(connp); *************** *** 625,631 **** do { acl.AFSOpaque_val = ioctlp->inDatap; acl.AFSOpaque_len = (u_int)strlen(ioctlp->inDatap)+1; ! code = cm_Conn(&scp->fid, userp, &req, &connp); if (code) continue; callp = cm_GetRxConn(connp); --- 625,631 ---- do { acl.AFSOpaque_val = ioctlp->inDatap; acl.AFSOpaque_len = (u_int)strlen(ioctlp->inDatap)+1; ! code = cm_ConnFromFID(&scp->fid, userp, &req, &connp); if (code) continue; callp = cm_GetRxConn(connp); *************** *** 657,664 **** cm_InitReq(&req); lock_ObtainWrite(&cm_scacheLock); ! for (i=0; inextp) { cm_HoldSCacheNoLock(scp); lock_ReleaseWrite(&cm_scacheLock); --- 657,664 ---- cm_InitReq(&req); lock_ObtainWrite(&cm_scacheLock); ! for (i=0; inextp) { cm_HoldSCacheNoLock(scp); lock_ReleaseWrite(&cm_scacheLock); *************** *** 741,747 **** return CM_ERROR_READONLY; } ! code = cm_GetVolumeByID(cellp, scp->fid.volume, userp, &req, &tvp); if (code) { cm_ReleaseSCache(scp); return code; --- 741,748 ---- return CM_ERROR_READONLY; } ! code = cm_GetVolumeByID(cellp, scp->fid.volume, userp, &req, ! CM_GETVOL_FLAG_CREATE, &tvp); if (code) { cm_ReleaseSCache(scp); return code; *************** *** 768,774 **** } do { ! code = cm_Conn(&scp->fid, userp, &req, &tcp); if (code) continue; callp = cm_GetRxConn(tcp); --- 769,775 ---- } do { ! code = cm_ConnFromFID(&scp->fid, userp, &req, &tcp); if (code) continue; callp = cm_GetRxConn(tcp); *************** *** 811,817 **** cm_scache_t *scp; char offLineMsg[256]; char motd[256]; ! cm_conn_t *tcp; register long code; AFSFetchVolumeStatus volStat; register char *cp; --- 812,818 ---- cm_scache_t *scp; char offLineMsg[256]; char motd[256]; ! cm_conn_t *connp; register long code; AFSFetchVolumeStatus volStat; register char *cp; *************** *** 830,844 **** OfflineMsg = offLineMsg; MOTD = motd; do { ! code = cm_Conn(&scp->fid, userp, &req, &tcp); if (code) continue; ! callp = cm_GetRxConn(tcp); code = RXAFS_GetVolumeStatus(callp, scp->fid.volume, &volStat, &Name, &OfflineMsg, &MOTD); rx_PutConnection(callp); ! } while (cm_Analyze(tcp, userp, &req, &scp->fid, NULL, NULL, NULL, code)); code = cm_MapRPCError(code, &req); cm_ReleaseSCache(scp); --- 831,845 ---- OfflineMsg = offLineMsg; MOTD = motd; do { ! code = cm_ConnFromFID(&scp->fid, userp, &req, &connp); if (code) continue; ! callp = cm_GetRxConn(connp); code = RXAFS_GetVolumeStatus(callp, scp->fid.volume, &volStat, &Name, &OfflineMsg, &MOTD); rx_PutConnection(callp); ! } while (cm_Analyze(connp, userp, &req, &scp->fid, NULL, NULL, NULL, code)); code = cm_MapRPCError(code, &req); cm_ReleaseSCache(scp); *************** *** 945,951 **** if (!cellp) return CM_ERROR_NOSUCHCELL; ! code = cm_GetVolumeByID(cellp, volume, userp, &req, &tvp); if (code) return code; cp = ioctlp->outDatap; --- 946,952 ---- if (!cellp) return CM_ERROR_NOSUCHCELL; ! code = cm_GetVolumeByID(cellp, volume, userp, &req, CM_GETVOL_FLAG_CREATE, &tvp); if (code) return code; cp = ioctlp->outDatap; *************** *** 959,965 **** cp += sizeof(long); } lock_ReleaseRead(&cm_serverLock); ! cm_FreeServerList(tsrpp); lock_ReleaseMutex(&tvp->mx); /* still room for terminating NULL, add it on */ --- 960,966 ---- cp += sizeof(long); } lock_ReleaseRead(&cm_serverLock); ! cm_FreeServerList(tsrpp, 0); lock_ReleaseMutex(&tvp->mx); /* still room for terminating NULL, add it on */ *************** *** 1267,1273 **** } lock_ObtainRead(&cm_cellLock); ! for (tcellp = cm_data.allCellsp; tcellp; tcellp = tcellp->nextp) { if (whichCell == 0) break; whichCell--; } --- 1268,1274 ---- } lock_ObtainRead(&cm_cellLock); ! for (tcellp = cm_data.allCellsp; tcellp; tcellp = tcellp->allNextp) { if (whichCell == 0) break; whichCell--; } *************** *** 1324,1335 **** cm_SkipIoctlPath(ioctlp); lock_ObtainWrite(&cm_cellLock); ! for (cp = cm_data.allCellsp; cp; cp=cp->nextp) { long code; lock_ObtainMutex(&cp->mx); /* delete all previous server lists - cm_FreeServerList will ask for write on cm_ServerLock*/ ! cm_FreeServerList(&cp->vlServersp); cp->vlServersp = NULL; code = cm_SearchCellFile(cp->name, cp->name, cm_AddCellProc, cp); #ifdef AFS_AFSDB_ENV --- 1325,1336 ---- cm_SkipIoctlPath(ioctlp); lock_ObtainWrite(&cm_cellLock); ! for (cp = cm_data.allCellsp; cp; cp=cp->allNextp) { long code; lock_ObtainMutex(&cp->mx); /* delete all previous server lists - cm_FreeServerList will ask for write on cm_ServerLock*/ ! cm_FreeServerList(&cp->vlServersp, CM_FREESERVERLIST_DELETE); cp->vlServersp = NULL; code = cm_SearchCellFile(cp->name, cp->name, cm_AddCellProc, cp); #ifdef AFS_AFSDB_ENV *************** *** 2755,2762 **** #endif /* dump all interesting data */ ! cm_DumpSCache(hLogFile, cookie, 1); cm_DumpVolumes(hLogFile, cookie, 1); cm_DumpBufHashTable(hLogFile, cookie, 1); smb_DumpVCP(hLogFile, cookie, 1); --- 2756,2764 ---- #endif /* dump all interesting data */ ! cm_DumpCells(hLogFile, cookie, 1); cm_DumpVolumes(hLogFile, cookie, 1); + cm_DumpSCache(hLogFile, cookie, 1); cm_DumpBufHashTable(hLogFile, cookie, 1); smb_DumpVCP(hLogFile, cookie, 1); *************** *** 2790,2799 **** lock_ReleaseRead(&cm_serverLock); if (!(tsp->flags & CM_SERVERFLAG_DOWN)) { allDown = 0; ! if (tsrp->status == busy) { allOffline = 0; someBusy = 1; ! } else if (tsrp->status == offline) { allBusy = 0; someOffline = 1; } else { --- 2792,2801 ---- lock_ReleaseRead(&cm_serverLock); if (!(tsp->flags & CM_SERVERFLAG_DOWN)) { allDown = 0; ! if (tsrp->status == srv_busy) { allOffline = 0; someBusy = 1; ! } else if (tsrp->status == srv_offline) { allBusy = 0; someOffline = 1; } else { *************** *** 2828,2835 **** cm_scache_t *scp; cm_cell_t *cellp; cm_volume_t *tvp; ! cm_serverRef_t **tsrpp; ! unsigned long volume; cm_req_t req; cm_InitReq(&req); --- 2830,2837 ---- cm_scache_t *scp; cm_cell_t *cellp; cm_volume_t *tvp; ! cm_vol_state_t *statep; ! afs_uint32 volume; cm_req_t req; cm_InitReq(&req); *************** *** 2847,2863 **** if (!cellp) return CM_ERROR_NOSUCHCELL; ! code = cm_GetVolumeByID(cellp, volume, userp, &req, &tvp); if (code) return code; ! lock_ObtainMutex(&tvp->mx); ! tsrpp = cm_GetVolServers(tvp, volume); ! code = cm_CheckServersStatus(*tsrpp); ! cm_FreeServerList(tsrpp); ! lock_ReleaseMutex(&tvp->mx); cm_PutVolume(tvp); ! return 0; } --- 2849,2882 ---- if (!cellp) return CM_ERROR_NOSUCHCELL; ! code = cm_GetVolumeByID(cellp, volume, userp, &req, CM_GETVOL_FLAG_CREATE, &tvp); if (code) return code; ! if (volume == tvp->rw.ID) ! statep = &tvp->rw; ! else if (volume == tvp->ro.ID) ! statep = &tvp->ro; ! else ! statep = &tvp->bk; ! ! switch (statep->state) { ! case vl_online: ! case vl_unknown: ! code = 0; ! break; ! case vl_busy: ! code = CM_ERROR_ALLBUSY; ! break; ! case vl_offline: ! code = CM_ERROR_ALLOFFLINE; ! break; ! case vl_alldown: ! code = CM_ERROR_ALLDOWN; ! break; ! } cm_PutVolume(tvp); ! return code; } Index: openafs/src/WINNT/afsd/cm_memmap.c diff -c openafs/src/WINNT/afsd/cm_memmap.c:1.7.2.4 openafs/src/WINNT/afsd/cm_memmap.c:1.7.2.6 *** openafs/src/WINNT/afsd/cm_memmap.c:1.7.2.4 Sun Feb 4 22:41:41 2007 --- openafs/src/WINNT/afsd/cm_memmap.c Fri Jun 22 18:16:39 2007 *************** *** 39,44 **** --- 39,60 ---- } afs_uint64 + ComputeSizeOfCellHT(DWORD maxcells) + { + afs_uint64 size; + size = osi_PrimeLessThan((afs_uint32)(maxcells/7 + 1)) * sizeof(cm_cell_t *); + return size; + } + + afs_uint64 + ComputeSizeOfVolumeHT(DWORD maxvols) + { + afs_uint64 size; + size = osi_PrimeLessThan((afs_uint32)(maxvols/7 + 1)) * sizeof(cm_volume_t *); + return size; + } + + afs_uint64 ComputeSizeOfCells(DWORD maxcells) { afs_uint64 size; *************** *** 66,72 **** ComputeSizeOfSCacheHT(DWORD stats) { afs_uint64 size; ! size = (stats + 10) / 2 * sizeof(cm_scache_t *);; return size; } --- 82,88 ---- ComputeSizeOfSCacheHT(DWORD stats) { afs_uint64 size; ! size = osi_PrimeLessThan(stats / 2 + 1) * sizeof(cm_scache_t *);; return size; } *************** *** 109,115 **** --- 125,133 ---- size = ComputeSizeOfConfigData() + ComputeSizeOfVolumes(maxVols) + + 4 * ComputeSizeOfVolumeHT(maxVols) + ComputeSizeOfCells(maxCells) + + 2 * ComputeSizeOfCellHT(maxCells) + ComputeSizeOfACLCache(stats) + ComputeSizeOfSCache(stats) + ComputeSizeOfSCacheHT(stats) *************** *** 221,231 **** afsi_log(" blockSize = %d", cm_data.blockSize); afsi_log(" bufferSize = %d", cm_data.bufferSize); afsi_log(" cacheType = %d", cm_data.cacheType); afsi_log(" currentVolumes = %d", cm_data.currentVolumes); afsi_log(" maxVolumes = %d", cm_data.maxVolumes); afsi_log(" currentCells = %d", cm_data.currentCells); afsi_log(" maxCells = %d", cm_data.maxCells); ! afsi_log(" hashTableSize = %d", cm_data.hashTableSize); afsi_log(" currentSCaches = %d", cm_data.currentSCaches); afsi_log(" maxSCaches = %d", cm_data.maxSCaches); --- 239,251 ---- afsi_log(" blockSize = %d", cm_data.blockSize); afsi_log(" bufferSize = %d", cm_data.bufferSize); afsi_log(" cacheType = %d", cm_data.cacheType); + afsi_log(" volumeHashTableSize = %d", cm_data.volumeHashTableSize); afsi_log(" currentVolumes = %d", cm_data.currentVolumes); afsi_log(" maxVolumes = %d", cm_data.maxVolumes); + afsi_log(" cellHashTableSize = %d", cm_data.cellHashTableSize); afsi_log(" currentCells = %d", cm_data.currentCells); afsi_log(" maxCells = %d", cm_data.maxCells); ! afsi_log(" scacheHashTableSize = %d", cm_data.scacheHashTableSize); afsi_log(" currentSCaches = %d", cm_data.currentSCaches); afsi_log(" maxSCaches = %d", cm_data.maxSCaches); *************** *** 404,414 **** fprintf(stderr," blockSize = %d\n", config_data_p->blockSize); fprintf(stderr," bufferSize = %d\n", config_data_p->bufferSize); fprintf(stderr," cacheType = %d\n", config_data_p->cacheType); fprintf(stderr," currentVolumes = %d\n", config_data_p->currentVolumes); fprintf(stderr," maxVolumes = %d\n", config_data_p->maxVolumes); fprintf(stderr," currentCells = %d\n", config_data_p->currentCells); fprintf(stderr," maxCells = %d\n", config_data_p->maxCells); ! fprintf(stderr," hashTableSize = %d\n", config_data_p->hashTableSize); fprintf(stderr," currentSCaches = %d\n", config_data_p->currentSCaches); fprintf(stderr," maxSCaches = %d\n", config_data_p->maxSCaches); cm_data = *config_data_p; --- 424,436 ---- fprintf(stderr," blockSize = %d\n", config_data_p->blockSize); fprintf(stderr," bufferSize = %d\n", config_data_p->bufferSize); fprintf(stderr," cacheType = %d\n", config_data_p->cacheType); + fprintf(stderr," volumeHashTableSize = %d", config_data_p->volumeHashTableSize); fprintf(stderr," currentVolumes = %d\n", config_data_p->currentVolumes); fprintf(stderr," maxVolumes = %d\n", config_data_p->maxVolumes); + fprintf(stderr," cellHashTableSize = %d", config_data_p->cellHashTableSize); fprintf(stderr," currentCells = %d\n", config_data_p->currentCells); fprintf(stderr," maxCells = %d\n", config_data_p->maxCells); ! fprintf(stderr," scacheHashTableSize = %d\n", config_data_p->scacheHashTableSize); fprintf(stderr," currentSCaches = %d\n", config_data_p->currentSCaches); fprintf(stderr," maxSCaches = %d\n", config_data_p->maxSCaches); cm_data = *config_data_p; *************** *** 802,812 **** afsi_log(" blockSize = %d", config_data_p->blockSize); afsi_log(" bufferSize = %d", config_data_p->bufferSize); afsi_log(" cacheType = %d", config_data_p->cacheType); afsi_log(" currentVolumes = %d", config_data_p->currentVolumes); afsi_log(" maxVolumes = %d", config_data_p->maxVolumes); afsi_log(" currentCells = %d", config_data_p->currentCells); afsi_log(" maxCells = %d", config_data_p->maxCells); ! afsi_log(" hashTableSize = %d", config_data_p->hashTableSize); afsi_log(" currentSCaches = %d", config_data_p->currentSCaches); afsi_log(" maxSCaches = %d", config_data_p->maxSCaches); --- 824,836 ---- afsi_log(" blockSize = %d", config_data_p->blockSize); afsi_log(" bufferSize = %d", config_data_p->bufferSize); afsi_log(" cacheType = %d", config_data_p->cacheType); + afsi_log(" volumeHashTableSize = %d", config_data_p->volumeHashTableSize); afsi_log(" currentVolumes = %d", config_data_p->currentVolumes); afsi_log(" maxVolumes = %d", config_data_p->maxVolumes); + afsi_log(" cellHashTableSize = %d", config_data_p->cellHashTableSize); afsi_log(" currentCells = %d", config_data_p->currentCells); afsi_log(" maxCells = %d", config_data_p->maxCells); ! afsi_log(" scacheHashTableSize = %d", config_data_p->scacheHashTableSize); afsi_log(" currentSCaches = %d", config_data_p->currentSCaches); afsi_log(" maxSCaches = %d", config_data_p->maxSCaches); *************** *** 827,833 **** cm_data.chunkSize = chunkSize; cm_data.blockSize = CM_CONFIGDEFAULT_BLOCKSIZE; cm_data.bufferSize = mappingSize; ! cm_data.hashTableSize = osi_PrimeLessThan(stats / 2 + 1); if (virtualCache) { cm_data.cacheType = CM_BUF_CACHETYPE_VIRTUAL; } else { --- 851,859 ---- cm_data.chunkSize = chunkSize; cm_data.blockSize = CM_CONFIGDEFAULT_BLOCKSIZE; cm_data.bufferSize = mappingSize; ! cm_data.scacheHashTableSize = osi_PrimeLessThan(stats / 2 + 1); ! cm_data.volumeHashTableSize = osi_PrimeLessThan((afs_uint32)(maxVols/7 + 1)); ! cm_data.cellHashTableSize = osi_PrimeLessThan((afs_uint32)(maxCells/7 + 1)); if (virtualCache) { cm_data.cacheType = CM_BUF_CACHETYPE_VIRTUAL; } else { *************** *** 844,860 **** baseAddress += ComputeSizeOfConfigData(); cm_data.volumeBaseAddress = (cm_volume_t *) baseAddress; baseAddress += ComputeSizeOfVolumes(maxVols); cm_data.cellBaseAddress = (cm_cell_t *) baseAddress; baseAddress += ComputeSizeOfCells(maxCells); cm_data.aclBaseAddress = (cm_aclent_t *) baseAddress; baseAddress += ComputeSizeOfACLCache(stats); cm_data.scacheBaseAddress = (cm_scache_t *) baseAddress; baseAddress += ComputeSizeOfSCache(stats); ! cm_data.hashTablep = (cm_scache_t **) baseAddress; baseAddress += ComputeSizeOfSCacheHT(stats); cm_data.dnlcBaseAddress = (cm_nc_t *) baseAddress; baseAddress += ComputeSizeOfDNLCache(); ! cm_data.buf_hashTablepp = (cm_buf_t **) baseAddress; baseAddress += ComputeSizeOfDataHT(cacheBlocks); cm_data.buf_fileHashTablepp = (cm_buf_t **) baseAddress; baseAddress += ComputeSizeOfDataHT(cacheBlocks); --- 870,898 ---- baseAddress += ComputeSizeOfConfigData(); cm_data.volumeBaseAddress = (cm_volume_t *) baseAddress; baseAddress += ComputeSizeOfVolumes(maxVols); + cm_data.volumeNameHashTablep = (cm_volume_t **)baseAddress; + baseAddress += ComputeSizeOfVolumeHT(maxVols); + cm_data.volumeRWIDHashTablep = (cm_volume_t **)baseAddress; + baseAddress += ComputeSizeOfVolumeHT(maxVols); + cm_data.volumeROIDHashTablep = (cm_volume_t **)baseAddress; + baseAddress += ComputeSizeOfVolumeHT(maxVols); + cm_data.volumeBKIDHashTablep = (cm_volume_t **)baseAddress; + baseAddress += ComputeSizeOfVolumeHT(maxVols); + cm_data.cellNameHashTablep = (cm_cell_t **)baseAddress; + baseAddress += ComputeSizeOfCellHT(maxCells); + cm_data.cellIDHashTablep = (cm_cell_t **)baseAddress; + baseAddress += ComputeSizeOfCellHT(maxCells); cm_data.cellBaseAddress = (cm_cell_t *) baseAddress; baseAddress += ComputeSizeOfCells(maxCells); cm_data.aclBaseAddress = (cm_aclent_t *) baseAddress; baseAddress += ComputeSizeOfACLCache(stats); cm_data.scacheBaseAddress = (cm_scache_t *) baseAddress; baseAddress += ComputeSizeOfSCache(stats); ! cm_data.scacheHashTablep = (cm_scache_t **) baseAddress; baseAddress += ComputeSizeOfSCacheHT(stats); cm_data.dnlcBaseAddress = (cm_nc_t *) baseAddress; baseAddress += ComputeSizeOfDNLCache(); ! cm_data.buf_scacheHashTablepp = (cm_buf_t **) baseAddress; baseAddress += ComputeSizeOfDataHT(cacheBlocks); cm_data.buf_fileHashTablepp = (cm_buf_t **) baseAddress; baseAddress += ComputeSizeOfDataHT(cacheBlocks); Index: openafs/src/WINNT/afsd/cm_memmap.h diff -c openafs/src/WINNT/afsd/cm_memmap.h:1.3.4.2 openafs/src/WINNT/afsd/cm_memmap.h:1.3.4.4 *** openafs/src/WINNT/afsd/cm_memmap.h:1.3.4.2 Sun Feb 4 22:41:41 2007 --- openafs/src/WINNT/afsd/cm_memmap.h Fri Jun 22 18:16:39 2007 *************** *** 51,64 **** cm_aclent_t * aclLRUp; cm_aclent_t * aclLRUEndp; ! cm_scache_t ** hashTablep; ! afs_uint32 hashTableSize; afs_uint32 currentSCaches; afs_uint32 maxSCaches; cm_scache_t * scacheLRUFirstp; cm_scache_t * scacheLRULastp; cm_nc_t * ncfreelist; cm_nc_t * nameCache; cm_nc_t ** nameHash; --- 51,77 ---- cm_aclent_t * aclLRUp; cm_aclent_t * aclLRUEndp; ! cm_scache_t ** scacheHashTablep; ! afs_uint32 scacheHashTableSize; + cm_scache_t * allSCachesp; afs_uint32 currentSCaches; afs_uint32 maxSCaches; cm_scache_t * scacheLRUFirstp; cm_scache_t * scacheLRULastp; + cm_cell_t ** cellNameHashTablep; + cm_cell_t ** cellIDHashTablep; + afs_uint32 cellHashTableSize; + + cm_volume_t ** volumeNameHashTablep; + cm_volume_t ** volumeRWIDHashTablep; + cm_volume_t ** volumeROIDHashTablep; + cm_volume_t ** volumeBKIDHashTablep; + afs_uint32 volumeHashTableSize; + cm_volume_t * volumeLRUFirstp; + cm_volume_t * volumeLRULastp; + cm_nc_t * ncfreelist; cm_nc_t * nameCache; cm_nc_t ** nameHash; *************** *** 67,73 **** cm_buf_t * buf_freeListEndp; cm_buf_t * buf_dirtyListp; cm_buf_t * buf_dirtyListEndp; ! cm_buf_t ** buf_hashTablepp; cm_buf_t ** buf_fileHashTablepp; cm_buf_t * buf_allp; afs_uint64 buf_nbuffers; --- 80,86 ---- cm_buf_t * buf_freeListEndp; cm_buf_t * buf_dirtyListp; cm_buf_t * buf_dirtyListEndp; ! cm_buf_t ** buf_scacheHashTablepp; cm_buf_t ** buf_fileHashTablepp; cm_buf_t * buf_allp; afs_uint64 buf_nbuffers; Index: openafs/src/WINNT/afsd/cm_scache.c diff -c openafs/src/WINNT/afsd/cm_scache.c:1.35.2.34 openafs/src/WINNT/afsd/cm_scache.c:1.35.2.39 *** openafs/src/WINNT/afsd/cm_scache.c:1.35.2.34 Wed May 16 11:51:05 2007 --- openafs/src/WINNT/afsd/cm_scache.c Fri Jul 6 19:22:03 2007 *************** *** 42,48 **** #endif /* must be called with cm_scacheLock write-locked! */ ! void cm_AdjustLRU(cm_scache_t *scp) { if (scp == cm_data.scacheLRULastp) cm_data.scacheLRULastp = (cm_scache_t *) osi_QPrev(&scp->q); --- 42,48 ---- #endif /* must be called with cm_scacheLock write-locked! */ ! void cm_AdjustScacheLRU(cm_scache_t *scp) { if (scp == cm_data.scacheLRULastp) cm_data.scacheLRULastp = (cm_scache_t *) osi_QPrev(&scp->q); *************** *** 62,68 **** if (scp->flags & CM_SCACHEFLAG_INHASH) { /* hash it out first */ i = CM_SCACHE_HASH(&scp->fid); ! for (lscpp = &cm_data.hashTablep[i], tscp = cm_data.hashTablep[i]; tscp; lscpp = &tscp->nextp, tscp = tscp->nextp) { if (tscp == scp) { --- 62,68 ---- if (scp->flags & CM_SCACHEFLAG_INHASH) { /* hash it out first */ i = CM_SCACHE_HASH(&scp->fid); ! for (lscpp = &cm_data.scacheHashTablep[i], tscp = cm_data.scacheHashTablep[i]; tscp; lscpp = &tscp->nextp, tscp = tscp->nextp) { if (tscp == scp) { *************** *** 162,179 **** scp->bulkStatProgress = hzero; scp->waitCount = 0; scp->fid.vnode = 0; scp->fid.volume = 0; scp->fid.unique = 0; scp->fid.cell = 0; - /* discard callback */ - if (scp->cbServerp) { - cm_PutServer(scp->cbServerp); - scp->cbServerp = NULL; - } - scp->cbExpires = 0; - /* remove from dnlc */ cm_dnlcPurgedp(scp); cm_dnlcPurgevp(scp); --- 162,178 ---- scp->bulkStatProgress = hzero; scp->waitCount = 0; + if (scp->cbServerp) { + cm_PutServer(scp->cbServerp); + scp->cbServerp = NULL; + } + scp->cbExpires = 0; + scp->fid.vnode = 0; scp->fid.volume = 0; scp->fid.unique = 0; scp->fid.cell = 0; /* remove from dnlc */ cm_dnlcPurgedp(scp); cm_dnlcPurgevp(scp); *************** *** 222,228 **** scp; scp = (cm_scache_t *) osi_QPrev(&scp->q)) { ! osi_assert(scp >= cm_data.scacheBaseAddress && scp < (cm_scache_t *)cm_data.hashTablep); if (scp->refCount == 0) { if (scp->flags & CM_SCACHEFLAG_DELETED) { --- 221,227 ---- scp; scp = (cm_scache_t *) osi_QPrev(&scp->q)) { ! osi_assert(scp >= cm_data.scacheBaseAddress && scp < (cm_scache_t *)cm_data.scacheHashTablep); if (scp->refCount == 0) { if (scp->flags & CM_SCACHEFLAG_DELETED) { *************** *** 233,239 **** /* now remove from the LRU queue and put it back at the * head of the LRU queue. */ ! cm_AdjustLRU(scp); /* and we're done */ return scp; --- 232,238 ---- /* now remove from the LRU queue and put it back at the * head of the LRU queue. */ ! cm_AdjustScacheLRU(scp); /* and we're done */ return scp; *************** *** 244,250 **** /* now remove from the LRU queue and put it back at the * head of the LRU queue. */ ! cm_AdjustLRU(scp); /* and we're done */ return scp; --- 243,249 ---- /* now remove from the LRU queue and put it back at the * head of the LRU queue. */ ! cm_AdjustScacheLRU(scp); /* and we're done */ return scp; *************** *** 258,297 **** /* There were no deleted scache objects that we could use. Try to find * one that simply hasn't been used in a while. */ ! for ( scp = cm_data.scacheLRULastp; ! scp; ! scp = (cm_scache_t *) osi_QPrev(&scp->q)) ! { ! /* It is possible for the refCount to be zero and for there still ! * to be outstanding dirty buffers. If there are dirty buffers, ! * we must not recycle the scp. */ ! if (scp->refCount == 0 && scp->bufReadsp == NULL && scp->bufWritesp == NULL) { ! if (!buf_DirtyBuffersExist(&scp->fid)) { ! if (!cm_RecycleSCache(scp, 0)) { ! /* we found an entry, so return it */ ! /* now remove from the LRU queue and put it back at the ! * head of the LRU queue. ! */ ! cm_AdjustLRU(scp); ! ! /* and we're done */ ! return scp; ! } ! } else { ! osi_Log1(afsd_logp,"GetNewSCache dirty buffers exist scp 0x%x", scp); ! } ! } ! } ! osi_Log1(afsd_logp, "GetNewSCache all scache entries in use (retry = %d)", retry); ! ! return NULL; } /* if we get here, we should allocate a new scache entry. We either are below * quota or we have a leak and need to allocate a new one to avoid panicing. */ scp = cm_data.scacheBaseAddress + cm_data.currentSCaches; ! osi_assert(scp >= cm_data.scacheBaseAddress && scp < (cm_scache_t *)cm_data.hashTablep); memset(scp, 0, sizeof(cm_scache_t)); scp->magic = CM_SCACHE_MAGIC; lock_InitializeMutex(&scp->mx, "cm_scache_t mutex"); --- 257,296 ---- /* There were no deleted scache objects that we could use. Try to find * one that simply hasn't been used in a while. */ ! for ( scp = cm_data.scacheLRULastp; ! scp; ! scp = (cm_scache_t *) osi_QPrev(&scp->q)) ! { ! /* It is possible for the refCount to be zero and for there still ! * to be outstanding dirty buffers. If there are dirty buffers, ! * we must not recycle the scp. */ ! if (scp->refCount == 0 && scp->bufReadsp == NULL && scp->bufWritesp == NULL) { ! if (!buf_DirtyBuffersExist(&scp->fid)) { ! if (!cm_RecycleSCache(scp, 0)) { ! /* we found an entry, so return it */ ! /* now remove from the LRU queue and put it back at the ! * head of the LRU queue. ! */ ! cm_AdjustScacheLRU(scp); ! ! /* and we're done */ ! return scp; ! } ! } else { ! osi_Log1(afsd_logp,"GetNewSCache dirty buffers exist scp 0x%x", scp); ! } ! } ! } ! osi_Log1(afsd_logp, "GetNewSCache all scache entries in use (retry = %d)", retry); ! ! return NULL; } /* if we get here, we should allocate a new scache entry. We either are below * quota or we have a leak and need to allocate a new one to avoid panicing. */ scp = cm_data.scacheBaseAddress + cm_data.currentSCaches; ! osi_assert(scp >= cm_data.scacheBaseAddress && scp < (cm_scache_t *)cm_data.scacheHashTablep); memset(scp, 0, sizeof(cm_scache_t)); scp->magic = CM_SCACHE_MAGIC; lock_InitializeMutex(&scp->mx, "cm_scache_t mutex"); *************** *** 305,310 **** --- 304,311 ---- cm_data.currentSCaches++; cm_dnlcPurgedp(scp); /* make doubly sure that this is not in dnlc */ cm_dnlcPurgevp(scp); + scp->allNextp = cm_data.allSCachesp; + cm_data.allSCachesp = scp; return scp; } *************** *** 419,426 **** } } ! for ( i=0; i < cm_data.hashTableSize; i++ ) { ! for ( scp = cm_data.hashTablep[i]; scp; scp = scp->nextp ) { if (scp->magic != CM_SCACHE_MAGIC) { afsi_log("cm_ValidateSCache failure: scp->magic != CM_SCACHE_MAGIC"); fprintf(stderr, "cm_ValidateSCache failure: scp->magic != CM_SCACHE_MAGIC\n"); --- 420,427 ---- } } ! for ( i=0; i < cm_data.scacheHashTableSize; i++ ) { ! for ( scp = cm_data.scacheHashTablep[i]; scp; scp = scp->nextp ) { if (scp->magic != CM_SCACHE_MAGIC) { afsi_log("cm_ValidateSCache failure: scp->magic != CM_SCACHE_MAGIC"); fprintf(stderr, "cm_ValidateSCache failure: scp->magic != CM_SCACHE_MAGIC\n"); *************** *** 447,467 **** return cm_dnlcValidate(); } long cm_ShutdownSCache(void) { cm_scache_t * scp; ! for ( scp = cm_data.scacheLRULastp; scp; ! scp = (cm_scache_t *) osi_QPrev(&scp->q) ) { if (scp->randomACLp) { lock_ObtainMutex(&scp->mx); cm_FreeAllACLEnts(scp); lock_ReleaseMutex(&scp->mx); } lock_FinalizeMutex(&scp->mx); lock_FinalizeRWLock(&scp->bufCreateLock); } return cm_dnlcShutdown(); } --- 448,501 ---- return cm_dnlcValidate(); } + void + cm_SuspendSCache(void) + { + cm_scache_t * scp; + + cm_GiveUpAllCallbacksAllServers(); + + lock_ObtainWrite(&cm_scacheLock); + for ( scp = cm_data.allSCachesp; scp; + scp = scp->allNextp ) { + if (scp->cbServerp) { + cm_PutServer(scp->cbServerp); + scp->cbServerp = NULL; + } + scp->cbExpires = 0; + scp->flags &= ~CM_SCACHEFLAG_CALLBACK; + } + lock_ReleaseWrite(&cm_scacheLock); + } + long cm_ShutdownSCache(void) { cm_scache_t * scp; ! lock_ObtainWrite(&cm_scacheLock); ! ! for ( scp = cm_data.allSCachesp; scp; ! scp = scp->allNextp ) { if (scp->randomACLp) { lock_ObtainMutex(&scp->mx); cm_FreeAllACLEnts(scp); lock_ReleaseMutex(&scp->mx); } + + if (scp->cbServerp) { + cm_PutServer(scp->cbServerp); + scp->cbServerp = NULL; + } + scp->cbExpires = 0; + scp->flags &= ~CM_SCACHEFLAG_CALLBACK; + lock_FinalizeMutex(&scp->mx); lock_FinalizeRWLock(&scp->bufCreateLock); } + lock_ReleaseWrite(&cm_scacheLock); + + cm_GiveUpAllCallbacksAllServers(); return cm_dnlcShutdown(); } *************** *** 473,487 **** if (osi_Once(&once)) { lock_InitializeRWLock(&cm_scacheLock, "cm_scacheLock"); if ( newFile ) { ! memset(cm_data.hashTablep, 0, sizeof(cm_scache_t *) * cm_data.hashTableSize); cm_data.currentSCaches = 0; cm_data.maxSCaches = maxSCaches; cm_data.scacheLRUFirstp = cm_data.scacheLRULastp = NULL; } else { cm_scache_t * scp; ! for ( scp = cm_data.scacheLRULastp; scp; ! scp = (cm_scache_t *) osi_QPrev(&scp->q) ) { lock_InitializeMutex(&scp->mx, "cm_scache_t mutex"); lock_InitializeRWLock(&scp->bufCreateLock, "cm_scache_t bufCreateLock"); --- 507,522 ---- if (osi_Once(&once)) { lock_InitializeRWLock(&cm_scacheLock, "cm_scacheLock"); if ( newFile ) { ! memset(cm_data.scacheHashTablep, 0, sizeof(cm_scache_t *) * cm_data.scacheHashTableSize); ! cm_data.allSCachesp = NULL; cm_data.currentSCaches = 0; cm_data.maxSCaches = maxSCaches; cm_data.scacheLRUFirstp = cm_data.scacheLRULastp = NULL; } else { cm_scache_t * scp; ! for ( scp = cm_data.allSCachesp; scp; ! scp = scp->allNextp ) { lock_InitializeMutex(&scp->mx, "cm_scache_t mutex"); lock_InitializeRWLock(&scp->bufCreateLock, "cm_scache_t bufCreateLock"); *************** *** 523,532 **** } lock_ObtainWrite(&cm_scacheLock); ! for (scp=cm_data.hashTablep[hash]; scp; scp=scp->nextp) { if (cm_FidCmp(fidp, &scp->fid) == 0) { cm_HoldSCacheNoLock(scp); ! cm_AdjustLRU(scp); lock_ReleaseWrite(&cm_scacheLock); return scp; } --- 558,567 ---- } lock_ObtainWrite(&cm_scacheLock); ! for (scp=cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) { if (cm_FidCmp(fidp, &scp->fid) == 0) { cm_HoldSCacheNoLock(scp); ! cm_AdjustScacheLRU(scp); lock_ReleaseWrite(&cm_scacheLock); return scp; } *************** *** 567,573 **** // yj: check if we have the scp, if so, we don't need // to do anything else lock_ObtainWrite(&cm_scacheLock); ! for (scp=cm_data.hashTablep[hash]; scp; scp=scp->nextp) { if (cm_FidCmp(fidp, &scp->fid) == 0) { #ifdef DEBUG_REFCOUNT afsi_log("%s:%d cm_GetSCache (1) outScpp 0x%p ref %d", file, line, scp, scp->refCount); --- 602,608 ---- // yj: check if we have the scp, if so, we don't need // to do anything else lock_ObtainWrite(&cm_scacheLock); ! for (scp=cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) { if (cm_FidCmp(fidp, &scp->fid) == 0) { #ifdef DEBUG_REFCOUNT afsi_log("%s:%d cm_GetSCache (1) outScpp 0x%p ref %d", file, line, scp, scp->refCount); *************** *** 575,581 **** #endif cm_HoldSCacheNoLock(scp); *outScpp = scp; ! cm_AdjustLRU(scp); lock_ReleaseWrite(&cm_scacheLock); return 0; } --- 610,616 ---- #endif cm_HoldSCacheNoLock(scp); *outScpp = scp; ! cm_AdjustScacheLRU(scp); lock_ReleaseWrite(&cm_scacheLock); return 0; } *************** *** 638,645 **** scp->dotdotFid.unique=1; scp->dotdotFid.vnode=1; scp->flags |= (CM_SCACHEFLAG_PURERO | CM_SCACHEFLAG_RO); ! scp->nextp=cm_data.hashTablep[hash]; ! cm_data.hashTablep[hash]=scp; scp->flags |= CM_SCACHEFLAG_INHASH; scp->refCount = 1; osi_Log1(afsd_logp,"cm_GetSCache (freelance) sets refCount to 1 scp 0x%x", scp); --- 673,680 ---- scp->dotdotFid.unique=1; scp->dotdotFid.vnode=1; scp->flags |= (CM_SCACHEFLAG_PURERO | CM_SCACHEFLAG_RO); ! scp->nextp=cm_data.scacheHashTablep[hash]; ! cm_data.scacheHashTablep[hash]=scp; scp->flags |= CM_SCACHEFLAG_INHASH; scp->refCount = 1; osi_Log1(afsd_logp,"cm_GetSCache (freelance) sets refCount to 1 scp 0x%x", scp); *************** *** 685,691 **** if (!cellp) return CM_ERROR_NOSUCHCELL; ! code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, &volp); if (code) return code; lock_ObtainWrite(&cm_scacheLock); --- 720,726 ---- if (!cellp) return CM_ERROR_NOSUCHCELL; ! code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, CM_GETVOL_FLAG_CREATE, &volp); if (code) return code; lock_ObtainWrite(&cm_scacheLock); *************** *** 694,700 **** /* otherwise, we have the volume, now reverify that the scp doesn't * exist, and proceed. */ ! for (scp=cm_data.hashTablep[hash]; scp; scp=scp->nextp) { if (cm_FidCmp(fidp, &scp->fid) == 0) { #ifdef DEBUG_REFCOUNT afsi_log("%s:%d cm_GetSCache (3) outScpp 0x%p ref %d", file, line, scp, scp->refCount); --- 729,735 ---- /* otherwise, we have the volume, now reverify that the scp doesn't * exist, and proceed. */ ! for (scp=cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) { if (cm_FidCmp(fidp, &scp->fid) == 0) { #ifdef DEBUG_REFCOUNT afsi_log("%s:%d cm_GetSCache (3) outScpp 0x%p ref %d", file, line, scp, scp->refCount); *************** *** 702,708 **** #endif cm_HoldSCacheNoLock(scp); osi_assert(scp->volp == volp); ! cm_AdjustLRU(scp); lock_ReleaseWrite(&cm_scacheLock); if (volp) cm_PutVolume(volp); --- 737,743 ---- #endif cm_HoldSCacheNoLock(scp); osi_assert(scp->volp == volp); ! cm_AdjustScacheLRU(scp); lock_ReleaseWrite(&cm_scacheLock); if (volp) cm_PutVolume(volp); *************** *** 746,758 **** scp->dotdotFid = volp->dotdotFid; } ! if (volp->roID == fidp->volume) scp->flags |= (CM_SCACHEFLAG_PURERO | CM_SCACHEFLAG_RO); ! else if (volp->bkID == fidp->volume) scp->flags |= CM_SCACHEFLAG_RO; } ! scp->nextp = cm_data.hashTablep[hash]; ! cm_data.hashTablep[hash] = scp; scp->flags |= CM_SCACHEFLAG_INHASH; scp->refCount = 1; osi_Log1(afsd_logp,"cm_GetSCache sets refCount to 1 scp 0x%x", scp); --- 781,793 ---- scp->dotdotFid = volp->dotdotFid; } ! if (volp->ro.ID == fidp->volume) scp->flags |= (CM_SCACHEFLAG_PURERO | CM_SCACHEFLAG_RO); ! else if (volp->bk.ID == fidp->volume) scp->flags |= CM_SCACHEFLAG_RO; } ! scp->nextp = cm_data.scacheHashTablep[hash]; ! cm_data.scacheHashTablep[hash] = scp; scp->flags |= CM_SCACHEFLAG_INHASH; scp->refCount = 1; osi_Log1(afsd_logp,"cm_GetSCache sets refCount to 1 scp 0x%x", scp); *************** *** 793,799 **** if (cm_FidCmp(&scp->fid, &parent_fid)) { i = CM_SCACHE_HASH(&parent_fid); ! for (pscp = cm_data.hashTablep[i]; pscp; pscp = pscp->nextp) { if (!cm_FidCmp(&pscp->fid, &parent_fid)) { cm_HoldSCacheNoLock(pscp); break; --- 828,834 ---- if (cm_FidCmp(&scp->fid, &parent_fid)) { i = CM_SCACHE_HASH(&parent_fid); ! for (pscp = cm_data.scacheHashTablep[i]; pscp; pscp = pscp->nextp) { if (!cm_FidCmp(&pscp->fid, &parent_fid)) { cm_HoldSCacheNoLock(pscp); break; *************** *** 1355,1361 **** struct cm_volume *volp = NULL; cm_GetVolumeByID(cellp, scp->fid.volume, userp, ! (cm_req_t *) NULL, &volp); osi_Log2(afsd_logp, "old data from server %x volume %s", scp->cbServerp->addr.sin_addr.s_addr, volp ? volp->namep : "(unknown)"); --- 1390,1396 ---- struct cm_volume *volp = NULL; cm_GetVolumeByID(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, volp ? volp->namep : "(unknown)"); *************** *** 1564,1570 **** osi_assert(fidp->cell != 0); lock_ObtainWrite(&cm_scacheLock); ! for (scp=cm_data.hashTablep[hash]; scp; scp=scp->nextp) { if (cm_FidCmp(fidp, &scp->fid) == 0) { lock_ReleaseWrite(&cm_scacheLock); return scp->fileType; --- 1599,1605 ---- osi_assert(fidp->cell != 0); lock_ObtainWrite(&cm_scacheLock); ! for (scp=cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) { if (cm_FidCmp(fidp, &scp->fid) == 0) { lock_ReleaseWrite(&cm_scacheLock); return scp->fileType; *************** *** 1582,1625 **** { int zilch; cm_scache_t *scp; ! char output[1024]; int i; if (lock) lock_ObtainRead(&cm_scacheLock); ! sprintf(output, "%s - dumping scache - cm_data.currentSCaches=%d, cm_data.maxSCaches=%d\r\n", cookie, cm_data.currentSCaches, cm_data.maxSCaches); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); ! for (scp = cm_data.scacheLRULastp; scp; scp = (cm_scache_t *) osi_QPrev(&scp->q)) { ! if (scp->refCount != 0) ! { ! sprintf(output, "%s scp=0x%p, fid (cell=%d, volume=%d, vnode=%d, unique=%d) refCount=%u\r\n", ! cookie, scp, scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique, ! scp->refCount); ! WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); ! } } ! sprintf(output, "%s - dumping cm_data.hashTable - cm_data.hashTableSize=%d\r\n", cookie, cm_data.hashTableSize); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); ! for (i = 0; i < cm_data.hashTableSize; i++) { ! for(scp = cm_data.hashTablep[i]; scp; scp=scp->nextp) { ! if (scp->refCount != 0) ! { ! sprintf(output, "%s scp=0x%p, hash=%d, fid (cell=%d, volume=%d, vnode=%d, unique=%d) refCount=%u\r\n", ! cookie, scp, i, scp->fid.cell, scp->fid.volume, scp->fid.vnode, ! scp->fid.unique, scp->refCount); ! WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); ! } } } ! sprintf(output, "%s - Done dumping scache.\r\n", cookie); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); if (lock) --- 1617,1656 ---- { int zilch; cm_scache_t *scp; ! char output[2048]; int i; if (lock) lock_ObtainRead(&cm_scacheLock); ! sprintf(output, "%s - dumping all scache - cm_data.currentSCaches=%d, cm_data.maxSCaches=%d\r\n", cookie, cm_data.currentSCaches, cm_data.maxSCaches); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); ! 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=%d 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, ! (unsigned long)scp->cbExpires, scp->refCount); ! WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); } ! sprintf(output, "%s - Done dumping all scache.\r\n", cookie); ! WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); ! sprintf(output, "%s - dumping cm_data.scacheHashTable - cm_data.scacheHashTableSize=%d\r\n", cookie, cm_data.scacheHashTableSize); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); ! for (i = 0; i < cm_data.scacheHashTableSize; i++) { ! for(scp = cm_data.scacheHashTablep[i]; scp; scp=scp->nextp) { ! sprintf(output, "%s scp=0x%p, hash=%d, fid (cell=%d, volume=%d, vnode=%d, unique=%d)\r\n", ! cookie, scp, i, scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique); ! WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); } } ! sprintf(output, "%s - Done dumping cm_data.scacheHashTable\r\n", cookie); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); if (lock) Index: openafs/src/WINNT/afsd/cm_scache.h diff -c openafs/src/WINNT/afsd/cm_scache.h:1.21.2.11 openafs/src/WINNT/afsd/cm_scache.h:1.21.2.13 *** openafs/src/WINNT/afsd/cm_scache.h:1.21.2.11 Wed Feb 7 12:35:16 2007 --- openafs/src/WINNT/afsd/cm_scache.h Thu Jun 28 00:05:20 2007 *************** *** 89,94 **** --- 89,95 ---- osi_queue_t q; /* lru queue; cm_scacheLock */ afs_uint32 magic; struct cm_scache *nextp; /* next in hash; cm_scacheLock */ + struct cm_scache *allNextp; /* next in all scache list; cm_scacheLock */ cm_fid_t fid; afs_uint32 flags; /* flags; locked by mx */ *************** *** 302,308 **** ((fidp)->volume + \ (fidp)->vnode + \ (fidp)->unique)) \ ! % cm_data.hashTableSize) #include "cm_conn.h" #include "cm_buf.h" --- 303,309 ---- ((fidp)->volume + \ (fidp)->vnode + \ (fidp)->unique)) \ ! % cm_data.scacheHashTableSize) #include "cm_conn.h" #include "cm_buf.h" *************** *** 378,383 **** --- 379,386 ---- extern long cm_ShutdownSCache(void); + extern void cm_SuspendSCache(void); + extern long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags); extern void cm_RemoveSCacheFromHashTable(cm_scache_t *scp); Index: openafs/src/WINNT/afsd/cm_server.c diff -c openafs/src/WINNT/afsd/cm_server.c:1.25.2.4 openafs/src/WINNT/afsd/cm_server.c:1.25.2.11 *** openafs/src/WINNT/afsd/cm_server.c:1.25.2.4 Mon Mar 19 09:46:15 2007 --- openafs/src/WINNT/afsd/cm_server.c Sat Jul 7 09:38:33 2007 *************** *** 22,27 **** --- 22,28 ---- #include #include "afsd.h" + #include #include #include *************** *** 54,59 **** --- 55,61 ---- long usecs; Capabilities caps = {0, 0}; char hoststr[16]; + cm_req_t req; lock_ObtainMutex(&tsp->mx); if (tsp->flags & CM_SERVERFLAG_PINGING) { *************** *** 86,106 **** wasDown ? "down" : "up", tsp->capabilities); if (wasDown) ! rx_SetConnDeadTime(connp->callp, 10); if (tsp->type == CM_SERVER_VLDB) { ! code = VL_ProbeServer(connp->callp); } else { /* file server */ - rxconnp = cm_GetRxConn(connp); code = RXAFS_GetCapabilities(rxconnp, &caps); if (code == RXGEN_OPCODE) code = RXAFS_GetTime(rxconnp, &secs, &usecs); - rx_PutConnection(rxconnp); } if (wasDown) ! rx_SetConnDeadTime(connp->callp, ConnDeadtimeout); cm_PutConn(connp); } /* got an unauthenticated connection to this server */ --- 88,108 ---- wasDown ? "down" : "up", tsp->capabilities); + rxconnp = cm_GetRxConn(connp); if (wasDown) ! rx_SetConnDeadTime(rxconnp, 10); if (tsp->type == CM_SERVER_VLDB) { ! code = VL_ProbeServer(rxconnp); } else { /* file server */ code = RXAFS_GetCapabilities(rxconnp, &caps); if (code == RXGEN_OPCODE) code = RXAFS_GetTime(rxconnp, &secs, &usecs); } if (wasDown) ! rx_SetConnDeadTime(rxconnp, ConnDeadtimeout); ! rx_PutConnection(rxconnp); cm_PutConn(connp); } /* got an unauthenticated connection to this server */ *************** *** 123,128 **** --- 125,154 ---- osi_LogSaveString(afsd_logp, hoststr), tsp->type == CM_SERVER_VLDB ? "vldb" : "file", tsp->capabilities); + + /* Now update the volume status if necessary */ + if (wasDown) { + cm_server_vols_t * tsrvp; + cm_volume_t * volp; + int i; + + lock_ReleaseMutex(&tsp->mx); + for (tsrvp = tsp->vols; tsrvp; tsrvp = tsrvp->nextp) { + for (i=0; iids[i] != 0) { + cm_InitReq(&req); + + code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, + &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp); + if (code == 0) { +