From: Jeffrey Altman Date: Mon, 22 Jan 2007 02:16:38 +0000 (+0000) Subject: windows-fix-volume-refcount-leak-20070121 X-Git-Tag: BP-openafs-windows-kdfs-ifs~848 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=f9697113d97135fa606a9fa92905d3fcc478bc34 windows-fix-volume-refcount-leak-20070121 Plug a volume refcount leak Add volume data to the "fs memdump" output Add memmap stat data to the afsd_init.log output at startup and shutdown --- diff --git a/src/WINNT/afsd/cm_ioctl.c b/src/WINNT/afsd/cm_ioctl.c index 65bd9e4..adaf855 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -728,6 +728,7 @@ long cm_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp) cm_ReleaseSCache(scp); return code; } + cm_PutVolume(tvp); /* Copy the junk out, using cp as a roving pointer. */ cp = ioctlp->inDatap; @@ -2703,11 +2704,13 @@ long cm_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp) /* dump all interesting data */ cm_DumpSCache(hLogFile, cookie, 1); + cm_DumpVolumes(hLogFile, cookie, 1); cm_DumpBufHashTable(hLogFile, cookie, 1); smb_DumpVCP(hLogFile, cookie, 1); CloseHandle(hLogFile); + inValue = 0; /* success */ memcpy(ioctlp->outDatap, &inValue, sizeof(long)); ioctlp->outDatap += sizeof(long); diff --git a/src/WINNT/afsd/cm_memmap.c b/src/WINNT/afsd/cm_memmap.c index 900c01b..2433216 100644 --- a/src/WINNT/afsd/cm_memmap.c +++ b/src/WINNT/afsd/cm_memmap.c @@ -214,6 +214,21 @@ cm_ShutdownMappedMemory(void) cm_config_data_t * config_data_p = (cm_config_data_t *)cm_data.baseAddress; int dirty = 0; + afsi_log("Closing AFS Cache:"); + afsi_log(" Base Address = %p", config_data_p); + afsi_log(" stats = %d", cm_data.stats); + afsi_log(" chunkSize = %d", cm_data.chunkSize); + 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); + cm_ShutdownDCache(); cm_ShutdownSCache(); cm_ShutdownACLCache(); @@ -393,7 +408,7 @@ cm_ValidateMappedMemory(char * cachePath) 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," 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; @@ -778,9 +793,23 @@ cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD chu config_data_p = (cm_config_data_t *) baseAddress; if (!newFile) { - afsi_log("Reusing existing AFS Cache data: Base Address = %lX",baseAddress); + afsi_log("Reusing existing AFS Cache data:"); cm_data = *config_data_p; + afsi_log(" Base Address = %p",baseAddress); + afsi_log(" stats = %d", config_data_p->stats); + afsi_log(" chunkSize = %d", config_data_p->chunkSize); + 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); + // perform validation of persisted data structures // if there is a failure, start from scratch if (cm_ValidateCache && !cm_IsCacheValid()) { diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index d3595d7..459b2a9 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -543,9 +543,9 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp, long hash; cm_scache_t *scp; long code; - cm_volume_t *volp = 0; + cm_volume_t *volp = NULL; cm_cell_t *cellp; - char* mp = 0; + char* mp = NULL; int special; // yj: boolean variable to test if file is on root.afs int isRoot; extern cm_fid_t cm_rootFid; @@ -629,6 +629,7 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp, #endif scp->fid = *fidp; scp->volp = cm_data.rootSCachep->volp; + cm_GetVolume(scp->volp); /* grab an additional reference */ scp->dotdotFid.cell=AFS_FAKE_ROOT_CELL_ID; scp->dotdotFid.volume=AFS_FAKE_ROOT_VOL_ID; scp->dotdotFid.unique=1; @@ -712,6 +713,8 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp, if (scp == NULL) { osi_Log0(afsd_logp,"cm_GetNewSCache unable to obtain *new* scache entry"); lock_ReleaseWrite(&cm_scacheLock); + if (volp) + cm_PutVolume(volp); return CM_ERROR_WOULDBLOCK; } osi_Log2(afsd_logp,"cm_GetNewSCache returns scp 0x%x flags 0x%x", scp, scp->flags); diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 4d1ba03..509fe4f 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -1000,7 +1000,7 @@ long cm_FollowMountPoint(cm_scache_t *scp, cm_scache_t *dscp, cm_user_t *userp, long code; char *cp; char *mpNamep; - cm_volume_t *volp; + cm_volume_t *volp = NULL; cm_cell_t *cellp; char mtType; cm_fid_t tfid; @@ -1106,6 +1106,8 @@ long cm_FollowMountPoint(cm_scache_t *scp, cm_scache_t *dscp, cm_user_t *userp, } done: + if (volp) + cm_PutVolume(volp); free(cellNamep); free(volNamep); return code; @@ -2112,22 +2114,16 @@ cm_TryBulkStat(cm_scache_t *dscp, osi_hyper_t *offsetp, cm_user_t *userp, } /* while there are still more files to process */ lock_ObtainMutex(&dscp->mx); -#if 0 - /* If we did the InlineBulk RPC pull out the return code */ + /* If we did the InlineBulk RPC pull out the return code and log it */ if (inlinebulk) { if ((&bb.stats[0])->errorCode) { - cm_Analyze(NULL /*connp was released by the previous cm_Analyze */, - userp, reqp, &dscp->fid, &volSync, NULL, NULL, (&bb.stats[0])->errorCode); - code = cm_MapRPCError((&bb.stats[0])->errorCode, reqp); + osi_Log1(afsd_logp, "cm_TryBulkStat bulk stat error: %d", + (&bb.stats[0])->errorCode); } - } else -#endif - { - code = 0; } - osi_Log1(afsd_logp, "END cm_TryBulkStat code = 0x%x", code); - return code; + osi_Log0(afsd_logp, "END cm_TryBulkStat"); + return 0; } void cm_StatusFromAttr(AFSStoreStatus *statusp, cm_scache_t *scp, cm_attr_t *attrp) diff --git a/src/WINNT/afsd/cm_volume.c b/src/WINNT/afsd/cm_volume.c index 7c9959b..9f987df 100644 --- a/src/WINNT/afsd/cm_volume.c +++ b/src/WINNT/afsd/cm_volume.c @@ -125,7 +125,7 @@ void cm_InitVolume(int newFile, long maxVols) */ #define MULTIHOMED 1 long cm_UpdateVolume(struct cm_cell *cellp, cm_user_t *userp, cm_req_t *reqp, - cm_volume_t *volp) + cm_volume_t *volp) { cm_conn_t *connp; int i, j, k; @@ -359,150 +359,160 @@ long cm_UpdateVolume(struct cm_cell *cellp, cm_user_t *userp, cm_req_t *reqp, return code; } +void cm_GetVolume(cm_volume_t *volp) +{ + if (volp) { + lock_ObtainWrite(&cm_volumeLock); + volp->refCount++; + lock_ReleaseWrite(&cm_volumeLock); + } +} + long cm_GetVolumeByID(cm_cell_t *cellp, long volumeID, cm_user_t *userp, cm_req_t *reqp, cm_volume_t **outVolpp) { - cm_volume_t *volp; - char volNameString[100]; - long code; - - lock_ObtainWrite(&cm_volumeLock); - for(volp = cm_data.allVolumesp; volp; volp=volp->nextp) { - if (cellp == volp->cellp && - ((unsigned) volumeID == volp->rwID || - (unsigned) volumeID == volp->roID || - (unsigned) volumeID == volp->bkID)) - break; - } + cm_volume_t *volp; + char volNameString[100]; + long code; - /* hold the volume if we found it */ + lock_ObtainWrite(&cm_volumeLock); + for(volp = cm_data.allVolumesp; volp; volp=volp->nextp) { + if (cellp == volp->cellp && + ((unsigned) volumeID == volp->rwID || + (unsigned) volumeID == volp->roID || + (unsigned) volumeID == volp->bkID)) + break; + } + + /* hold the volume if we found it */ if (volp) volp->refCount++; - lock_ReleaseWrite(&cm_volumeLock); + lock_ReleaseWrite(&cm_volumeLock); - /* return it held */ - if (volp) { - lock_ObtainMutex(&volp->mx); + /* return it held */ + if (volp) { + lock_ObtainMutex(&volp->mx); - if (volp->flags & CM_VOLUMEFLAG_RESET) { - code = cm_UpdateVolume(cellp, userp, reqp, volp); - if (code == 0) { - volp->flags &= ~CM_VOLUMEFLAG_RESET; - } - } - else - code = 0; - lock_ReleaseMutex(&volp->mx); - if (code == 0) - *outVolpp = volp; - return code; - } + if (volp->flags & CM_VOLUMEFLAG_RESET) { + code = cm_UpdateVolume(cellp, userp, reqp, volp); + if (code == 0) { + volp->flags &= ~CM_VOLUMEFLAG_RESET; + } + } + else + code = 0; + lock_ReleaseMutex(&volp->mx); + if (code == 0) + *outVolpp = volp; + return code; + } - /* otherwise, we didn't find it so consult the VLDB */ - sprintf(volNameString, "%u", volumeID); - code = cm_GetVolumeByName(cellp, volNameString, userp, reqp, - 0, outVolpp); - return code; + /* otherwise, we didn't find it so consult the VLDB */ + sprintf(volNameString, "%u", volumeID); + code = cm_GetVolumeByName(cellp, volNameString, userp, reqp, + 0, outVolpp); + return code; } long cm_GetVolumeByName(struct cm_cell *cellp, char *volumeNamep, - struct cm_user *userp, struct cm_req *reqp, - long flags, cm_volume_t **outVolpp) + struct cm_user *userp, struct cm_req *reqp, + long flags, cm_volume_t **outVolpp) { - cm_volume_t *volp; - long code; - - /* initialize this */ - code = 0; - - lock_ObtainWrite(&cm_volumeLock); - for (volp = cm_data.allVolumesp; volp; volp=volp->nextp) { - if (cellp == volp->cellp && strcmp(volumeNamep, volp->namep) == 0) { - break; - } - } + cm_volume_t *volp; + long code; - /* otherwise, get from VLDB */ - if (!volp) { - if ( cm_data.currentVolumes >= cm_data.maxVolumes ) { - for (volp = cm_data.allVolumesp; volp; volp=volp->nextp) { - if ( volp->refCount == 0 ) { - /* There is one we can re-use */ - break; - } - } - if (!volp) - osi_panic("Exceeded Max Volumes", __FILE__, __LINE__); - } + /* initialize this */ + code = 0; - if (volp) { - volp->rwID = volp->roID = volp->bkID = 0; - volp->dotdotFid.cell = 0; - volp->dotdotFid.volume = 0; - volp->dotdotFid.unique = 0; - volp->dotdotFid.vnode = 0; - } else { - volp = &cm_data.volumeBaseAddress[cm_data.currentVolumes++]; - memset(volp, 0, sizeof(cm_volume_t)); - volp->magic = CM_VOLUME_MAGIC; - volp->nextp = cm_data.allVolumesp; - cm_data.allVolumesp = volp; - lock_InitializeMutex(&volp->mx, "cm_volume_t mutex"); - } - volp->cellp = cellp; - strncpy(volp->namep, volumeNamep, VL_MAXNAMELEN); - volp->namep[VL_MAXNAMELEN-1] = '\0'; - volp->refCount = 1; /* starts off held */ - volp->flags = CM_VOLUMEFLAG_RESET; - } - else { - volp->refCount++; + lock_ObtainWrite(&cm_volumeLock); + for (volp = cm_data.allVolumesp; volp; volp=volp->nextp) { + if (cellp == volp->cellp && strcmp(volumeNamep, volp->namep) == 0) { + break; } + } - /* next should work since no one could have gotten ptr to this structure yet */ - lock_ReleaseWrite(&cm_volumeLock); - lock_ObtainMutex(&volp->mx); - - if (volp->flags & CM_VOLUMEFLAG_RESET) { - code = cm_UpdateVolume(cellp, userp, reqp, volp); - if (code == 0) - volp->flags &= ~CM_VOLUMEFLAG_RESET; + /* otherwise, get from VLDB */ + if (!volp) { + if ( cm_data.currentVolumes >= cm_data.maxVolumes ) { + for (volp = cm_data.allVolumesp; volp; volp=volp->nextp) { + if ( volp->refCount == 0 ) { + /* There is one we can re-use */ + break; + } + } + if (!volp) + osi_panic("Exceeded Max Volumes", __FILE__, __LINE__); + } + + if (volp) { + volp->rwID = volp->roID = volp->bkID = 0; + volp->dotdotFid.cell = 0; + volp->dotdotFid.volume = 0; + volp->dotdotFid.unique = 0; + volp->dotdotFid.vnode = 0; + } else { + volp = &cm_data.volumeBaseAddress[cm_data.currentVolumes++]; + memset(volp, 0, sizeof(cm_volume_t)); + volp->magic = CM_VOLUME_MAGIC; + volp->nextp = cm_data.allVolumesp; + cm_data.allVolumesp = volp; + lock_InitializeMutex(&volp->mx, "cm_volume_t mutex"); } + volp->cellp = cellp; + strncpy(volp->namep, volumeNamep, VL_MAXNAMELEN); + volp->namep[VL_MAXNAMELEN-1] = '\0'; + volp->refCount = 1; /* starts off held */ + volp->flags = CM_VOLUMEFLAG_RESET; + } + else { + volp->refCount++; + } + + /* next should work since no one could have gotten ptr to this structure yet */ + lock_ReleaseWrite(&cm_volumeLock); + lock_ObtainMutex(&volp->mx); + if (volp->flags & CM_VOLUMEFLAG_RESET) { + code = cm_UpdateVolume(cellp, userp, reqp, volp); if (code == 0) - *outVolpp = volp; - lock_ReleaseMutex(&volp->mx); - return code; -} + volp->flags &= ~CM_VOLUMEFLAG_RESET; + } + + if (code == 0) + *outVolpp = volp; + lock_ReleaseMutex(&volp->mx); + return code; +} void cm_ForceUpdateVolume(cm_fid_t *fidp, cm_user_t *userp, cm_req_t *reqp) { - cm_cell_t *cellp; - cm_volume_t *volp; + cm_cell_t *cellp; + cm_volume_t *volp; - if (!fidp) return; + if (!fidp) return; - cellp = cm_FindCellByID(fidp->cell); - if (!cellp) return; + cellp = cm_FindCellByID(fidp->cell); + if (!cellp) return; - /* search for the volume */ - lock_ObtainWrite(&cm_volumeLock); - for(volp = cm_data.allVolumesp; volp; volp=volp->nextp) { - if (cellp == volp->cellp && - (fidp->volume == volp->rwID || - fidp->volume == volp->roID || - fidp->volume == volp->bkID)) - break; - } - - /* hold the volume if we found it */ - if (volp) volp->refCount++; - lock_ReleaseWrite(&cm_volumeLock); + /* search for the volume */ + lock_ObtainWrite(&cm_volumeLock); + for(volp = cm_data.allVolumesp; volp; volp=volp->nextp) { + if (cellp == volp->cellp && + (fidp->volume == volp->rwID || + fidp->volume == volp->roID || + fidp->volume == volp->bkID)) + break; + } + + /* hold the volume if we found it */ + if (volp) + volp->refCount++; + lock_ReleaseWrite(&cm_volumeLock); - /* update it */ - cm_data.mountRootGen = time(NULL); - lock_ObtainMutex(&volp->mx); - volp->flags |= CM_VOLUMEFLAG_RESET; + /* update it */ + cm_data.mountRootGen = time(NULL); + lock_ObtainMutex(&volp->mx); + volp->flags |= CM_VOLUMEFLAG_RESET; #ifdef COMMENT /* Mark the volume to be updated but don't update it now. * This function is called only from within cm_Analyze @@ -514,13 +524,13 @@ void cm_ForceUpdateVolume(cm_fid_t *fidp, cm_user_t *userp, cm_req_t *reqp) * accessed by Name or ID the UpdateVolume call will * occur. */ - code = cm_UpdateVolume(cellp, userp, reqp, volp); - if (code == 0) - volp->flags &= ~CM_VOLUMEFLAG_RESET; + code = cm_UpdateVolume(cellp, userp, reqp, volp); + if (code == 0) + volp->flags &= ~CM_VOLUMEFLAG_RESET; #endif - lock_ReleaseMutex(&volp->mx); + lock_ReleaseMutex(&volp->mx); - cm_PutVolume(volp); + cm_PutVolume(volp); } /* find the appropriate servers from a volume */ @@ -560,38 +570,38 @@ void cm_PutVolume(cm_volume_t *volp) */ long cm_GetROVolumeID(cm_volume_t *volp) { - long id; + long id; - lock_ObtainMutex(&volp->mx); - if (volp->roID && volp->roServersp) - id = volp->roID; - else - id = volp->rwID; - lock_ReleaseMutex(&volp->mx); + lock_ObtainMutex(&volp->mx); + if (volp->roID && volp->roServersp) + id = volp->roID; + else + id = volp->rwID; + lock_ReleaseMutex(&volp->mx); - return id; + return id; } void cm_CheckVolumes(void) { - cm_volume_t *volp; + cm_volume_t *volp; - cm_data.mountRootGen = time(NULL); - lock_ObtainWrite(&cm_volumeLock); - for (volp = cm_data.allVolumesp; volp; volp=volp->nextp) { - volp->refCount++; - lock_ReleaseWrite(&cm_volumeLock); - lock_ObtainMutex(&volp->mx); + cm_data.mountRootGen = time(NULL); + lock_ObtainWrite(&cm_volumeLock); + for (volp = cm_data.allVolumesp; volp; volp=volp->nextp) { + volp->refCount++; + lock_ReleaseWrite(&cm_volumeLock); + lock_ObtainMutex(&volp->mx); - volp->flags |= CM_VOLUMEFLAG_RESET; + volp->flags |= CM_VOLUMEFLAG_RESET; - lock_ReleaseMutex(&volp->mx); - lock_ObtainWrite(&cm_volumeLock); - osi_assert(volp->refCount-- > 0); - } - lock_ReleaseWrite(&cm_volumeLock); + lock_ReleaseMutex(&volp->mx); + lock_ObtainWrite(&cm_volumeLock); + osi_assert(volp->refCount-- > 0); + } + lock_ReleaseWrite(&cm_volumeLock); - /* We should also refresh cached mount points */ + /* We should also refresh cached mount points */ } /* @@ -599,29 +609,79 @@ void cm_CheckVolumes(void) ** RO list according to the changed rank of server. */ void cm_ChangeRankVolume(cm_server_t *tsp) -{ - int code; - cm_volume_t* volp; +{ + int code; + cm_volume_t* volp; - /* find volumes which might have RO copy on server*/ - lock_ObtainWrite(&cm_volumeLock); - for(volp = cm_data.allVolumesp; volp; volp=volp->nextp) - { - code = 1 ; /* assume that list is unchanged */ - volp->refCount++; - lock_ReleaseWrite(&cm_volumeLock); - lock_ObtainMutex(&volp->mx); - - if ((tsp->cellp==volp->cellp) && (volp->roServersp)) - code =cm_ChangeRankServer(&volp->roServersp, tsp); - - /* this volume list was changed */ - if ( !code ) - cm_RandomizeServer(&volp->roServersp); - - lock_ReleaseMutex(&volp->mx); - lock_ObtainWrite(&cm_volumeLock); - osi_assert(volp->refCount-- > 0); - } + /* find volumes which might have RO copy on server*/ + lock_ObtainWrite(&cm_volumeLock); + for(volp = cm_data.allVolumesp; volp; volp=volp->nextp) + { + code = 1 ; /* assume that list is unchanged */ + volp->refCount++; lock_ReleaseWrite(&cm_volumeLock); + lock_ObtainMutex(&volp->mx); + + if ((tsp->cellp==volp->cellp) && (volp->roServersp)) + code =cm_ChangeRankServer(&volp->roServersp, tsp); + + /* this volume list was changed */ + if ( !code ) + cm_RandomizeServer(&volp->roServersp); + + lock_ReleaseMutex(&volp->mx); + lock_ObtainWrite(&cm_volumeLock); + osi_assert(volp->refCount-- > 0); + } + lock_ReleaseWrite(&cm_volumeLock); +} + +/* dump all scp's that have reference count > 0 to a file. + * cookie is used to identify this batch for easy parsing, + * and it a string provided by a caller + */ +int cm_DumpVolumes(FILE *outputFile, char *cookie, int lock) +{ + int zilch; + cm_volume_t *volp; + char output[1024]; + + if (lock) { + lock_ObtainRead(&cm_scacheLock); + lock_ObtainRead(&cm_volumeLock); + } + + sprintf(output, "%s - dumping volumes - cm_data.currentVolumes=%d, cm_data.maxVolumes=%d\n", cookie, cm_data.currentVolumes, cm_data.maxVolumes); + WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); + + for (volp = cm_data.allVolumesp; volp; volp=volp->nextp) + { + if (volp->refCount != 0) + { + cm_scache_t *scp; + int scprefs = 0; + + for (scp = cm_data.scacheLRULastp; scp; scp = (cm_scache_t *) osi_QPrev(&scp->q)) + { + if (scp->volp == volp) + scprefs++; + } + + sprintf(output, "%s cell=%s name=%s rwID=%u roID=%u bkID=%u flags=0x%x fid (cell=%d, volume=%d, vnode=%d, unique=%d) refCount=%u scpRefs=%u\n", + cookie, volp->cellp->name, volp->namep, volp->rwID, volp->roID, volp->bkID, volp->flags, + volp->dotdotFid.cell, volp->dotdotFid.volume, volp->dotdotFid.vnode, volp->dotdotFid.unique, + volp->refCount, scprefs); + WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); + } + } + sprintf(output, "%s - Done dumping volumes.\n", cookie); + WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); + + if (lock) { + lock_ReleaseRead(&cm_volumeLock); + lock_ReleaseRead(&cm_scacheLock); + } + return (0); } + + diff --git a/src/WINNT/afsd/cm_volume.h b/src/WINNT/afsd/cm_volume.h index 848f4be..30045c3 100644 --- a/src/WINNT/afsd/cm_volume.h +++ b/src/WINNT/afsd/cm_volume.h @@ -38,13 +38,15 @@ extern void cm_InitVolume(int newFile, long maxVols); extern long cm_GetVolumeByName(struct cm_cell *, char *, struct cm_user *, struct cm_req *, long, cm_volume_t **); +extern long cm_GetVolumeByID(struct cm_cell *cellp, long volumeID, + cm_user_t *userp, cm_req_t *reqp, cm_volume_t **outVolpp); + +extern void cm_GetVolume(cm_volume_t *volp); + extern void cm_PutVolume(cm_volume_t *volp); extern long cm_GetROVolumeID(cm_volume_t *volp); -extern long cm_GetVolumeByID(struct cm_cell *cellp, long volumeID, - cm_user_t *userp, cm_req_t *reqp, cm_volume_t **outVolpp); - extern void cm_ForceUpdateVolume(struct cm_fid *fidp, cm_user_t *userp, cm_req_t *reqp); @@ -57,4 +59,6 @@ extern void cm_CheckVolumes(void); extern long cm_ValidateVolume(void); extern long cm_ShutdownVolume(void); + +extern int cm_DumpVolumes(FILE *outputFile, char *cookie, int lock); #endif /* __CM_VOLUME_H_ENV__ */ diff --git a/src/WINNT/afsd/fs.c b/src/WINNT/afsd/fs.c index 0259749..f18a322 100644 --- a/src/WINNT/afsd/fs.c +++ b/src/WINNT/afsd/fs.c @@ -3826,7 +3826,7 @@ MemDumpCmd(struct cmd_syndesc *asp, char *arock) return code; } - if (outValue) { + if (!outValue) { printf("AFS memdump created.\n"); return 0; } else {