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;
{
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);
// 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);
} 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 */
}
if (cm_freelanceEnabled && special) {
- char mp[MOUNTPOINTLEN] = "";
- afs_uint32 fileType;
-
lock_ReleaseWrite(&cm_scacheLock);
osi_Log0(afsd_logp,"cm_GetSCache Freelance and special");
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 */
}
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;
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;
}
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;