]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Windows: Freelance get callback sync and uninitialized variables
authorJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 5 Sep 2009 03:13:52 +0000 (23:13 -0400)
committerJeffrey Altman <jaltman|account-1000011@unknown>
Sat, 5 Sep 2009 13:41:32 +0000 (06:41 -0700)
In cm_GetCallback the Freelance mode case did not properly
synchronize attempts to fake obtain a callback.

cm_GetCallback also failed to initialize the contents of afsStatus and
volSync which are used as input to cm_MergeStatus.
cm_MergeStatus special cased the freelance root.afs volume root
directory but failed to handle any other freelance volume objects.
As a result it used the contents of the uninitialzed input structures
to populate the status of the object for which the callback was
obtained.

LICENSE MIT

Reviewed-on: http://gerrit.openafs.org/401
Tested-by: Asanka Herath <asanka@secure-endpoints.com>
Reviewed-by: Asanka Herath <asanka@secure-endpoints.com>
Tested-by: Jeffrey Altman <jaltman@openafs.org>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
src/WINNT/afsd/cm_callback.c
src/WINNT/afsd/cm_scache.c

index a488c864af75372fcf18ffff8916baf58d45bd22..006cedb48ce3ac241e386621656210d6425a4b81 100644 (file)
@@ -1772,31 +1772,41 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp,
     // The case where a callback is needed on /afs is handled
     // specially. We need to fetch the status by calling
     // 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) {
+    if (cm_freelanceEnabled &&
+        (scp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
+         scp->fid.volume==AFS_FAKE_ROOT_VOL_ID)) {
+
+        code = cm_SyncOp(scp, NULL, userp, reqp, 0,
+                          CM_SCACHESYNC_FETCHSTATUS | CM_SCACHESYNC_GETCALLBACK);
+        if (code)
+            goto done;
+        syncop_done = 1;
+
+        if (cm_fakeDirCallback != 2) {
             // Start by indicating that we're in the process
             // of fetching the callback
             lock_ObtainMutex(&cm_Freelance_Lock);
-            osi_Log0(afsd_logp,"cm_getGetCallback fakeGettingCallback=1");
+            osi_Log0(afsd_logp,"GetCallback Freelance fakeGettingCallback=1");
             cm_fakeGettingCallback = 1;
             lock_ReleaseMutex(&cm_Freelance_Lock);
 
+            memset(&afsStatus, 0, sizeof(afsStatus));
+            memset(&volSync, 0, sizeof(volSync));
+
             // Fetch the status info 
             cm_MergeStatus(NULL, scp, &afsStatus, &volSync, userp, reqp, 0);
 
             // Indicate that the callback is not done
             lock_ObtainMutex(&cm_Freelance_Lock);
-            osi_Log0(afsd_logp,"cm_getGetCallback fakeDirCallback=2");
+            osi_Log0(afsd_logp,"GetCallback Freelance fakeDirCallback=2");
             cm_fakeDirCallback = 2;
 
             // Indicate that we're no longer fetching the callback
-            osi_Log0(afsd_logp,"cm_getGetCallback fakeGettingCallback=0");
+            osi_Log0(afsd_logp,"GetCallback Freelance fakeGettingCallback=0");
             cm_fakeGettingCallback = 0;
             lock_ReleaseMutex(&cm_Freelance_Lock);
-
-            return 0;
         }
+        goto done;
     }
 #endif /* AFS_FREELANCE_CLIENT */
        
@@ -1857,6 +1867,7 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp,
            break;
     }
 
+  done:
     if (syncop_done)
        cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_FETCHSTATUS | CM_SCACHESYNC_GETCALLBACK);
     
index 0fafcf577c5d9a97856e0f9b0e620e8a47ab6a3e..2e6718c3d9ab2bb11c2d16eac1a228aa7431d570 100644 (file)
@@ -1507,13 +1507,20 @@ void cm_MergeStatus(cm_scache_t *dscp,
     // yj: i want to create some fake status for the /afs directory and the
     // entries under that directory
 #ifdef AFS_FREELANCE_CLIENT
-    if (cm_freelanceEnabled && scp == cm_data.rootSCachep) {
-        osi_Log0(afsd_logp,"cm_MergeStatus Freelance cm_data.rootSCachep");
+    if (cm_freelanceEnabled && scp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
+         scp->fid.volume==AFS_FAKE_ROOT_VOL_ID) {
+        if (scp == cm_data.rootSCachep) {
+            osi_Log0(afsd_logp,"cm_MergeStatus Freelance cm_data.rootSCachep");
+            statusp->FileType = CM_SCACHETYPE_DIRECTORY;
+            statusp->Length = cm_fakeDirSize;
+            statusp->Length_hi = 0;
+        } else {
+            statusp->FileType = scp->fileType;
+            statusp->Length = scp->length.LowPart;
+            statusp->Length_hi = scp->length.HighPart;
+        }
         statusp->InterfaceVersion = 0x1;
-        statusp->FileType = CM_SCACHETYPE_DIRECTORY;
         statusp->LinkCount = scp->linkCount;
-        statusp->Length = cm_fakeDirSize;
-        statusp->Length_hi = 0;
         statusp->DataVersion = (afs_uint32)(cm_data.fakeDirVersion & 0xFFFFFFFF);
         statusp->Author = 0x1;
         statusp->Owner = 0x0;