From: Jeffrey Altman Date: Mon, 5 Jan 2009 16:20:08 +0000 (+0000) Subject: windows-afsd-freelance-20090105 X-Git-Tag: openafs-devel-1_5_61~632 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=8c4b06a5b62a07d4d6733b313ad404e1cb6abe8d windows-afsd-freelance-20090105 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. --- diff --git a/src/WINNT/afsd/afsd.h b/src/WINNT/afsd/afsd.h index aa027af..afa11a8 100644 --- a/src/WINNT/afsd/afsd.h +++ b/src/WINNT/afsd/afsd.h @@ -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 diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index df3a015..32f59ab 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -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 */ diff --git a/src/WINNT/afsd/cm_freelance.c b/src/WINNT/afsd/cm_freelance.c index 5b88d65..fe2085e 100644 --- a/src/WINNT/afsd/cm_freelance.c +++ b/src/WINNT/afsd/cm_freelance.c @@ -18,14 +18,14 @@ 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 */ diff --git a/src/WINNT/afsd/cm_freelance.h b/src/WINNT/afsd/cm_freelance.h index 9f327fa..3b01684 100644 --- a/src/WINNT/afsd/cm_freelance.h +++ b/src/WINNT/afsd/cm_freelance.h @@ -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); diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index 257d0f7..2d143df 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -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; diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index c7a4cab..8122978 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -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;