afs_syscall_icreate(long dev, long near_inode, long param1, long param2,
long param3, long param4, long *retval)
{
- return EOPNOTSUPP;
+ return ENOTSUP;
}
int
afs_syscall_iopen(int dev, int inode, int usrmod, long *retval)
{
- return EOPNOTSUPP;
+ return ENOTSUP;
}
int
afs_syscall_iincdec(int dev, int inode, int inode_p1, int amount)
{
- return EOPNOTSUPP;
+ return ENOTSUP;
}
extern int osi_VM_Setup(struct vcache *avc, int force);
/* osi_vnodeops.c */
-extern int afs_darwin_getnewvnode(struct vcache *avc, int recycle);
+extern int afs_darwin_getnewvnode(struct vcache *avc);
extern int afs_darwin_finalizevnode(struct vcache *avc, struct vnode *parent,
struct componentname *cnp, int isroot,
int locked);
osi_AttachVnode(struct vcache *avc, int seq) {
ReleaseWriteLock(&afs_xvcache);
AFS_GUNLOCK();
- afs_darwin_getnewvnode(avc, seq ? 0 : 1); /* includes one refcount */
+ afs_darwin_getnewvnode(avc); /* includes one refcount */
AFS_GLOCK();
ObtainWriteLock(&afs_xvcache,338);
#ifdef AFS_DARWIN80_ENV
osi_PostPopulateVCache(struct vcache *avc) {
#if !defined(AFS_DARWIN80_ENV)
avc->v->v_mount = afs_globalVFS;
-#endif
vSetType(avc, VREG);
+#else
+ vSetType(avc, VNON);
+#endif
}
int
afs_quotactl()
{
- return EOPNOTSUPP;
+ return ENOTSUP;
}
int
AFS_GLOCK();
if (error)
tvp = NULL;
- else
+ else
/* re-acquire the usecount that finalizevnode disposed of */
vnode_ref(AFSTOV(tvp));
}
}
break;
}
- return EOPNOTSUPP;
+ return ENOTSUP;
}
typedef (*PFI) ();
struct vnode *vp = ap->a_vp;
int haveGlock = ISAFS_GLOCK();
+ /* in order to recycle faked vnodes for bulkstat */
+ if (VTOAFS(vp) == NULL)
+ return ENOTSUP;
+
/* afs_vop_lookup glocks, can call us through vinvalbuf from GetVCache */
if (!haveGlock) AFS_GLOCK();
if (vop_cred)
* } */ *ap;
{
/* printf("stray afs_vop_truncate\n"); */
- return EOPNOTSUPP;
+ return ENOTSUP;
}
int
* } */ *ap;
{
/* printf("stray afs_vop_update\n"); */
- return EOPNOTSUPP;
+ return ENOTSUP;
}
int
#endif
int
-afs_darwin_getnewvnode(struct vcache *avc, int recycle)
+afs_darwin_getnewvnode(struct vcache *avc)
{
#ifdef AFS_DARWIN80_ENV
vnode_t vp;
vnode_addfsref(vp);
vnode_ref(vp);
avc->v = vp;
- if (recycle)
- vnode_recycle(vp); /* terminate as soon as iocount drops */
+ vnode_recycle(vp); /* terminate as soon as iocount drops */
avc->f.states |= CDeadVnode;
}
return error;
#ifdef AFS_DARWIN80_ENV
/* if this fails, then tvc has been unrefed and may have been freed.
Don't touch! */
-int
-afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp, struct componentname *cnp, int isroot, int locked)
+int
+afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp,
+ struct componentname *cnp, int isroot, int locked)
{
vnode_t ovp;
vnode_t nvp;
int error;
struct vnode_fsparam par;
+
if (!locked) {
AFS_GLOCK();
ObtainWriteLock(&avc->lock,325);
}
ovp = AFSTOV(avc);
- if (!(avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON) {
- AFS_GUNLOCK();
+
+ /* if the type changed, we still need to do a fixup, for bulkstat */
+ if (vnode_vtype(ovp) == avc->f.m.Type && !(avc->f.states & CDeadVnode)
+ && vnode_vtype(ovp) != VNON)
+ {
+ AFS_GUNLOCK();
#if 0 /* unsupported */
if (dvp && cnp)
vnode_update_identity(ovp, dvp, cnp->cn_nameptr, cnp->cn_namelen,
VNODE_UPDATE_PARENT|VNODE_UPDATE_NAME);
#endif
/* Can end up in reclaim... drop GLOCK */
- vnode_rele(ovp);
+ vnode_rele(ovp);
AFS_GLOCK();
if (!locked) {
ReleaseWriteLock(&avc->lock);
AFS_GUNLOCK();
}
- return 0;
+ return 0;
}
+
if ((avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON)
panic("vcache %p should not be CDeadVnode", avc);
AFS_GUNLOCK();
if ((avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON)
printf("vcache %p should not be CDeadVnode", avc);
if (avc->v == ovp) {
- if (avc->f.states & CBulkFetching) {
- vnode_recycle(ovp);
- }
if (!(avc->f.states & CVInit)) {
vnode_clearfsnode(ovp);
vnode_removefsref(ovp);
}
+ /* we're discarding on a fixup. mark for recycle */
+ if (!(avc->f.states & CDeadVnode))
+ vnode_recycle(ovp);
}
avc->v = nvp;
avc->f.states &=~ CDeadVnode;
long startTime; /* time we started the call,
* for callback expiration base
*/
+ int ftype[4] = {VNON, VREG, VDIR, VLNK}; /* verify type is as expected */
afs_size_t statSeqNo = 0; /* Valued of file size to detect races */
int code; /* error code */
long newIndex; /* new index in the dir */
do {
retry = 0;
ObtainWriteLock(&afs_xvcache, 130);
- tvcp = afs_FindVCache(&tfid, &retry, IS_WLOCK|FIND_BULKDEAD /* no stats | LRU */ );
+ tvcp = afs_FindVCache(&tfid, &retry, IS_WLOCK /* no stats | LRU */ );
if (tvcp && retry) {
ReleaseWriteLock(&afs_xvcache);
afs_PutVCache(tvcp);
tvcp = afs_NewBulkVCache(&tfid, hostp, statSeqNo);
if (tvcp)
{
- ObtainWriteLock(&tvcp->lock, 505);
- ReleaseWriteLock(&afs_xvcache);
- afs_RemoveVCB(&tfid);
- ReleaseWriteLock(&tvcp->lock);
+ ObtainWriteLock(&tvcp->lock, 505);
+#ifdef AFS_DARWIN80_ENV
+ /* use even/odd hack to guess file versus dir.
+ let links be reaped. oh well. */
+ if (dirEntryp->fid.vnode & 1)
+ tvcp->f.m.Type = VDIR;
+ else
+ tvcp->f.m.Type = VREG;
+ /* finalize to a best guess */
+ afs_darwin_finalizevnode(tvcp, VTOAFS(adp), NULL, 0, 1);
+ /* re-acquire usecount that finalizevnode disposed of */
+ vnode_ref(AFSTOV(tvcp));
+#endif
+ ReleaseWriteLock(&afs_xvcache);
+ afs_RemoveVCB(&tfid);
+ ReleaseWriteLock(&tvcp->lock);
} else {
- ReleaseWriteLock(&afs_xvcache);
+ ReleaseWriteLock(&afs_xvcache);
}
} else {
ReleaseWriteLock(&afs_xvcache);
do {
retry = 0;
ObtainReadLock(&afs_xvcache);
- tvcp = afs_FindVCache(&afid, &retry, FIND_CDEAD /* !stats&!lru */);
+ tvcp = afs_FindVCache(&afid, &retry, 0/* !stats&!lru */);
ReleaseReadLock(&afs_xvcache);
} while (tvcp && retry);
* matches the value we placed there when we set the CBulkFetching
* flag, then someone else has done something with this node,
* and we may not have the latest status information for this
- * file. Leave the entry alone.
+ * file. Leave the entry alone. There's also a file type
+ * change here, for OSX bulkstat support.
*/
- if (!(tvcp->f.states & CBulkFetching) || (tvcp->f.m.Length != statSeqNo)) {
+ if (!(tvcp->f.states & CBulkFetching)
+ || (tvcp->f.m.Length != statSeqNo)
+ || (ftype[(&statsp[i])->FileType] != vType(tvcp))) {
flagIndex++;
ReleaseWriteLock(&tvcp->lock);
afs_PutVCache(tvcp);
afs_DequeueCallback(tvcp);
if ((tvcp->f.states & CForeign) || (vType(tvcp) == VDIR))
osi_dnlc_purgedp(tvcp); /* if it (could be) a directory */
- } else {
+ } else
/* re-acquire the usecount that finalizevnode disposed of */
vnode_ref(AFSTOV(tvcp));
- }
} else
#endif
ReleaseWriteLock(&afs_xcbhash);
do {
retry = 0;
ObtainReadLock(&afs_xvcache);
- tvcp = afs_FindVCache(&afid, &retry, FIND_CDEAD /* !stats&!lru */);
+ tvcp = afs_FindVCache(&afid, &retry, 0 /* !stats&!lru */);
ReleaseReadLock(&afs_xvcache);
} while (tvcp && retry);
if (tvcp != NULL) {
#define DO_VLRU 2
#define IS_SLOCK 4
#define IS_WLOCK 8
-#define FIND_CDEAD 16
-#define FIND_BULKDEAD 32
/* values for adown value of afs_LoopServers */
#define AFS_LS_UP 0
#else
#ifdef AFS_DARWIN80_ENV
if (tvc->f.states & CDeadVnode) {
- if (!(tvc->f.states & CBulkFetching)) {
- ReleaseReadLock(&afs_xvcache);
- afs_osi_Sleep(&tvc->f.states);
- goto loop1;
- }
+ ReleaseReadLock(&afs_xvcache);
+ afs_osi_Sleep(&tvc->f.states);
+ goto loop1;
}
vp = AFSTOV(tvc);
if (vnode_get(vp))
AFS_GLOCK();
continue;
}
- if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
- AFS_GUNLOCK();
- vnode_recycle(AFSTOV(tvc));
- AFS_GLOCK();
- }
#else
AFS_FAST_HOLD(tvc);
#endif
#else
#ifdef AFS_DARWIN80_ENV
if (tvc->f.states & CDeadVnode) {
- if (!(tvc->f.states & CBulkFetching)) {
- ReleaseReadLock(&afs_xvcache);
- afs_osi_Sleep(&tvc->f.states);
- goto loop2;
- }
+ ReleaseReadLock(&afs_xvcache);
+ afs_osi_Sleep(&tvc->f.states);
+ goto loop2;
}
vp = AFSTOV(tvc);
if (vnode_get(vp))
AFS_GLOCK();
continue;
}
- if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
- AFS_GUNLOCK();
- vnode_recycle(AFSTOV(tvc));
- AFS_GLOCK();
- }
#else
AFS_FAST_HOLD(tvc);
#endif
}
#ifdef AFS_DARWIN80_ENV
if (tvc->f.states & CDeadVnode) {
- if (!(tvc->f.states & CBulkFetching)) {
- ReleaseReadLock(&afs_xvcache);
- afs_osi_Sleep(&tvc->f.states);
- goto loop;
- }
+ ReleaseReadLock(&afs_xvcache);
+ afs_osi_Sleep(&tvc->f.states);
+ goto loop;
}
vp = AFSTOV(tvc);
if (vnode_get(vp))
AFS_GLOCK();
continue;
}
- if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
- AFS_GUNLOCK();
- vnode_recycle(AFSTOV(tvc));
- AFS_GLOCK();
- }
#else
AFS_FAST_HOLD(tvc);
#endif
struct AFSFetchStatus *astat, struct vrequest *areq)
{
afs_size_t length;
+#ifdef AFS_DARWIN80_ENV
+ int fixup = 0;
+#endif
AFS_STATCNT(afs_ProcessFS);
#ifdef AFS_64BIT_CLIENT
avc->f.m.Group = astat->Group;
avc->f.m.LinkCount = astat->LinkCount;
if (astat->FileType == File) {
+#ifdef AFS_DARWIN80_ENV
+ if (avc->f.m.Type != VREG)
+ fixup = 1;
+#endif
vSetType(avc, VREG);
avc->f.m.Mode |= S_IFREG;
} else if (astat->FileType == Directory) {
+#ifdef AFS_DARWIN80_ENV
+ if (avc->f.m.Type != VDIR)
+ fixup = 1;
+#endif
vSetType(avc, VDIR);
avc->f.m.Mode |= S_IFDIR;
} else if (astat->FileType == SymbolicLink) {
if (afs_fakestat_enable && (avc->f.m.Mode & 0111) == 0) {
+#ifdef AFS_DARWIN80_ENV
+ if (avc->f.m.Type != VDIR)
+ fixup = 1;
+#endif
vSetType(avc, VDIR);
avc->f.m.Mode |= S_IFDIR;
} else {
+#ifdef AFS_DARWIN80_ENV
+ if (avc->f.m.Type != VLNK)
+ fixup = 1;
+#endif
vSetType(avc, VLNK);
avc->f.m.Mode |= S_IFLNK;
}
avc->mvstat = 1;
}
}
+#ifdef AFS_DARWIN80_ENV
+ if (fixup) {
+ /* perform type correction on underlying vnode */
+ afs_darwin_finalizevnode(avc, NULL, NULL, 0, 1);
+ /* re-acquire the usecount that finalizevnode disposed of */
+ vnode_ref(AFSTOV(avc));
+ }
+#endif
avc->f.anyAccess = astat->AnonymousAccess;
#ifdef badidea
if ((astat->CallerAccess & ~astat->AnonymousAccess))
}
#ifdef AFS_DARWIN80_ENV
if (tvc->f.states & CDeadVnode) {
- if (!(tvc->f.states & CBulkFetching)) {
- ReleaseSharedLock(&afs_xvcache);
- afs_osi_Sleep(&tvc->f.states);
- goto rootvc_loop;
- }
+ ReleaseSharedLock(&afs_xvcache);
+ afs_osi_Sleep(&tvc->f.states);
+ goto rootvc_loop;
}
tvp = AFSTOV(tvc);
if (vnode_get(tvp)) /* this bumps ref count */
AFS_GLOCK();
continue;
}
- if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
- AFS_GUNLOCK();
- vnode_recycle(AFSTOV(tvc));
- AFS_GLOCK();
- }
#endif
break;
}
static void
findvc_sleep(struct vcache *avc, int flag)
{
- int fstates = avc->f.states;
if (flag & IS_SLOCK) {
ReleaseSharedLock(&afs_xvcache);
} else {
ReleaseReadLock(&afs_xvcache);
}
}
- if (flag & FIND_CDEAD) {
- ObtainWriteLock(&afs_xvcache, 342);
- afs_FlushReclaimedVcaches();
- if (fstates == avc->f.states) {
- ReleaseWriteLock(&afs_xvcache);
- afs_osi_Sleep(&avc->f.states);
- } else
- ReleaseWriteLock(&afs_xvcache);
- } else
- afs_osi_Sleep(&avc->f.states);
+ afs_osi_Sleep(&avc->f.states);
if (flag & IS_SLOCK) {
ObtainSharedLock(&afs_xvcache, 341);
} else {
i = VCHash(afid);
for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
if (FidMatches(afid, tvc)) {
-#ifdef AFS_DARWIN80_ENV
- if (flag & FIND_CDEAD) {
- if (tvc->f.states & (CDeadVnode|CBulkFetching)) {
- deadvc = tvc;
- continue;
- }
- } else {
- if (tvc->f.states & CDeadVnode)
- if ((tvc->f.states & CBulkFetching) &&
- !(flag & FIND_BULKDEAD))
- continue;
- }
-#endif
if (tvc->f.states & CVInit) {
findvc_sleep(tvc, flag);
goto findloop;
findvc_sleep(tvc, flag);
goto findloop;
}
- if (flag & FIND_CDEAD) {
- livevc = tvc;
- continue;
- }
#endif
break;
}
}
-#ifdef AFS_DARWIN80_ENV
- if (flag & FIND_CDEAD) {
- if (livevc && deadvc) {
- /* discard deadvc */
- AFS_GUNLOCK();
- vnode_recycle(AFSTOV(deadvc));
- vnode_put(AFSTOV(deadvc));
- vnode_rele(AFSTOV(deadvc));
- AFS_GLOCK();
- deadvc = NULL;
- }
-
- /* return what's left */
- tvc = livevc ? livevc : deadvc;
- }
-#endif
/* should I have a read lock on the vnode here? */
if (tvc) {
AFS_GLOCK();
tvp = NULL;
}
- if (tvp && (tvc->f.states & (CBulkFetching|CDeadVnode))) {
- AFS_GUNLOCK();
- vnode_recycle(AFSTOV(tvc));
- AFS_GLOCK();
- }
if (!tvp) {
tvc = NULL;
return tvc;
}
#ifdef AFS_DARWIN80_ENV
if (tvc->f.states & CDeadVnode) {
- if (!(tvc->f.states & CBulkFetching)) {
- ReleaseSharedLock(&afs_xvcache);
- afs_osi_Sleep(&tvc->f.states);
- goto loop;
- }
+ ReleaseSharedLock(&afs_xvcache);
+ afs_osi_Sleep(&tvc->f.states);
+ goto loop;
}
tvp = AFSTOV(tvc);
if (vnode_get(tvp)) {
AFS_GLOCK();
continue;
}
- if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
- AFS_GUNLOCK();
- vnode_recycle(AFSTOV(tvc));
- AFS_GLOCK();
- }
#endif /* AFS_DARWIN80_ENV */
count++;
if (found_tvc) {