From a43c893d498effd1165bfe78179934194c34b448 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Fri, 4 Sep 2009 23:13:52 -0400 Subject: [PATCH] Windows: Freelance get callback sync and uninitialized variables 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 Reviewed-by: Asanka Herath Tested-by: Jeffrey Altman Reviewed-by: Jeffrey Altman --- src/WINNT/afsd/cm_callback.c | 27 +++++++++++++++++++-------- src/WINNT/afsd/cm_scache.c | 17 ++++++++++++----- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index a488c864a..006cedb48 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -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); diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index 0fafcf577..2e6718c3d 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -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; -- 2.39.5