/* unrewritten mount point? */
if (tvc->mvstat == AFS_MVSTAT_MTPT) {
- if (tvc->mvid && (tvc->f.states & CMValid)) {
+ if (tvc->mvid.target_root && (tvc->f.states & CMValid)) {
struct vrequest treq;
afs_InitFakeStat(&fakestate);
#ifdef AFS_SGI64_ENV
qprintf(" mapcnt %llu, mvstat %d anyAcc 0x%x Access 0x%x\n",
avc->mapcnt, avc->mvstat, avc->f.anyAccess, avc->Access);
- qprintf(" mvid 0x%x &lock 0x%x cred 0x%x\n", avc->mvid, &avc->lock,
+ qprintf(" mvid 0x%x &lock 0x%x cred 0x%x\n", avc->mvid.target_root, &avc->lock,
avc->cred);
qprintf(" rwlock 0x%x (%d) id %llu trips %d\n", &avc->vc_rwlock,
valusema(&avc->vc_rwlock), avc->vc_rwlockid, avc->vc_locktrips);
#else
qprintf(" mapcnt %d mvstat %d anyAcc 0x%x Access 0x%x\n", avc->mapcnt,
avc->mvstat, avc->f.anyAccess, avc->Access);
- qprintf(" mvid 0x%x &lock 0x%x cred 0x%x\n", avc->mvid, &avc->lock,
+ qprintf(" mvid 0x%x &lock 0x%x cred 0x%x\n", avc->mvid.target_root, &avc->lock,
avc->cred);
qprintf(" rwlock 0x%x (%d) id %d trips %d\n", &avc->vc_rwlock,
valusema(&avc->vc_rwlock), avc->vc_rwlockid, avc->vc_locktrips);
} else if (vcp->mvstat == AFS_MVSTAT_ROOT) {
/* volume root */
ObtainReadLock(&vcp->lock);
- if (vcp->mvid && vcp->mvid->Fid.Volume) {
- tfid = *vcp->mvid;
+ if (vcp->mvid.parent && vcp->mvid.parent->Fid.Volume) {
+ tfid = *vcp->mvid.parent;
ReleaseReadLock(&vcp->lock);
} else {
ReleaseReadLock(&vcp->lock);
if (locked) {
if (vcp->mvstat == AFS_MVSTAT_MTPT) {
- if (vcp->mvid && (vcp->f.states & CMValid)) {
+ if (vcp->mvid.target_root && (vcp->f.states & CMValid)) {
int tryEvalOnly = 0;
int code = 0;
struct vrequest *treq = NULL;
}
}
} else if (vcp->mvstat == AFS_MVSTAT_ROOT && *dp->d_name.name != '/') {
- osi_Assert(vcp->mvid != NULL);
+ osi_Assert(vcp->mvid.parent != NULL);
}
}
VTOAFS(dir), (char *)__dp->d_name.name,
credp);
if (!code) {
- tvc->mvid = (void *) __name;
+ tvc->mvid.silly_name = __name;
crhold(credp);
if (tvc->uncred) {
crfree(tvc->uncred);
/* Disconnected. */
/* We have the dir entry now, we can use it while disconnected. */
- if (adp->mvid == NULL) {
+ if (adp->mvid.target_root == NULL) {
/* If not mount point, generate a new fid. */
newFid.Cell = adp->f.fid.Cell;
newFid.Fid.Volume = adp->f.fid.Fid.Volume;
* what "@sys" is in binary... */
#define AFS_EQ_ATSYS(name) (((name)[0]=='@')&&((name)[1]=='s')&&((name)[2]=='y')&&((name)[3]=='s')&&(!(name)[4]))
-/* call under write lock, evaluate mvid field from a mt pt.
+/* call under write lock, evaluate mvid.target_root field from a mt pt.
* avc is the vnode of the mount point object; must be write-locked.
* advc is the vnode of the containing directory (optional; if NULL and
* EvalMountPoint succeeds, caller must initialize *avolpp->dotdot)
AFS_STATCNT(EvalMountPoint);
#ifdef notdef
- if (avc->mvid && (avc->f.states & CMValid))
+ if (avc->mvid.target_root && (avc->f.states & CMValid))
return 0; /* done while racing */
#endif
*avolpp = NULL;
if (!auniq)
auniq = 1;
- if (avc->mvid == 0)
- avc->mvid = osi_AllocSmallSpace(sizeof(struct VenusFid));
- avc->mvid->Cell = (*avolpp)->cell;
- avc->mvid->Fid.Volume = (*avolpp)->volume;
- avc->mvid->Fid.Vnode = avnoid;
- avc->mvid->Fid.Unique = auniq;
+ if (avc->mvid.target_root == NULL)
+ avc->mvid.target_root = osi_AllocSmallSpace(sizeof(struct VenusFid));
+ avc->mvid.target_root->Cell = (*avolpp)->cell;
+ avc->mvid.target_root->Fid.Volume = (*avolpp)->volume;
+ avc->mvid.target_root->Fid.Vnode = avnoid;
+ avc->mvid.target_root->Fid.Unique = auniq;
avc->f.states |= CMValid;
/* Used to: if the mount point is stored within a backup volume,
tvolp->dotdot.Fid.Unique = tvc->f.parent.unique;
}
}
- if (tvc->mvid && (tvc->f.states & CMValid)) {
+ if (tvc->mvid.target_root && (tvc->f.states & CMValid)) {
if (!canblock) {
afs_int32 retry;
do {
retry = 0;
ObtainWriteLock(&afs_xvcache, 597);
- root_vp = afs_FindVCache(tvc->mvid, &retry, IS_WLOCK);
+ root_vp = afs_FindVCache(tvc->mvid.target_root, &retry, IS_WLOCK);
if (root_vp && retry) {
ReleaseWriteLock(&afs_xvcache);
afs_PutVCache(root_vp);
} while (root_vp && retry);
ReleaseWriteLock(&afs_xvcache);
} else {
- root_vp = afs_GetVCache(tvc->mvid, areq, NULL, NULL);
+ root_vp = afs_GetVCache(tvc->mvid.target_root, areq, NULL, NULL);
}
if (!root_vp) {
code = canblock ? ENOENT : 0;
* NBObtainWriteLock to avoid potential deadlock.
*/
ObtainWriteLock(&root_vp->lock, 598);
- if (!root_vp->mvid)
- root_vp->mvid = osi_AllocSmallSpace(sizeof(struct VenusFid));
- *root_vp->mvid = tvolp->dotdot;
+ if (!root_vp->mvid.parent)
+ root_vp->mvid.parent = osi_AllocSmallSpace(sizeof(struct VenusFid));
+ *root_vp->mvid.parent = tvolp->dotdot;
ReleaseWriteLock(&root_vp->lock);
}
state->need_release = 1;
/* now copy ".." entry back out of volume structure, if necessary */
if (tvcp->mvstat == AFS_MVSTAT_ROOT && (dotdot.Fid.Volume != 0)) {
- if (!tvcp->mvid)
- tvcp->mvid = osi_AllocSmallSpace(sizeof(struct VenusFid));
- *tvcp->mvid = dotdot;
+ if (!tvcp->mvid.parent)
+ tvcp->mvid.parent = osi_AllocSmallSpace(sizeof(struct VenusFid));
+ *tvcp->mvid.parent = dotdot;
}
#ifdef AFS_DARWIN80_ENV
/* watch for ".." in a volume root */
if (adp->mvstat == AFS_MVSTAT_ROOT && aname[0] == '.' && aname[1] == '.' && !aname[2]) {
/* looking up ".." in root via special hacks */
- if (adp->mvid == (struct VenusFid *)0 || adp->mvid->Fid.Volume == 0) {
+ if (adp->mvid.parent == (struct VenusFid *)0 || adp->mvid.parent->Fid.Volume == 0) {
code = ENODEV;
goto done;
}
/* otherwise we have the fid here, so we use it */
/*printf("Getting vcache\n");*/
- tvc = afs_GetVCache(adp->mvid, treq, NULL, NULL);
- afs_Trace3(afs_iclSetp, CM_TRACE_GETVCDOTDOT, ICL_TYPE_FID, adp->mvid,
+ tvc = afs_GetVCache(adp->mvid.parent, treq, NULL, NULL);
+ afs_Trace3(afs_iclSetp, CM_TRACE_GETVCDOTDOT, ICL_TYPE_FID, adp->mvid.parent,
ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32, code);
*avcp = tvc;
code = (tvc ? 0 : ENOENT);
force_eval = 1;
ReleaseReadLock(&tvc->lock);
}
- if (tvc->mvstat == AFS_MVSTAT_MTPT && (tvc->f.states & CMValid) && tvc->mvid != NULL)
+ if (tvc->mvstat == AFS_MVSTAT_MTPT && (tvc->f.states & CMValid) && tvc->mvid.target_root != NULL)
force_eval = 1; /* This is now almost for free, get it correct */
#if defined(UKERNEL)
}
/* next, we want to continue using the target of the mt point */
- if (tvc->mvid && (tvc->f.states & CMValid)) {
+ if (tvc->mvid.target_root && (tvc->f.states & CMValid)) {
struct vcache *uvc;
/* now lookup target, to set .. pointer */
afs_Trace2(afs_iclSetp, CM_TRACE_LOOKUP1,
if (tvolp && (tvolp->states & VForeign)) {
/* XXXX tvolp has ref cnt on but not locked! XXX */
tvc =
- afs_GetRootVCache(tvc->mvid, treq, NULL, tvolp);
+ afs_GetRootVCache(tvc->mvid.target_root, treq, NULL, tvolp);
} else {
- tvc = afs_GetVCache(tvc->mvid, treq, NULL, NULL);
+ tvc = afs_GetVCache(tvc->mvid.target_root, treq, NULL, NULL);
}
afs_PutVCache(uvc); /* we're done with it */
* ptr to point back to the appropriate place */
if (tvolp) {
ObtainWriteLock(&tvc->lock, 134);
- if (tvc->mvid == NULL) {
- tvc->mvid =
+ if (tvc->mvid.parent == NULL) {
+ tvc->mvid.parent =
osi_AllocSmallSpace(sizeof(struct VenusFid));
}
/* setup backpointer */
- *tvc->mvid = tvolp->dotdot;
+ *tvc->mvid.parent = tvolp->dotdot;
ReleaseWriteLock(&tvc->lock);
afs_PutVolume(tvolp, WRITE_LOCK);
}
} else if (vc->mvstat == AFS_MVSTAT_ROOT) {
/* We are a volume root, which means our parent is in another
* volume. Luckily, we should have his fid cached... */
- if (vc->mvid) {
- if (!FidCmp(&afs_rootFid, vc->mvid)) {
+ if (vc->mvid.parent) {
+ if (!FidCmp(&afs_rootFid, vc->mvid.parent)) {
/* Parent directory is the root of the AFS root */
Volume = 0;
Vnode = 2;
- } else if (vc->mvid->Fid.Vnode == 1
- && vc->mvid->Fid.Unique == 1) {
+ } else if (vc->mvid.parent->Fid.Vnode == 1
+ && vc->mvid.parent->Fid.Unique == 1) {
/* XXX The above test is evil and probably breaks DFS */
/* Parent directory is the target of a mount point */
- tvp = afs_GetVolume(vc->mvid, 0, READ_LOCK);
+ tvp = afs_GetVolume(vc->mvid.parent, 0, READ_LOCK);
if (tvp) {
Volume = tvp->mtpoint.Fid.Volume;
Vnode = tvp->mtpoint.Fid.Vnode;
}
} else {
/* Parent directory is not a volume root */
- Volume = vc->mvid->Fid.Volume;
- Vnode = vc->mvid->Fid.Vnode;
+ Volume = vc->mvid.parent->Fid.Volume;
+ Vnode = vc->mvid.parent->Fid.Vnode;
}
}
} else if (de->fid.vnode == 1 && de->fid.vunique == 1) {
code = afsrename(adp, aname, adp, unlname, acred, treq);
Tnam1 = unlname;
if (!code) {
- struct VenusFid *oldmvid = NULL;
- if (tvc->mvid)
- oldmvid = tvc->mvid;
- tvc->mvid = (struct VenusFid *)unlname;
+ void *oldmvid = NULL;
+ if (tvc->mvid.silly_name)
+ oldmvid = tvc->mvid.silly_name;
+ tvc->mvid.silly_name = unlname;
if (oldmvid)
osi_FreeSmallSpace(oldmvid);
crhold(acred);
}
#endif
- if (avc->mvid && (doit || (avc->f.states & CUnlinkedDel))) {
+ if (avc->mvid.silly_name && (doit || (avc->f.states & CUnlinkedDel))) {
struct vrequest *treq = NULL;
if ((code = afs_CreateReq(&treq, avc->uncred))) {
/* Must bump the refCount because GetVCache may block.
* Also clear mvid so no other thread comes here if we block.
*/
- unlname = (char *)avc->mvid;
- avc->mvid = NULL;
+ unlname = avc->mvid.silly_name;
+ avc->mvid.silly_name = NULL;
cred = avc->uncred;
avc->uncred = NULL;
#endif
#endif
- struct VenusFid *mvid; /* Either parent dir (if root) or root (if mt pt) */
+ union {
+ char *silly_name; /* For sillyrenamed regular files, the silly
+ * name the file was renamed to. */
+ struct VenusFid *target_root; /* For mountpoints, the fid of the root dir
+ * in the target volume. */
+ struct VenusFid *parent; /* For root dir vcaches, the fid of the
+ * parent dir. */
+ } mvid;
+
char *linkData; /* Link data if a symlink. */
afs_hyper_t flushDV; /* data version last flushed from text */
afs_hyper_t mapDV; /* data version last flushed from map */
uq = QPrev(tq);
AFS_FAST_RELE(tvc);
} else if ((tvc->f.states & CMValid)
- && (tvc->mvid->Fid.Volume == a_fid->Volume)) {
+ && (tvc->mvid.target_root->Fid.Volume == a_fid->Volume)) {
tvc->f.states &= ~CMValid;
if (!localFid.Cell)
- localFid.Cell = tvc->mvid->Cell;
+ localFid.Cell = tvc->mvid.target_root->Cell;
}
}
ReleaseReadLock(&afs_xvcache);
}
#endif
- if (avc->mvid)
- osi_FreeSmallSpace(avc->mvid);
- avc->mvid = (struct VenusFid *)0;
+ if (avc->mvid.target_root)
+ osi_FreeSmallSpace(avc->mvid.target_root);
+ avc->mvid.target_root = NULL;
if (avc->linkData) {
afs_osi_Free(avc->linkData, strlen(avc->linkData) + 1);
avc->linkData = NULL;
AFS_RWLOCK_INIT(&avc->lock, "vcache lock");
- avc->mvid = NULL;
+ memset(&avc->mvid, 0, sizeof(avc->mvid));
avc->linkData = NULL;
avc->cbExpires = 0;
avc->opens = 0;
tvc->f.states |= CBackup;
/* now copy ".." entry back out of volume structure, if necessary */
if (tvc->mvstat == AFS_MVSTAT_ROOT && tvp->dotdot.Fid.Volume != 0) {
- if (!tvc->mvid)
- tvc->mvid = (struct VenusFid *)
+ if (!tvc->mvid.parent)
+ tvc->mvid.parent = (struct VenusFid *)
osi_AllocSmallSpace(sizeof(struct VenusFid));
- *tvc->mvid = tvp->dotdot;
+ *tvc->mvid.parent = tvp->dotdot;
}
afs_PutVolume(tvp, READ_LOCK);
}
tvc->f.states |= CBackup;
/* now copy ".." entry back out of volume structure, if necessary */
if (tvc->mvstat == AFS_MVSTAT_ROOT && tvp->dotdot.Fid.Volume != 0) {
- if (!tvc->mvid)
- tvc->mvid = (struct VenusFid *)
+ if (!tvc->mvid.parent)
+ tvc->mvid.parent = (struct VenusFid *)
osi_AllocSmallSpace(sizeof(struct VenusFid));
- *tvc->mvid = tvp->dotdot;
+ *tvc->mvid.parent = tvp->dotdot;
}
}
tvc->mvstat = AFS_MVSTAT_ROOT;
}
if (tvc->mvstat == AFS_MVSTAT_ROOT && tvolp->dotdot.Fid.Volume != 0) {
- if (!tvc->mvid)
- tvc->mvid = (struct VenusFid *)
+ if (!tvc->mvid.parent)
+ tvc->mvid.parent = (struct VenusFid *)
osi_AllocSmallSpace(sizeof(struct VenusFid));
- *tvc->mvid = tvolp->dotdot;
+ *tvc->mvid.parent = tvolp->dotdot;
}
/* stat the file */
* necessary
*/
if (tvc->mvstat == AFS_MVSTAT_ROOT && tvp->dotdot.Fid.Volume != 0) {
- if (!tvc->mvid)
- tvc->mvid = (struct VenusFid *)
+ if (!tvc->mvid.parent)
+ tvc->mvid.parent = (struct VenusFid *)
osi_AllocSmallSpace(sizeof(struct VenusFid));
- *tvc->mvid = tvp->dotdot;
+ *tvc->mvid.parent = tvp->dotdot;
}
}
/* store the stat on the file */
for (tq = VLRU.prev; tq != &VLRU; tq = uq) {
tvc = QTOV(tq);
uq = QPrev(tq);
- if (tvc->mvid) {
- osi_FreeSmallSpace(tvc->mvid);
- tvc->mvid = (struct VenusFid *)0;
+ if (tvc->mvid.target_root) {
+ osi_FreeSmallSpace(tvc->mvid.target_root);
+ tvc->mvid.target_root = NULL;
}
#ifdef AFS_AIX_ENV
aix_gnode_rele(AFSTOV(tvc));
*/
for (i = 0; i < VCSIZE; i++) {
for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
- if (tvc->mvid) {
- osi_FreeSmallSpace(tvc->mvid);
- tvc->mvid = (struct VenusFid *)0;
+ if (tvc->mvid.target_root) {
+ osi_FreeSmallSpace(tvc->mvid.target_root);
+ tvc->mvid.target_root = NULL;
}
#ifdef AFS_AIX_ENV
if (tvc->v.v_gnode)
for (i = 0; i < VCSIZE; i++) {
for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
- /* if the volume of "mvid" of the vcache entry is among the
- * ones we found earlier, then we re-evaluate it. Also, if the
- * force bit is set or we explicitly asked to reevaluate the
- * mt-pts, we clean the cmvalid bit */
+ /* if the volume of "mvid.target_root" of the vcache entry is
+ * among the ones we found earlier, then we re-evaluate it.
+ * Also, if the force bit is set or we explicitly asked to
+ * reevaluate the mt-pts, we clean the cmvalid bit */
if ((flags & (AFS_VOLCHECK_FORCE | AFS_VOLCHECK_MTPTS))
- || (tvc->mvid
- && inVolList(tvc->mvid, nvols, volumeID, cellID)))
+ || (tvc->mvid.target_root
+ && inVolList(tvc->mvid.target_root, nvols, volumeID, cellID)))
tvc->f.states &= ~CMValid;
/* If the volume that this file belongs to was reset earlier,