windows-remove-scache-volp-20080312
authorJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 13 Mar 2008 04:37:44 +0000 (04:37 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 13 Mar 2008 04:37:44 +0000 (04:37 +0000)
LICENSE MIT

The cm_scache structure has included a reference to the associated cm_volume_t,
volp.  By doing so the reference count on the cm_volume_t objects never hits
zero unless all of the cm_scache_t objects in that volume have been reused.
This prevents cm_volume object recycling.

This commit removes the hard reference and instead adds a function
cm_GetVolumeByFID which obtains a reference to the cm_volume that matches
the cm_scache fid value as needed.

A new "Volumes" registry value is added to permit explicit specification
of the number of volume objects to be allocated.

13 files changed:
src/WINNT/afsd/afsd_init.c
src/WINNT/afsd/cm.h
src/WINNT/afsd/cm_callback.c
src/WINNT/afsd/cm_conn.c
src/WINNT/afsd/cm_ioctl.c
src/WINNT/afsd/cm_performance.c
src/WINNT/afsd/cm_scache.c
src/WINNT/afsd/cm_scache.h
src/WINNT/afsd/cm_server.c
src/WINNT/afsd/cm_vnodeops.c
src/WINNT/afsd/cm_volstat.c
src/WINNT/afsd/cm_volume.c
src/WINNT/afsd/cm_volume.h

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