]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
windows-afsd-freelance-20090105
authorJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 5 Jan 2009 16:20:08 +0000 (16:20 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 5 Jan 2009 16:20:08 +0000 (16:20 +0000)
LICENSE MIT

Bring a bit more sanity to the Freelance code:

1. Add functions cm_FreelanceFetchMountPointString and
   cm_FreelanceFetchFileType to cm_freelance.c.  These functions
   permit the MountPointString and FileType to be obtained within
   cm_GetSCache without requiring knowledge of data structures
   that should be private to cm_freelance.c

2. Enforce the rule that odd vnode values are directory objects.
   The root directory is 1 and everything else must be a multiple
   of two.

3. Use the unique field as an index into the localMountPoints
   array.

4. Fix cm_GetCallback to process freelance data refreshes on
   all objects in the freelance volume not just the root directory.
   If this is not done, an access to \\afs\foo prior to \\afs\all
   being evaluated will cause an unnecessary attempt to send a
   fetch status request to a file server and produce an alldown
   error.

src/WINNT/afsd/afsd.h
src/WINNT/afsd/cm_callback.c
src/WINNT/afsd/cm_freelance.c
src/WINNT/afsd/cm_freelance.h
src/WINNT/afsd/cm_scache.c
src/WINNT/afsd/cm_vnodeops.c

index aa027afe43ee5e7f9ae86d5b39b858ebdf967056..afa11a85ed5327a552771df4e01ad1d90648d1b2 100644 (file)
@@ -98,10 +98,6 @@ extern BOOL reportSessionStartups;
 #ifdef AFS_FREELANCE_CLIENT
 extern char *cm_FakeRootDir;                           // the fake root.afs directory
 
-extern int cm_noLocalMountPoints;                      // no. of fake mountpoints
-
-extern cm_localMountPoint_t* cm_localMountPoints;      // array of fake mountpoints
-
 extern int cm_fakeDirSize;                             // size (in bytes) of fake root.afs directory
 
 extern int cm_fakeDirCallback;                         // state of the fake root.afs directory. indicates
index df3a0159da6a657a202ba813a1e19ee03b75e0fb..32f59ab36e1a5ec15d6a98005bd80c3855da0012 100644 (file)
@@ -1739,10 +1739,7 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp,
     // cm_MergeStatus and mark that cm_fakeDirCallback is 2
     if (cm_freelanceEnabled) {
         if (scp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
-             scp->fid.volume==AFS_FAKE_ROOT_VOL_ID &&
-             scp->fid.unique==0x1 &&
-             scp->fid.vnode==0x1) {
-            
+            scp->fid.volume==AFS_FAKE_ROOT_VOL_ID) {
             // Start by indicating that we're in the process
             // of fetching the callback
             lock_ObtainMutex(&cm_Freelance_Lock);
@@ -1765,10 +1762,6 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp,
 
             return 0;
         }
-
-        if (scp->fid.cell==AFS_FAKE_ROOT_CELL_ID && scp->fid.volume==AFS_FAKE_ROOT_VOL_ID) {
-            osi_Log0(afsd_logp,"cm_getcallback should NEVER EVER get here... ");
-        }
     }
 #endif /* AFS_FREELANCE_CLIENT */
        
index 5b88d65eb7153c977384e7d21cd5d1ccf8e8efa3..fe2085e04543b27e192470fec888a7bd32b321ba 100644 (file)
 
 extern void afsi_log(char *pattern, ...);
 
-int cm_noLocalMountPoints;
+static int cm_noLocalMountPoints;
 char * cm_FakeRootDir = NULL;
 int cm_fakeDirSize = 0;
 int cm_fakeDirCallback=0;
 int cm_fakeGettingCallback=0;
-cm_localMountPoint_t* cm_localMountPoints;
+static cm_localMountPoint_t* cm_localMountPoints;
 osi_mutex_t cm_Freelance_Lock;
-int cm_localMountPointChangeFlag = 0;
+static int cm_localMountPointChangeFlag = 0;
 int cm_freelanceEnabled = 1;
 time_t FakeFreelanceModTime = 0x3b49f6e2;
 
@@ -274,7 +274,9 @@ void cm_InitFakeRootDir() {
     {       
 
         noChunks = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0);
-        fakeEntry.fid.vnode = htonl(curDirEntry + 2);
+        /* enforce the rule that only directories have odd vnode values */
+        fakeEntry.fid.vnode = htonl((curDirEntry + 1) * 2);
+        fakeEntry.fid.unique = htonl(curDirEntry + 1);
         currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE;
 
         memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE);
@@ -316,7 +318,9 @@ void cm_InitFakeRootDir() {
             // add an entry to this page
 
             noChunks = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0);
-            fakeEntry.fid.vnode=htonl(curDirEntry+2);
+            /* enforce the rule that only directories have odd vnode values */
+            fakeEntry.fid.vnode = htonl((curDirEntry + 1) * 2);
+            fakeEntry.fid.unique = htonl(curDirEntry + 1);
             currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE;
             memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE);
             strcpy(currentPos + 12, (cm_localMountPoints+curDirEntry)->namep);
@@ -1336,4 +1340,43 @@ long cm_FreelanceRemoveSymlink(char *toremove)
     } else
         return CM_ERROR_NOSUCHFILE;
 }
+
+long
+cm_FreelanceFetchMountPointString(cm_scache_t *scp)
+{
+    lock_ObtainMutex(&cm_Freelance_Lock);
+    if (!scp->mountPointStringp[0] && 
+        scp->fid.cell == AFS_FAKE_ROOT_CELL_ID &&
+        scp->fid.volume == AFS_FAKE_ROOT_VOL_ID && 
+        scp->fid.unique <= cm_noLocalMountPoints) {
+        strncpy(scp->mountPointStringp, cm_localMountPoints[scp->fid.unique-1].mountPointStringp, MOUNTPOINTLEN);
+        scp->mountPointStringp[MOUNTPOINTLEN-1] = 0;   /* null terminate */
+    }
+    lock_ReleaseMutex(&cm_Freelance_Lock);
+
+    return 0;
+}
+
+long 
+cm_FreelanceFetchFileType(cm_scache_t *scp)
+{
+    lock_ObtainMutex(&cm_Freelance_Lock);
+    if (scp->fid.cell == AFS_FAKE_ROOT_CELL_ID &&
+        scp->fid.volume == AFS_FAKE_ROOT_VOL_ID && 
+        scp->fid.unique <= cm_noLocalMountPoints) 
+    {
+        scp->fileType = cm_localMountPoints[scp->fid.unique-1].fileType;
+    
+        if ( scp->fileType == CM_SCACHETYPE_SYMLINK &&
+             !strnicmp(cm_localMountPoints[scp->fid.unique-1].mountPointStringp, "msdfs:", strlen("msdfs:")) )
+        {
+            scp->fileType = CM_SCACHETYPE_DFSLINK;
+        } 
+    } else {
+        scp->fileType = CM_SCACHETYPE_INVALID;
+    }
+    lock_ReleaseMutex(&cm_Freelance_Lock);
+
+    return 0;
+}
 #endif /* AFS_FREELANCE_CLIENT */
index 9f327fab878e3263f07945200bb89cd714f080d3..3b016840870bf856982e1e49b40020526ee11913 100644 (file)
@@ -21,6 +21,9 @@ extern long cm_FreelanceRemoveSymlink(char *toremove);
 extern long cm_FreelanceAddSymlink(char *filename, char *destination, cm_fid_t *fidp);
 extern long cm_FreelanceMountPointExists(char * filename, int prefix_ok);
 extern long cm_FreelanceSymlinkExists(char * filename, int prefix_ok);
+extern long cm_FreelanceFetchMountPointString(cm_scache_t *scp);
+extern long cm_FreelanceFetchFileType(cm_scache_t *scp);
+
 extern int cm_clearLocalMountPointChange();
 extern int cm_FakeRootFid(cm_fid_t *fidp);
 
index 257d0f7b6da133fbdd8897b119bd01bf43f26a35..2d143df85e7599211107e12bb5f7064a96fffbfe 100644 (file)
@@ -718,9 +718,6 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp,
     }
          
     if (cm_freelanceEnabled && special) {
-        char mp[MOUNTPOINTLEN] = "";
-        afs_uint32 fileType;
-
         lock_ReleaseWrite(&cm_scacheLock);
         osi_Log0(afsd_logp,"cm_GetSCache Freelance and special");
 
@@ -729,19 +726,6 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp,
             cm_reInitLocalMountPoints();       // start reinit
         }
 
-        lock_ObtainMutex(&cm_Freelance_Lock);
-        if (fidp->vnode >= 2 && fidp->vnode - 2 < cm_noLocalMountPoints) {
-            strncpy(mp,(cm_localMountPoints+fidp->vnode-2)->mountPointStringp, MOUNTPOINTLEN);
-            mp[MOUNTPOINTLEN-1] = '\0';
-            if ( !strnicmp(mp, "msdfs:", strlen("msdfs:")) )
-                fileType = CM_SCACHETYPE_DFSLINK;
-            else
-                fileType = (cm_localMountPoints+fidp->vnode-2)->fileType;
-        } else {
-            fileType = CM_SCACHETYPE_INVALID;
-
-        }
-        lock_ReleaseMutex(&cm_Freelance_Lock);
         lock_ObtainWrite(&cm_scacheLock);
         if (scp == NULL) {
             scp = cm_GetNewSCache();    /* returns scp->rw held */
@@ -768,10 +752,13 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp,
         }
         scp->refCount = 1;
        osi_Log1(afsd_logp,"cm_GetSCache (freelance) sets refCount to 1 scp 0x%x", scp);
-        scp->fileType = fileType;
-        scp->length.LowPart = (DWORD)strlen(mp)+4;
+
+        /* must be called after the scp->fid is set */
+        cm_FreelanceFetchMountPointString(scp);
+        cm_FreelanceFetchFileType(scp);
+        
+        scp->length.LowPart = (DWORD)strlen(scp->mountPointStringp)+4;
         scp->length.HighPart = 0;
-        strncpy(scp->mountPointStringp,mp,MOUNTPOINTLEN);
         scp->owner=0x0;
         scp->unixModeBits=0777;
         scp->clientModTime=FakeFreelanceModTime;
index c7a4cabf41136ef55751ab344fca998e5adfcf58..81229786a8337855d69b42d3d5c762e9838df4c2 100644 (file)
@@ -808,68 +808,79 @@ long cm_LookupSearchProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp,
 long cm_ReadMountPoint(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
 {
     long code;
-    cm_buf_t *bufp;
+    cm_buf_t *bufp = NULL;
     osi_hyper_t thyper;
     int tlen;
 
     if (scp->mountPointStringp[0]) 
         return 0;
         
-    /* otherwise, we have to read it in */
-    lock_ReleaseWrite(&scp->rw);
-
-    thyper.LowPart = thyper.HighPart = 0;
-    code = buf_Get(scp, &thyper, &bufp);
+#ifdef AFS_FREELANCE_CLIENT
+    /* File servers do not have data for freelance entries */
+    if (cm_freelanceEnabled &&
+        scp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
+        scp->fid.volume==AFS_FAKE_ROOT_VOL_ID )
+    {       
+        code = cm_FreelanceFetchMountPointString(scp);
+    } else 
+#endif /* AFS_FREELANCE_CLIENT */        
+    {
+        /* otherwise, we have to read it in */
+        lock_ReleaseWrite(&scp->rw);
 
-    lock_ObtainWrite(&scp->rw);
-    if (code)
-        return code;
+        thyper.LowPart = thyper.HighPart = 0;
+        code = buf_Get(scp, &thyper, &bufp);
 
-    while (1) {
-        code = cm_SyncOp(scp, bufp, userp, reqp, 0,
-                          CM_SCACHESYNC_READ | CM_SCACHESYNC_NEEDCALLBACK);
+        lock_ObtainWrite(&scp->rw);
         if (code)
-            goto done;
+            return code;
 
-       cm_SyncOpDone(scp, bufp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);
+        while (1) {
+            code = cm_SyncOp(scp, bufp, userp, reqp, 0,
+                              CM_SCACHESYNC_READ | CM_SCACHESYNC_NEEDCALLBACK);
+            if (code)
+                goto done;
 
-        if (cm_HaveBuffer(scp, bufp, 0)) 
-            break;
+            cm_SyncOpDone(scp, bufp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);
 
-        /* otherwise load buffer */
-        code = cm_GetBuffer(scp, bufp, NULL, userp, reqp);
-        if (code)
+            if (cm_HaveBuffer(scp, bufp, 0)) 
+                break;
+
+            /* otherwise load buffer */
+            code = cm_GetBuffer(scp, bufp, NULL, userp, reqp);
+            if (code)
+                goto done;
+        }
+        /* locked, has callback, has valid data in buffer */
+        if ((tlen = scp->length.LowPart) > MOUNTPOINTLEN - 1) 
+            return CM_ERROR_TOOBIG;
+        if (tlen <= 0) {
+            code = CM_ERROR_INVAL;
             goto done;
-    }
-    /* locked, has callback, has valid data in buffer */
-    if ((tlen = scp->length.LowPart) > MOUNTPOINTLEN - 1) 
-        return CM_ERROR_TOOBIG;
-    if (tlen <= 0) {
-        code = CM_ERROR_INVAL;
-        goto done;
-    }
+        }
 
-    /* someone else did the work while we were out */
-    if (scp->mountPointStringp[0]) {
-        code = 0;
-        goto done;
-    }
+        /* someone else did the work while we were out */
+        if (scp->mountPointStringp[0]) {
+            code = 0;
+            goto done;
+        }
 
-    /* otherwise, copy out the link */
-    memcpy(scp->mountPointStringp, bufp->datap, tlen);
+        /* otherwise, copy out the link */
+        memcpy(scp->mountPointStringp, bufp->datap, tlen);
 
-    /* now make it null-terminated.  Note that the original contents of a
-     * link that is a mount point is "#volname." where "." is there just to
-     * be turned into a null.  That is, we can trash the last char of the
-     * link without damaging the vol name.  This is a stupid convention,
-     * but that's the protocol.
-     */
-    scp->mountPointStringp[tlen-1] = 0;
-    code = 0;
+        /* now make it null-terminated.  Note that the original contents of a
+         * link that is a mount point is "#volname." where "." is there just to
+         * be turned into a null.  That is, we can trash the last char of the
+         * link without damaging the vol name.  This is a stupid convention,
+         * but that's the protocol.
+         */
+        scp->mountPointStringp[tlen-1] = 0;
+        code = 0;
 
-  done:
-    if (bufp) 
-        buf_Release(bufp);
+      done:
+        if (bufp) 
+            buf_Release(bufp);
+    }
     return code;
 }
 
@@ -1628,51 +1639,64 @@ long cm_HandleLink(cm_scache_t *linkScp, cm_user_t *userp, cm_req_t *reqp)
 
     lock_AssertWrite(&linkScp->rw);
     if (!linkScp->mountPointStringp[0]) {
-        /* read the link data */
-        lock_ReleaseWrite(&linkScp->rw);
-        thyper.LowPart = thyper.HighPart = 0;
-        code = buf_Get(linkScp, &thyper, &bufp);
-        lock_ObtainWrite(&linkScp->rw);
-        if (code) 
-            return code;
-        while (1) {
-            code = cm_SyncOp(linkScp, bufp, userp, reqp, 0,
-                              CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);
-            if (code) {
-                buf_Release(bufp);
+        
+#ifdef AFS_FREELANCE_CLIENT
+       /* File servers do not have data for freelance entries */
+        if (cm_freelanceEnabled &&
+            linkScp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
+            linkScp->fid.volume==AFS_FAKE_ROOT_VOL_ID )
+        {
+            code = cm_FreelanceFetchMountPointString(linkScp);
+        } else 
+#endif /* AFS_FREELANCE_CLIENT */        
+        {
+            /* read the link data from the file server*/
+            lock_ReleaseWrite(&linkScp->rw);
+            thyper.LowPart = thyper.HighPart = 0;
+            code = buf_Get(linkScp, &thyper, &bufp);
+            lock_ObtainWrite(&linkScp->rw);
+            if (code) 
                 return code;
-            }
-           cm_SyncOpDone(linkScp, bufp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);
+            while (1) {
+                code = cm_SyncOp(linkScp, bufp, userp, reqp, 0,
+                                  CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);
+                if (code) {
+                    buf_Release(bufp);
+                    return code;
+                }
+                cm_SyncOpDone(linkScp, bufp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);
 
-            if (cm_HaveBuffer(linkScp, bufp, 0)) 
-                break;
+                if (cm_HaveBuffer(linkScp, bufp, 0)) 
+                    break;
 
-            code = cm_GetBuffer(linkScp, bufp, NULL, userp, reqp);
-            if (code) {
+                code = cm_GetBuffer(linkScp, bufp, NULL, userp, reqp);
+                if (code) {
+                    buf_Release(bufp);
+                    return code;
+                }
+            } /* while loop to get the data */
+
+            /* now if we still have no link read in,
+             * copy the data from the buffer */
+            if ((temp = linkScp->length.LowPart) >= MOUNTPOINTLEN) {
                 buf_Release(bufp);
-                return code;
+                return CM_ERROR_TOOBIG;
+            }       
+
+            /* otherwise, it fits; make sure it is still null (could have
+             * lost race with someone else referencing this link above),
+             * and if so, copy in the data.
+             */
+            if (!linkScp->mountPointStringp[0]) {
+                strncpy(linkScp->mountPointStringp, bufp->datap, temp);
+                linkScp->mountPointStringp[temp] = 0;  /* null terminate */
             }
-        } /* while loop to get the data */
-                
-        /* now if we still have no link read in,
-         * copy the data from the buffer */
-        if ((temp = linkScp->length.LowPart) >= MOUNTPOINTLEN) {
             buf_Release(bufp);
-            return CM_ERROR_TOOBIG;
         }
+        
+        if ( !strnicmp(linkScp->mountPointStringp, "msdfs:", strlen("msdfs:")) )
+            linkScp->fileType = CM_SCACHETYPE_DFSLINK;
 
-        /* otherwise, it fits; make sure it is still null (could have
-         * lost race with someone else referencing this link above),
-         * and if so, copy in the data.
-         */
-        if (!linkScp->mountPointStringp[0]) {
-            strncpy(linkScp->mountPointStringp, bufp->datap, temp);
-            linkScp->mountPointStringp[temp] = 0;      /* null terminate */
-
-            if ( !strnicmp(linkScp->mountPointStringp, "msdfs:", strlen("msdfs:")) )
-                 linkScp->fileType = CM_SCACHETYPE_DFSLINK;
-        }
-        buf_Release(bufp);
     }  /* don't have sym link contents cached */
 
     return 0;