_done:
lock_ReleaseMutex(&scp->mx);
+ osi_Log3(afsd_logp,"cm_CheckNTOpen scp 0x%p ldp 0x%p code 0x%x", scp, *ldpp, code);
return code;
}
extern long cm_CheckNTOpenDone(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp,
cm_lock_data_t ** ldpp)
{
+ osi_Log2(afsd_logp,"cm_CheckNTOpenDone scp 0x%p ldp 0x%p", scp, *ldpp);
if (*ldpp) {
lock_ObtainMutex(&scp->mx);
cm_Unlock(scp, (*ldpp)->sLockType, (*ldpp)->LOffset, (*ldpp)->LLength,
return code;
thyper.HighPart = 0; thyper.LowPart = 0;
- lock_ObtainRead(&scp->bufCreateLock);
code = buf_Get(scp, &thyper, &bufferp);
- lock_ReleaseRead(&scp->bufCreateLock);
if (code)
return code;
bufferp = NULL;
}
- lock_ObtainRead(&scp->bufCreateLock);
code = buf_Get(scp, &thyper, &bufferp);
- lock_ReleaseRead(&scp->bufCreateLock);
if (code) {
/* if buf_Get() fails we do not have a buffer object to lock */
bufferp = NULL;
/* otherwise, we have to read it in */
lock_ReleaseMutex(&scp->mx);
- lock_ObtainRead(&scp->bufCreateLock);
thyper.LowPart = thyper.HighPart = 0;
code = buf_Get(scp, &thyper, &bufp);
- lock_ReleaseRead(&scp->bufCreateLock);
lock_ObtainMutex(&scp->mx);
if (code)
lock_ObtainMutex(&scp->mx);
if (code == 0) {
+ afs_uint32 cell, volume;
+
/* save the parent of the volume root for this is the
* place where the volume is mounted and we must remember
* this in the volume structure rather than just in the
volp->dotdotFid = dscp->fid;
lock_ReleaseMutex(&volp->mx);
- scp->mountRootFid.cell = cellp->cellID;
+ cell = cellp->cellID;
/* if the mt pt originates in a .backup volume (not a .readonly)
* and FollowBackupPath is active, and if there is a .backup
targetType = ROVOL;
}
if (targetType == ROVOL)
- scp->mountRootFid.volume = volp->ro.ID;
+ volume = volp->ro.ID;
else if (targetType == BACKVOL)
- scp->mountRootFid.volume = volp->bk.ID;
+ volume = volp->bk.ID;
else
- scp->mountRootFid.volume = volp->rw.ID;
+ volume = volp->rw.ID;
/* the rest of the fid is a magic number */
- scp->mountRootFid.vnode = 1;
- scp->mountRootFid.unique = 1;
+ cm_SetFid(&scp->mountRootFid, cell, volume, 1, 1);
scp->mountRootGen = cm_data.mountRootGen;
tfid = scp->mountRootFid;
else
return CM_ERROR_NOSUCHFILE;
}
- else { /* nonexistent dir on freelance root, so add it */
+ else if (!strchr(namep, '#') && !strchr(namep, '%') &&
+ strcmp(namep, "srvsvc") && strcmp(namep, "wkssvc") &&
+ strcmp(namep, "ipc$")) {
+ /* nonexistent dir on freelance root, so add it */
char fullname[200] = ".";
int found = 0;
osi_Log1(afsd_logp,"cm_Lookup adding mount for non-existent directory: %s",
osi_LogSaveString(afsd_logp,namep));
+
+ /*
+ * There is an ugly behavior where a share name "foo" will be searched
+ * for as "fo". If the searched for name differs by an already existing
+ * symlink or mount point in the Freelance directory, do not add the
+ * new value automatically.
+ */
+
+ code = -1;
if (namep[0] == '.') {
if (cm_GetCell_Gen(&namep[1], &fullname[1], CM_FLAG_CREATE)) {
found = 1;
- if ( stricmp(&namep[1], &fullname[1]) )
+ if (!cm_FreelanceMountPointExists(fullname, 0))
+ code = cm_FreelanceAddMount(fullname, &fullname[1], "root.cell.", 1, &rock.fid);
+ if ( stricmp(&namep[1], &fullname[1]) &&
+ !cm_FreelanceMountPointExists(namep, flags & CM_FLAG_DFS_REFERRAL ? 1 : 0) &&
+ !cm_FreelanceSymlinkExists(namep, flags & CM_FLAG_DFS_REFERRAL ? 1 : 0))
code = cm_FreelanceAddSymlink(namep, fullname, &rock.fid);
- else
- code = cm_FreelanceAddMount(namep, &fullname[1], "root.cell.", 1, &rock.fid);
}
} else {
if (cm_GetCell_Gen(namep, fullname, CM_FLAG_CREATE)) {
found = 1;
- if ( stricmp(namep, fullname) )
+ if (!cm_FreelanceMountPointExists(fullname, 0))
+ code = cm_FreelanceAddMount(fullname, fullname, "root.cell.", 0, &rock.fid);
+ if ( stricmp(namep, fullname) &&
+ !cm_FreelanceMountPointExists(namep, flags & CM_FLAG_DFS_REFERRAL ? 1 : 0) &&
+ !cm_FreelanceSymlinkExists(namep, flags & CM_FLAG_DFS_REFERRAL ? 1 : 0))
code = cm_FreelanceAddSymlink(namep, fullname, &rock.fid);
- else
- code = cm_FreelanceAddMount(namep, fullname, "root.cell.", 0, &rock.fid);
}
}
if (!found || code < 0) { /* add mount point failed, so give up */
cm_cell_t * cellp = NULL;
cm_volume_t * volp = NULL;
cm_fid_t fid;
+ afs_uint32 volume;
int volType;
int mountType = RWVOL;
if (code != 0)
goto _exit_cleanup;
- fid.cell = cellp->cellID;
-
if (volType == BACKVOL)
- fid.volume = volp->bk.ID;
+ volume = volp->bk.ID;
else if (volType == ROVOL ||
(volType == RWVOL && mountType == ROVOL && volp->ro.ID != 0))
- fid.volume = volp->ro.ID;
+ volume = volp->ro.ID;
else
- fid.volume = volp->rw.ID;
+ volume = volp->rw.ID;
- fid.vnode = 1;
- fid.unique = 1;
+ cm_SetFid(&fid, cellp->cellID, volume, 1, 1);
code = cm_GetSCache(&fid, outpScpp, userp, reqp);
if (strcmp(dep->name, ".") == 0 || strcmp(dep->name, "..") == 0)
return 0;
- tfid.cell = scp->fid.cell;
- tfid.volume = scp->fid.volume;
- tfid.vnode = ntohl(dep->fid.vnode);
- tfid.unique = ntohl(dep->fid.unique);
+ cm_SetFid(&tfid, scp->fid.cell, scp->fid.volume, ntohl(dep->fid.vnode), ntohl(dep->fid.unique));
tscp = cm_FindSCache(&tfid);
if (tscp) {
if (lock_TryMutex(&tscp->mx)) {
/* otherwise, we should do the merges */
for (i = 0; i<filesThisCall; i++) {
j = filex + i;
- tfid.cell = dscp->fid.cell;
- tfid.volume = bb.fids[j].Volume;
- tfid.vnode = bb.fids[j].Vnode;
- tfid.unique = bb.fids[j].Unique;
+ cm_SetFid(&tfid, dscp->fid.cell, bb.fids[j].Volume, bb.fids[j].Vnode, bb.fids[j].Unique);
code = cm_GetSCache(&tfid, &scp, userp, reqp);
if (code != 0)
continue;
return CM_ERROR_ATSYS;
}
+#ifdef AFS_FREELANCE_CLIENT
+ /* Freelance root volume does not hold files */
+ if (cm_freelanceEnabled &&
+ dscp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
+ dscp->fid.volume==AFS_FAKE_ROOT_VOL_ID )
+ {
+ return CM_ERROR_NOACCESS;
+ }
+#endif /* AFS_FREELANCE_CLIENT */
+
/* before starting the RPC, mark that we're changing the file data, so
* that someone who does a chmod will know to wait until our call
* completes.
* info.
*/
if (code == 0) {
- newFid.cell = dscp->fid.cell;
- newFid.volume = dscp->fid.volume;
- newFid.vnode = newAFSFid.Vnode;
- newFid.unique = newAFSFid.Unique;
+ cm_SetFid(&newFid, dscp->fid.cell, dscp->fid.volume, newAFSFid.Vnode, newAFSFid.Unique);
code = cm_GetSCache(&newFid, &scp, userp, reqp);
if (code == 0) {
lock_ObtainMutex(&scp->mx);
{
long code;
- lock_ObtainWrite(&scp->bufCreateLock);
code = buf_CleanVnode(scp, userp, reqp);
- lock_ReleaseWrite(&scp->bufCreateLock);
if (code == 0) {
lock_ObtainMutex(&scp->mx);
return CM_ERROR_ATSYS;
}
+#ifdef AFS_FREELANCE_CLIENT
+ /* Freelance root volume does not hold subdirectories */
+ if (cm_freelanceEnabled &&
+ dscp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
+ dscp->fid.volume==AFS_FAKE_ROOT_VOL_ID )
+ {
+ return CM_ERROR_NOACCESS;
+ }
+#endif /* AFS_FREELANCE_CLIENT */
+
/* before starting the RPC, mark that we're changing the directory
* data, so that someone who does a chmod on the dir will wait until
* our call completes.
* info.
*/
if (code == 0) {
- newFid.cell = dscp->fid.cell;
- newFid.volume = dscp->fid.volume;
- newFid.vnode = newAFSFid.Vnode;
- newFid.unique = newAFSFid.Unique;
+ cm_SetFid(&newFid, dscp->fid.cell, dscp->fid.volume, newAFSFid.Vnode, newAFSFid.Unique);
code = cm_GetSCache(&newFid, &scp, userp, reqp);
if (code == 0) {
lock_ObtainMutex(&scp->mx);
if (code == 0) {
if (cm_CheckDirOpForSingleChange(&dirop)) {
- newFid.cell = dscp->fid.cell;
- newFid.volume = dscp->fid.volume;
- newFid.vnode = newAFSFid.Vnode;
- newFid.unique = newAFSFid.Unique;
+ cm_SetFid(&newFid, dscp->fid.cell, dscp->fid.volume, newAFSFid.Vnode, newAFSFid.Unique);
cm_DirCreateEntry(&dirop, namep, &newFid);
#ifdef USE_BPLUS
* info.
*/
if (code == 0) {
- newFid.cell = dscp->fid.cell;
- newFid.volume = dscp->fid.volume;
- newFid.vnode = newAFSFid.Vnode;
- newFid.unique = newAFSFid.Unique;
+ cm_SetFid(&newFid, dscp->fid.cell, dscp->fid.volume, newAFSFid.Vnode, newAFSFid.Unique);
code = cm_GetSCache(&newFid, &scp, userp, reqp);
if (code == 0) {
lock_ObtainMutex(&scp->mx);
#endif
}
-/* Forward dcl. */
-static void cm_LockMarkSCacheLost(cm_scache_t * scp);
-
/* Called with cm_scacheLock write locked */
static cm_file_lock_t * cm_GetFileLock(void) {
cm_file_lock_t * l;
lock_ReleaseRead(&cm_scacheLock);
/* The lock didn't exist anyway. *shrug* */
- return 0;
+ return CM_ERROR_RANGE_NOT_LOCKED;
}
lock_ReleaseRead(&cm_scacheLock);
}
/* called with scp->mx held */
-static void cm_LockMarkSCacheLost(cm_scache_t * scp)
+void cm_LockMarkSCacheLost(cm_scache_t * scp)
{
cm_file_lock_t *fileLock;
osi_queue_t *q;
if (!IS_LOCK_ACTIVE(fileLock))
goto pre_syncopdone;
- if (scp->serverLock != -1) {
+ if (scp->serverLock != -1 && !(scp->flags & CM_SCACHEFLAG_DELETED)) {
cm_fid_t cfid;
cm_user_t * userp;
}
}
- if (code == EINVAL || code == CM_ERROR_INVAL) {
+ if (code == EINVAL || code == CM_ERROR_INVAL ||
+ code == CM_ERROR_BADFD) {
cm_LockMarkSCacheLost(scp);
}