use system vnodes. one remaining bug, dangling vnodes at shutdown.
#define AFS_PROC struct proc
-#define osi_vnhold(avc,r) do { \
- if ((avc)->vrefCount) { VN_HOLD(&((avc)->v)); } \
- else (avc)->vrefCount = 1; } while(0)
+#define osi_vnhold(avc,r) VN_HOLD(AFSTOV(avc))
+#define VN_HOLD(vp) darwin_vn_hold(vp)
+#define VN_RELE(vp) vrele(vp);
+
#define gop_rdwr(rw,gp,base,len,offset,segflg,unit,cred,aresid) \
vn_rdwr((rw),(gp),(base),(len),(offset),(segflg),(unit),(cred),(aresid),current_proc())
return KERN_FAILURE;
}
sysent[SYS_setgroups].sy_call = Afs_xsetgroups;
+#if 0
sysent[SYS_ioctl].sy_call = afs_xioctl;
+#endif
sysent[AFS_SYSCALL].sy_call = afs3_syscall;
sysent[AFS_SYSCALL].sy_narg = 5;
sysent[AFS_SYSCALL].sy_parallel = 0;
if (vfsconf_del("afs"))
return KERN_FAILURE;
/* give up syscall entries for ioctl & setgroups, which we've stolen */
+#if 0
sysent[SYS_ioctl].sy_call = ioctl;
+#endif
sysent[SYS_setgroups].sy_call = setgroups;
/* give up the stolen syscall entry */
sysent[AFS_SYSCALL].sy_narg = 0;
mp->mnt_data = (qaddr_t) - 1;
} else {
if (flags & MNT_FORCE) {
+ if (afs_globalVp) {
+ AFS_GUNLOCK();
+ vrele(AFSTOV(afs_globalVp));
+ AFS_GLOCK();
+ }
+ afs_globalVp = NULL;
+ AFS_GUNLOCK();
+ vflush(mp, NULLVP, FORCECLOSE/*0*/);
+ AFS_GLOCK();
afs_globalVFS = 0;
afs_shutdown();
} else {
int lfl;
{
int error;
- printf("vget called. help!\n");
+ //printf("vget called. help!\n");
if (vp->v_usecount < 0) {
vprint("bad usecount", vp);
panic("afs_vget");
osi_VM_FlushVCache(struct vcache *avc, int *slept)
{
struct vnode *vp = AFSTOV(avc);
-#ifdef AFS_DARWIN14_ENV
- if (UBCINFOEXISTS(vp))
- return EBUSY;
-#endif
- if (avc->vrefCount > DARWIN_REFBASE)
- return EBUSY;
-
- if (avc->opens)
- return EBUSY;
-
- /* if a lock is held, give up */
- if (CheckLock(&avc->lock))
- return EBUSY;
+ kern_return_t kret;
+ off_t size;
AFS_GUNLOCK();
- cache_purge(vp);
-#ifndef AFS_DARWIN14_ENV
- if (UBCINFOEXISTS(vp)) {
- ubc_clean(vp, 1);
- ubc_uncache(vp);
- ubc_release(vp);
- ubc_info_free(vp);
- }
-#else
- /* This is literally clean_up_name_parent_ptrs() */
- /* Critical to clean up any state attached to the vnode here since it's
- being recycled, and we're not letting refcnt drop to 0 to trigger
- normal recycling. */
- if (VNAME(vp) || VPARENT(vp)) {
- char *tmp1;
- struct vnode *tmp2;
-
- /* do it this way so we don't block before clearing
- these fields. */
- tmp1 = VNAME(vp);
- tmp2 = VPARENT(vp);
- VNAME(vp) = NULL;
- VPARENT(vp) = NULL;
-
- if (tmp1) {
- remove_name(tmp1);
- }
-
- if (tmp2) {
- vrele(tmp2);
- }
+#if 0
+ if (!(UBCINFOMISSING(vp) || UBCINFORECLAIMED(vp))) {
+ size=ubc_getsize(vp);
+ kret=ubc_invalidate(vp,0,size);
}
#endif
-
+ cache_purge(vp);
AFS_GLOCK();
return 0;
printf("VMFlushPages: invalidate failed (error = %d)\n", kret);
/* XXX what about when not CStatd */
if (avc->states & CStatd && size != avc->m.Length)
+ if (UBCISVALID(vp))
ubc_setsize(vp, avc->m.Length);
}
}
osi_VM_Truncate(struct vcache *avc, int alen, struct AFS_UCRED *acred)
{
struct vnode *vp = AFSTOV(avc);
- if (UBCINFOEXISTS(vp)) {
+ if (UBCINFOEXISTS(vp) && UBCISVALID(vp)) {
ubc_setsize(vp, alen);
}
}
-/* vnreclaim and vinactive are probably not aggressive enough to keep
- enough afs vcaches free, so we try to do some of it ourselves */
-/* XXX there's probably not nearly enough locking here */
-void
-osi_VM_TryReclaim(struct vcache *avc, int *slept)
-{
- struct proc *p = current_proc();
- struct vnode *vp = AFSTOV(avc);
- void *obj;
-#ifdef AFS_DARWIN14_ENV
- int didhold;
-#endif
-
- if (slept)
- *slept = 0;
- VN_HOLD(vp); /* remove from inactive list */
- if (!simple_lock_try(&vp->v_interlock)) {
- AFS_RELE(vp);
- return;
- }
- if (!UBCINFOEXISTS(vp) || vp->v_usecount != 2+DARWIN_REFBASE) {
- simple_unlock(&vp->v_interlock);
- AFS_RELE(vp);
- return;
- }
- if (ISSET(vp->v_flag, VUINACTIVE)) {
- simple_unlock(&vp->v_interlock);
- AFS_RELE(vp);
- printf("vnode %x still inactive!", vp);
- return;
- }
-#ifdef AFS_DARWIN14_ENV
- if (vp->v_ubcinfo->ui_refcount > 1 || vp->v_ubcinfo->ui_mapped) {
- simple_unlock(&vp->v_interlock);
- AFS_RELE(vp);
- return;
- }
- if (ISSET(vp->v_flag, VORECLAIM)) {
- simple_unlock(&vp->v_interlock);
- AFS_RELE(vp);
- return;
- }
-#else
- if (vp->v_ubcinfo->ui_holdcnt) {
- simple_unlock(&vp->v_interlock);
- AFS_RELE(vp);
- return;
- }
-#endif
- if (slept && ubc_issetflags(vp, UI_WASMAPPED)) {
- /* We can't possibly release this in time for this NewVCache to get it */
- simple_unlock(&vp->v_interlock);
- AFS_RELE(vp);
- return;
- }
-
-#ifndef AFS_DARWIN14_ENV
- vp->v_usecount--; /* we want the usecount to be 1 */
-#endif
-
- if (slept) {
- ReleaseWriteLock(&afs_xvcache);
- *slept = 1;
- } else
- ReleaseReadLock(&afs_xvcache);
- AFS_GUNLOCK();
- obj = 0;
- if (ubc_issetflags(vp, UI_WASMAPPED)) {
- simple_unlock(&vp->v_interlock);
-#ifdef AFS_DARWIN14_ENV
- ubc_release_named(vp);
-#else
- ubc_release(vp);
-#endif
- if (ubc_issetflags(vp, UI_HASOBJREF))
- printf("ubc_release didn't release the reference?!\n");
- } else {
-#ifdef AFS_DARWIN14_ENV
- SET(vp->v_flag, VORECLAIM);
-#endif
- if (!vn_lock(vp, LK_EXCLUSIVE|LK_INTERLOCK,current_proc())) {
-#ifdef AFS_DARWIN14_ENV
- obj = ubc_getobject(vp,UBC_HOLDOBJECT);
- if ((didhold = ubc_hold(vp)))
- (void)ubc_clean(vp, 0);
-#else
-#ifdef AFS_DARWIN13_ENV
- obj = ubc_getobject(vp,(UBC_NOREACTIVATE|UBC_HOLDOBJECT));
-#else
- obj = ubc_getobject(vp);
-#endif
- (void)ubc_clean(vp, 1);
-#endif
- vinvalbuf(vp, V_SAVE, &afs_osi_cred, p, 0, 0);
- if (vp->v_usecount ==
-#ifdef AFS_DARWIN14_ENV
- 2 + DARWIN_REFBASE
-#else
- 1
-#endif
- )
- VOP_UNLOCK(vp, 0, p); /* was VOP_INACTIVE(vp, p); */
- else
- VOP_UNLOCK(vp, 0, p);
-#ifdef AFS_DARWIN14_ENV
- if (didhold)
- ubc_rele(vp);
-#endif
- if (obj) {
- if (ISSET(vp->v_flag, VTERMINATE))
- panic("afs_vnreclaim: already terminating");
- SET(vp->v_flag, VTERMINATE);
- memory_object_destroy(obj, 0);
- while (ISSET(vp->v_flag, VTERMINATE)) {
- SET(vp->v_flag, VTERMWANT);
- tsleep((caddr_t)&vp->v_ubcinfo, PINOD, "afs_vnreclaim", 0);
- }
- }
-#ifdef AFS_DARWIN14_ENV
- simple_lock(&vp->v_interlock);
- CLR(vp->v_flag, VORECLAIM);
- if (ISSET((vp)->v_flag, VXWANT)) {
- CLR((vp)->v_flag, VXWANT);
- wakeup((caddr_t)(vp));
- }
- vp->v_usecount--;
- simple_unlock(&vp->v_interlock);
-#endif
- } else {
-#ifdef AFS_DARWIN14_ENV
- CLR(vp->v_flag, VORECLAIM);
-#endif
- if (simple_lock_try(&vp->v_interlock))
- panic("afs_vnreclaim: slept, but did no work :(");
- if (UBCINFOEXISTS(vp) && vp->v_count == DARWIN_REFBASE +
-#ifdef AFS_DARWIN14_ENV
- 2
-#else
- 1
-#endif
- ) {
-#ifndef AFS_DARWIN14_ENV
- /* We left the refcount high in 1.4 */
- vp->v_usecount++;
-#endif
- simple_unlock(&vp->v_interlock);
- VN_RELE(vp);
- } else {
-#ifdef AFS_DARWIN14_ENV
- /* We left the refcount high in 1.4 */
- vp->v_usecount--;
-#endif
- simple_unlock(&vp->v_interlock);
- }
- }
- }
- AFS_GLOCK();
- if (slept)
- ObtainWriteLock(&afs_xvcache,175);
- else
- ObtainReadLock(&afs_xvcache);
-}
-
void
osi_VM_NukePages(struct vnode *vp, off_t offset, off_t size)
{
+#if 0
void *object;
struct vcache *avc = VTOAFS(vp);
-#ifdef AFS_DARWIN14_ENV
offset = trunc_page(offset);
size = round_page(size + 1);
while (size) {
size -= PAGE_SIZE;
offset += PAGE_SIZE;
}
-#else
- object = NULL;
-#ifdef AFS_DARWIN13_ENV
- if (UBCINFOEXISTS(vp))
- object = ubc_getobject(vp, UBC_NOREACTIVATE);
-#else
- if (UBCINFOEXISTS(vp))
- object = ubc_getobject(vp);
-#endif
- if (!object)
- return;
-
- offset = trunc_page(offset);
- size = round_page(size + 1);
-
-#ifdef AFS_DARWIN13_ENV
- while (size) {
- memory_object_page_op(object, (vm_offset_t) offset,
- UPL_POP_SET | UPL_POP_BUSY | UPL_POP_DUMP, 0,
- 0);
- size -= PAGE_SIZE;
- offset += PAGE_SIZE;
- }
-#else
- /* This is all we can do, and it's not enough. sucks to be us */
- ubc_setsize(vp, offset);
- size = (offset + size > avc->m.Length) ? offset + size : avc->m.Length;
- ubc_setsize(vp, size);
-#endif
#endif
}
struct vnode *vp = AFSTOV(avc);
if (UBCISVALID(vp) && ((avc->states & CStatd) || force)) {
- if (!UBCINFOEXISTS(vp) && !ISSET(vp->v_flag, VTERMINATE)) {
+ if (!UBCINFOEXISTS(vp)) {
osi_vnhold(avc, 0);
avc->states |= CUBCinit;
AFS_GUNLOCK();
- if ((error = ubc_info_init(&avc->v))) {
+ if ((error = ubc_info_init(vp))) {
AFS_GLOCK();
avc->states &= ~CUBCinit;
- AFS_RELE(AFSTOV(avc));
+ AFS_RELE(vp);
return error;
}
-#ifndef AFS_DARWIN14_ENV
- simple_lock(&avc->v.v_interlock);
- if (!ubc_issetflags(&avc->v, UI_HASOBJREF))
-#ifdef AFS_DARWIN13_ENV
- if (ubc_getobject
- (&avc->v, (UBC_NOREACTIVATE | UBC_HOLDOBJECT)))
- panic("VM_Setup: null object");
-#else
- (void)_ubc_getobject(&avc->v, 1); /* return value not used */
-#endif
- simple_unlock(&avc->v.v_interlock);
-#endif
AFS_GLOCK();
avc->states &= ~CUBCinit;
- AFS_RELE(AFSTOV(avc));
+ AFS_RELE(vp);
+ }
+ if (UBCINFOEXISTS(vp) && UBCISVALID(vp)) {
+ ubc_setsize(vp, avc->m.Length);
}
- if (UBCINFOEXISTS(&avc->v))
- ubc_setsize(&avc->v, avc->m.Length);
}
return 0;
}
#define DROPNAME() FREE(name, M_TEMP)
+void
+darwin_vn_hold(struct vnode *vp)
+{
+ int haveGlock=ISAFS_GLOCK();
+ struct vcache *tvc = VTOAFS(vp);
+
+ tvc->states |= CUBCinit;
+ if (haveGlock) AFS_GUNLOCK();
+
+ /* vget needed for 0 ref'd vnode in GetVCache to not panic in vref.
+ vref needed for multiref'd vnode in vnop_remove not to deadlock
+ ourselves during vop_inactive, except we also need to not reinst
+ the ubc... so we just call VREF there now anyway. */
+
+ if (VREFCOUNT(tvc) > 0)
+ VREF(((struct vnode *)(vp)));
+ else
+ afs_vget(afs_globalVFS, 0, (vp));
+ if (UBCINFOMISSING(vp) || UBCINFORECLAIMED(vp)) {
+ ubc_info_init(vp);
+ }
+
+ if (haveGlock) AFS_GLOCK();
+ tvc->states &= ~CUBCinit;
+}
int
afs_vop_lookup(ap)
if (UBCINFOMISSING(vp) ||
UBCINFORECLAIMED(vp)) {
-#ifdef AFS_DARWIN14_ENV
- if (UBCINFORECLAIMED(vp) && ISSET(vp->v_flag, (VXLOCK|VORECLAIM))) {
- DROPNAME();
- return (ENXIO);
- } else
-#endif
ubc_info_init(vp);
}
+
/* The parent directory comes in locked. We unlock it on return
* unless the caller wants it left locked.
* we also always return the vnode locked. */
(*ap->a_vpp)->v_vfsp = dvp->v_vfsp;
vn_lock(*ap->a_vpp, LK_EXCLUSIVE | LK_RETRY, p);
if (UBCINFOMISSING(*ap->a_vpp) || UBCINFORECLAIMED(*ap->a_vpp)) {
-#ifdef AFS_DARWIN14_ENV
- if (UBCINFORECLAIMED(*ap->a_vpp) && ISSET((*ap->a_vpp)->v_flag,
- (VXLOCK|VORECLAIM))) {
- vput(dvp);
- DROPNAME();
- return (ENXIO);
- } else
-#endif
- ubc_info_init(*ap->a_vpp);
+ vcp->states |= CUBCinit;
+ ubc_info_init(*ap->a_vpp);
+ vcp->states &= ~CUBCinit;
}
} else
*ap->a_vpp = 0;
if (AFSTOV(vc) != vp)
panic("AFS open changed vnode!");
#endif
+#if 0
osi_FlushPages(vc, ap->a_cred);
+#endif
AFS_GUNLOCK();
#ifdef AFS_DARWIN14_ENV
if (error && didhold)
code = afs_close(avc, ap->a_fflag, ap->a_cred, ap->a_p);
else
code = afs_close(avc, ap->a_fflag, &afs_osi_cred, ap->a_p);
+#if 0
osi_FlushPages(avc, ap->a_cred); /* hold bozon lock, but not basic vnode lock */
- AFS_GUNLOCK();
-#ifdef AFS_DARWIN14_ENV
- if (UBCINFOEXISTS(ap->a_vp) && ap->a_vp->v_ubcinfo->ui_refcount < 2) {
- ubc_hold(ap->a_vp);
- if (ap->a_vp->v_ubcinfo->ui_refcount < 2) {
- printf("afs: Imminent ui_refcount panic\n");
- } else {
- printf("afs: WARNING: ui_refcount panic averted\n");
- }
- }
- if (UBCINFOMISSING(ap->a_vp) ||
- UBCINFORECLAIMED(ap->a_vp)) {
- if (UBCINFORECLAIMED(ap->a_vp) && ISSET(ap->a_vp->v_flag,
- (VXLOCK|VORECLAIM))) {
- printf("no ubc for %x in close, reclaim set\n", ap->a_vp);
- return (ENXIO);
- } else {
- printf("no ubc for %x in close, put back\n", ap->a_vp);
- ubc_info_init(ap->a_vp);
- }
- }
#endif
+ AFS_GUNLOCK();
return code;
}
* } */ *ap;
{
int code;
+
AFS_GLOCK();
code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
AFS_GUNLOCK();
* } */ *ap;
{
int code;
- struct vcache *avc = VTOAFS(ap->a_vp);
+ struct vnode *vp = ap->a_vp;
+ struct vcache *avc = VTOAFS(vp);
AFS_GLOCK();
+#if 0
osi_FlushPages(avc, ap->a_cred); /* hold bozon lock, but not basic vnode lock */
+#endif
code = afs_read(avc, ap->a_uio, ap->a_cred, 0, 0, 0);
AFS_GUNLOCK();
return code;
auio.uio_resid = aiov.iov_len = size;
aiov.iov_base = (caddr_t) ioaddr;
AFS_GLOCK();
+#if 0
osi_FlushPages(tvc, ap->a_cred); /* hold bozon lock, but not basic vnode lock */
+#endif
code = afs_read(tvc, uio, cred, 0, 0, 0);
if (code == 0) {
ObtainWriteLock(&tvc->lock, 2);
struct vcache *avc = VTOAFS(ap->a_vp);
void *object;
AFS_GLOCK();
+#if 0
osi_FlushPages(avc, ap->a_cred); /* hold bozon lock, but not basic vnode lock */
- if (UBCINFOEXISTS(ap->a_vp))
+#endif
+ if (UBCINFOEXISTS(ap->a_vp)) {
ubc_clean(ap->a_vp, 1);
+ }
if (UBCINFOEXISTS(ap->a_vp))
osi_VM_NukePages(ap->a_vp, ap->a_uio->uio_offset,
ap->a_uio->uio_resid);
#endif /* ] USV */
AFS_GLOCK();
+#if 0
osi_FlushPages(tvc, ap->a_cred); /* hold bozon lock, but not basic vnode lock */
+#endif
ObtainWriteLock(&tvc->lock, 1);
afs_FakeOpen(tvc);
ReleaseWriteLock(&tvc->lock);
int wait = ap->a_waitfor == MNT_WAIT;
int error;
register struct vnode *vp = ap->a_vp;
+ int haveGlock = ISAFS_GLOCK();
- AFS_GLOCK();
- /*vflushbuf(vp, wait); */
+ /* afs_vop_lookup glocks, can call us through vinvalbuf from GetVCache */
+ if (!haveGlock) AFS_GLOCK();
if (ap->a_cred)
error = afs_fsync(VTOAFS(vp), ap->a_cred);
else
error = afs_fsync(VTOAFS(vp), &afs_osi_cred);
- AFS_GUNLOCK();
+ if (!haveGlock) AFS_GUNLOCK();
return error;
}
error = afs_remove(VTOAFS(dvp), name, cnp->cn_cred);
AFS_GUNLOCK();
cache_purge(vp);
- if (!error && UBCINFOEXISTS(vp)) {
-#ifdef AFS_DARWIN14_ENV
+ vput(dvp);
+ if (!error) {
+ /* necessary so we don't deadlock ourselves in vclean */
+ VOP_UNLOCK(vp, 0, cnp->cn_proc);
+
/* If crashes continue in ubc_hold, comment this out */
- /* (void)ubc_uncache(vp);*/
-#else
- int wasmapped = ubc_issetflags(vp, UI_WASMAPPED);
- int hasobjref = ubc_issetflags(vp, UI_HASOBJREF);
- if (wasmapped)
- (void)ubc_uncache(vp);
- if (hasobjref)
- ubc_release(vp);
- /* WARNING vp may not be valid after this */
-#endif
+ (void)ubc_uncache(vp);
}
+
if (dvp == vp)
vrele(vp);
else
vput(vp);
- vput(dvp);
FREE_ZONE(cnp->cn_pnbuf, cnp->cn_pnlen, M_NAMEI);
DROPNAME();
register struct vnode *fdvp = ap->a_fdvp;
struct proc *p = fcnp->cn_proc;
- /* Check for cross-device rename.
- * For AFS, this means anything not in AFS-space
- */
- if ((0 != strcmp(tdvp->v_mount->mnt_stat.f_fstypename, "afs")) ||
- (tvp && (0 != strcmp(tvp->v_mount->mnt_stat.f_fstypename, "afs")))) {
- error = EXDEV;
- goto abortit;
- }
+ /* Check for cross-device rename.
+ * For AFS, this means anything not in AFS-space
+ */
+ if ((0 != strcmp(tdvp->v_mount->mnt_stat.f_fstypename, "afs")) ||
+ (tvp && (0 != strcmp(tvp->v_mount->mnt_stat.f_fstypename, "afs")))) {
+ error = EXDEV;
+ goto abortit;
+ }
/*
* if fvp == tvp, we're just removing one name of a pair of
* struct vnode *a_vp;
* } */ *ap;
{
- int error;
+ int error = 0;
int sl;
register struct vnode *vp = ap->a_vp;
+ int haveGlock = ISAFS_GLOCK();
+ struct vcache *tvc = VTOAFS(vp);
cache_purge(vp); /* just in case... */
+ if (!haveGlock)
+ AFS_GLOCK();
+ error = afs_FlushVCache(VTOAFS(vp), &sl); /* toss our stuff from vnode */
+ if (!haveGlock)
+ AFS_GUNLOCK();
-#if 0
- AFS_GLOCK();
- error = afs_FlushVCache(VTOAFS(vp), &sl); /* tosses our stuff from vnode */
- AFS_GUNLOCK();
- ubc_unlink(vp);
if (!error && vp->v_data)
panic("afs_reclaim: vnode not cleaned");
- return error;
-#else
- if (vp->v_usecount == 2) {
- vprint("reclaim count==2", vp);
- } else if (vp->v_usecount == 1) {
- vprint("reclaim count==1", vp);
- } else
- vprint("reclaim bad count", vp);
+ if (!error && (tvc->v != NULL))
+ panic("afs_reclaim: vcache not cleaned");
- return 0;
-#endif
+ return error;
}
int
if (vp->v_tag == VT_NON)
return (ENOENT);
+
return (lockmgr(&avc->rwlock, ap->a_flags, &vp->v_interlock, ap->a_p));
}
{
struct vnode *vp = ap->a_vp;
struct vcache *avc = VTOAFS(vp);
+
return (lockmgr
(&avc->rwlock, ap->a_flags | LK_RELEASE, &vp->v_interlock,
ap->a_p));
* int *a_runb;
* } */ *ap;
{
- struct vcache *vcp;
int error;
if (ap->a_bnp) {
*ap->a_bnp = ap->a_bn * (PAGE_SIZE / DEV_BSIZE);
*ap->a_run = MAX(ap->a_size, AFS_CHUNKSIZE(ap->a_foffset));
return 0;
}
+
+void
+afs_darwin_getnewvnode(struct vcache *tvc)
+{
+ while (getnewvnode(VT_AFS, afs_globalVFS, afs_vnodeop_p, &tvc->v)) {
+ /* no vnodes available, force an alloc (limits be damned)! */
+ printf("failed to get vnode\n");
+ }
+ tvc->v->v_data = (void *)tvc;
+}
#elif defined(AFS_OSF_ENV)
attrs->va_fsid = avc->v.v_mount->m_stat.f_fsid.val[0];
#elif defined(AFS_DARWIN70_ENV)
- attrs->va_fsid = avc->v.v_mount->mnt_stat.f_fsid.val[0];
-#else
+ attrs->va_fsid = avc->v->v_mount->mnt_stat.f_fsid.val[0];
+#else /* ! AFS_DARWIN70_ENV */
attrs->va_fsid = 1;
#endif
if (avc->mvstat == 2) {
if (tvc && (VREFCOUNT(tvc) > 2) && tvc->opens > 0
&& !(tvc->states & CUnlinked))
#else
-#ifdef AFS_DARWIN14_ENV
- if (tvc && (VREFCOUNT(tvc) > 1 + DARWIN_REFBASE) && tvc->opens > 0
- && !(tvc->states & CUnlinked))
-#else
if (tvc && (VREFCOUNT(tvc) > 1) && tvc->opens > 0
&& !(tvc->states & CUnlinked))
#endif
-#endif
{
char *unlname = afs_newname();
struct VenusFid dirFid;
register struct dcache *tdc;
afs_int32 code = 0;
-#ifdef AFS_DARWIN14_ENV
- int oldref;
-#endif
if (NBObtainWriteLock(&avc->lock, 423))
return 0;
cred = avc->uncred;
avc->uncred = NULL;
-#if defined(AFS_DARWIN_ENV) && !defined(AFS_DARWIN14_ENV)
- /* this is called by vrele (via VOP_INACTIVE) when the refcount
- * is 0. we can't just call VN_HOLD since vref will panic.
- * we can't just call osi_vnhold because a later AFS_RELE will call
- * vrele again, which will try to call VOP_INACTIVE again after
- * vn_locking the vnode. which would be fine except that our vrele
- * caller also locked the vnode... So instead, we just gimmick the
- * refcounts and hope nobody else can touch the file now */
- osi_Assert(VREFCOUNT(avc) == 0);
- VREFCOUNT_SET(avc, 1);
-#endif
+#ifdef AFS_DARWIN_ENV
+ VREF(AFSTOV(avc));
+#else
VN_HOLD(AFSTOV(avc));
+#endif
/* We'll only try this once. If it fails, just release the vnode.
* Clear after doing hold so that NewVCache doesn't find us yet.
*/
avc->states &= ~(CUnlinked | CUnlinkedDel);
-#ifdef AFS_DARWIN14_ENV
- if (VREFCOUNT(avc) < 4) {
- oldref = 4 - VREFCOUNT(avc);
- VREFCOUNT_SET(avc, 4);
- }
-#endif
ReleaseWriteLock(&avc->lock);
dirFid.Cell = avc->fid.Cell;
}
osi_FreeSmallSpace(unlname);
crfree(cred);
-#ifdef AFS_DARWIN_ENV
-#ifndef AFS_DARWIN14_ENV
- osi_Assert(VREFCOUNT(avc) == 1);
- VREFCOUNT_SET(avc, 0);
-#else
- if (oldref) {
- int newref = VREFCOUNT(avc) - oldref;
- VREFCOUNT_SET(avc, newref);
- }
-#endif
-#endif
}
} else {
ReleaseWriteLock(&avc->lock);
#define VPageCleaning 0x2 /* Solaris - Cache Trunc Daemon sez keep out */
#define CPSIZE 2
-#if defined(AFS_XBSD_ENV)
+#if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
#define vrefCount v->v_usecount
#else
#define vrefCount v.v_count
extern afs_uint32 afs_stampValue; /* stamp for pair's usage */
#define MakeStamp() (++afs_stampValue)
-#if defined(AFS_XBSD_ENV)
+#if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
#define VTOAFS(v) ((struct vcache *)(v)->v_data)
#define AFSTOV(vc) ((vc)->v)
#else
* !(avc->nextfree) && !avc->vlruq.next => (FreeVCList == avc->nextfree)
*/
struct vcache {
-#if defined(AFS_XBSD_ENV)
+#if defined(AFS_XBSD_ENV)||defined(AFS_DARWIN_ENV)
struct vnode *v;
#else
struct vnode v; /* Has reference count in v.v_count */
/*
* Vnode related macros
*/
+#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+#define vSetVfsp(vc, vfsp) AFSTOV(vc)->v_mount = (vfsp)
+#define vSetType(vc, type) AFSTOV(vc)->v_type = (type)
+#define vType(vc) AFSTOV(vc)->v_type
+#else
+#define vType(vc) (vc)->v.v_type
+#define vSetType(vc,type) (vc)->v.v_type = (type)
+#define vSetVfsp(vc,vfsp) (vc)->v.v_vfsp = (vfsp)
+#endif
+
#ifndef AFS_OBSD_ENV
#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
extern int (**afs_vnodeop_p) ();
#define IsAfsVnode(vc) ((vc)->v_op == afs_ops)
#define SetAfsVnode(vc) (vc)->v_op = afs_ops
#endif
-#define vType(vc) (vc)->v.v_type
-#define vSetType(vc,type) (vc)->v.v_type = (type)
-#define vSetVfsp(vc,vfsp) (vc)->v.v_vfsp = (vfsp)
#endif
#ifdef AFS_SGI65_ENV
register int ioctlDone = 0, code = 0;
AFS_STATCNT(afs_xioctl);
-#if defined(AFS_XBSD_ENV)
+#if defined(AFS_DARWIN_ENV)
+ if ((code = fdgetf(p, uap->fd, &fd)))
+ return code;
+#elif defined(AFS_XBSD_ENV)
fdp = p->p_fd;
if ((u_int) uap->fd >= fdp->fd_nfiles
|| (fd = fdp->fd_ofiles[uap->fd]) == NULL)
return EBADF;
if ((fd->f_flag & (FREAD | FWRITE)) == 0)
return EBADF;
-#elif defined(AFS_DARWIN_ENV)
- if ((code = fdgetf(p, uap->fd, &fd)))
- return code;
#elif defined(AFS_LINUX22_ENV)
ua.com = com;
ua.arg = arg;
afs_osi_Free(avc->linkData, strlen(avc->linkData) + 1);
avc->linkData = NULL;
}
-#if defined(AFS_XBSD_ENV)
+#if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
/* OK, there are no internal vrefCounts, so there shouldn't
* be any more refs here. */
if (avc->v) {
if (tvc->states & CVFlushed) {
refpanic("CVFlushed on VLRU");
+#if 0
} else if (i++ > 2 * afs_cacheStats) { /* even allowing for a few xallocs... */
refpanic("Increase -stat parameter of afsd(VLRU cycle?)");
+#endif
} else if (QNext(uq) != tq) {
refpanic("VLRU inconsistent");
}
-#ifdef AFS_DARWIN_ENV
- if ((VREFCOUNT(tvc) < DARWIN_REFBASE) ||
- (VREFCOUNT(tvc) < 1 + DARWIN_REFBASE &&
- UBCINFOEXISTS(&tvc->v))) {
- VREFCOUNT_SET(tvc,
- DARWIN_REFBASE +
- (UBCINFOEXISTS(&tvc->v) ? 1 : 0));
- }
- if (tvc->opens == 0 && ((tvc->states & CUnlinkedDel) == 0)
- && VREFCOUNT(tvc) == DARWIN_REFBASE + 1
- && UBCINFOEXISTS(&tvc->v)) {
- osi_VM_TryReclaim(tvc, &fv_slept);
- if (fv_slept) {
- uq = VLRU.prev;
- i = 0;
- continue; /* start over - may have raced. */
- }
- }
-#elif defined(AFS_LINUX22_ENV)
+#if defined(AFS_LINUX22_ENV)
if (tvc != afs_globalVp && VREFCOUNT(tvc) && tvc->opens == 0) {
struct dentry *dentry;
struct list_head *cur, *head = &(AFSTOI(tvc))->i_dentry;
}
#endif
- if (VREFCOUNT(tvc) ==
-#ifdef AFS_DARWIN_ENV
- DARWIN_REFBASE
-#else
- 0
+ if (((VREFCOUNT(tvc) == 0)
+#if defined(AFS_DARWIN_ENV) && !defined(UKERNEL)
+ || ((VREFCOUNT(tvc) == 1) &&
+ (UBCINFOEXISTS(AFSTOV(tvc))))
#endif
- && tvc->opens == 0 && (tvc->states & CUnlinkedDel) == 0) {
-#if defined(AFS_XBSD_ENV)
+ ) && tvc->opens == 0 && (tvc->states & CUnlinkedDel) == 0) {
+#if defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
/*
* vgone() reclaims the vnode, which calls afs_FlushVCache(),
* then it puts the vnode on the free list.
* not on the free list.
* XXX assume FreeBSD is the same for now.
*/
+ AFS_GUNLOCK();
vgone(AFSTOV(tvc));
+ AFS_GLOCK();
code = fv_slept = 0;
#else
code = afs_FlushVCache(tvc, &fv_slept);
if (!freeVCList) {
/* none free, making one is better than a panic */
afs_stats_cmperf.vcacheXAllocs++; /* count in case we have a leak */
+ if (afs_cacheStats == afs_stats_cmperf.vcacheXAllocs) printf("would vlru cycle panic\n");
tvc = (struct vcache *)afs_osi_Alloc(sizeof(struct vcache));
+#if defined(AFS_DARWIN_ENV) && !defined(UKERNEL)
+ tvc->v = NULL; /* important to clean this, or use memset 0 */
+#endif
#ifdef KERNEL_HAVE_PIN
pin((char *)tvc, sizeof(struct vcache)); /* XXX */
#endif
}
#endif /* AFS_OSF_ENV */
-#if defined(AFS_XBSD_ENV)
+#if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
if (tvc->v)
panic("afs_NewVCache(): free vcache with vnode attached");
#endif
AFS_GLOCK();
lockinit(&tvc->rwlock, PINOD, "vcache", 0, 0);
#endif
+#ifdef AFS_DARWIN_ENV
+ AFS_GUNLOCK();
+ afs_darwin_getnewvnode(tvc); /* includes one refcount */
+ AFS_GLOCK();
+ lockinit(&tvc->rwlock, PINOD, "vcache", 0, 0);
+#endif
#ifdef AFS_FBSD_ENV
{
struct vnode *vp;
/* Hold it for the LRU (should make count 2) */
VN_HOLD(AFSTOV(tvc));
#else /* AFS_OSF_ENV */
-#if !defined(AFS_XBSD_ENV)
+#if !(defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV))
VREFCOUNT_SET(tvc, 1); /* us */
#endif /* AFS_XBSD_ENV */
#endif /* AFS_OSF_ENV */
#else
SetAfsVnode(AFSTOV(tvc));
#endif /* AFS_SGI64_ENV */
-#ifdef AFS_DARWIN_ENV
- tvc->v.v_ubcinfo = UBC_INFO_NULL;
- lockinit(&tvc->rwlock, PINOD, "vcache rwlock", 0, 0);
- cache_purge(AFSTOV(tvc));
- tvc->v.v_data = tvc;
- tvc->v.v_tag = VT_AFS;
- /* VLISTNONE(&tvc->v); */
- tvc->v.v_freelist.tqe_next = 0;
- tvc->v.v_freelist.tqe_prev = (struct vnode **)0xdeadb;
- tvc->vrefCount += DARWIN_REFBASE;
-#endif
/*
* The proper value for mvstat (for root fids) is setup by the caller.
*/
crfree(cred);
}
}
-#ifdef AFS_DARWIN_ENV
- if (VREFCOUNT(tvc) == 1 + DARWIN_REFBASE
- && UBCINFOEXISTS(&tvc->v)) {
- if (tvc->opens)
- panic("flushactive open, hasubc, but refcnt 1");
- osi_VM_TryReclaim(tvc, 0);
- }
-#endif
}
}
ReleaseReadLock(&afs_xvcache);
#ifdef AFS_LINUX22_ENV
vcache2inode(avc); /* Set the inode attr cache */
#endif
-#ifdef AFS_DARWIN_ENV
- osi_VM_Setup(avc, 1);
-#endif
} /*afs_ProcessFS */
vcache2inode(tvc);
#endif
ReleaseWriteLock(&tvc->lock);
-#ifdef AFS_DARWIN_ENV
- osi_VM_Setup(tvc, 0);
-#endif
return tvc;
}
#if defined(AFS_OSF_ENV)
uvm_vnp_uncache(AFSTOV(tvc));
VOP_UNLOCK(AFSTOV(tvc), 0, curproc);
#endif
-#ifdef AFS_FBSD_ENV
+#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
/*
* XXX - I really don't like this. Should try to understand better.
* It seems that sometimes, when we get called, we already hold the
if (!iheldthelock)
VOP_UNLOCK(vp, LK_EXCLUSIVE, curthread);
#else
+#ifdef AFS_DARWIN_ENV
+ iheldthelock = VOP_ISLOCKED(vp);
+ if (!iheldthelock)
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, current_proc());
+ /* this is messy. we can call fsync which will try to reobtain this */
+ if (VTOAFS(vp) == tvc)
+ ReleaseWriteLock(&tvc->lock);
+ if (UBCINFOEXISTS(vp)) {
+ vinvalbuf(vp, V_SAVE, &afs_osi_cred, current_proc(), PINOD, 0);
+ }
+ if (VTOAFS(vp) == tvc)
+ ObtainWriteLock(&tvc->lock, 954);
+ if (!iheldthelock)
+ VOP_UNLOCK(vp, LK_EXCLUSIVE, current_proc());
+#else
iheldthelock = VOP_ISLOCKED(vp, curproc);
if (!iheldthelock)
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc);
if (!iheldthelock)
VOP_UNLOCK(vp, LK_EXCLUSIVE, curproc);
#endif
+#endif
}
#endif
if (vg)
continue;
#endif /* AFS_OSF_ENV */
-#ifdef AFS_DARWIN14_ENV
- /* It'd really suck if we allowed duplicate vcaches for the
- * same fid to happen. Wonder if this will work? */
- struct vnode *vp = AFSTOV(tvc);
- if (vp->v_flag & (VXLOCK | VORECLAIM | VTERMINATE)) {
- printf("precluded FindVCache on %x (%d:%d:%d)\n",
- vp, tvc->fid.Fid.Volume, tvc->fid.Fid.Vnode,
- tvc->fid.Fid.Unique);
- simple_lock(&vp->v_interlock);
- SET(vp->v_flag, VTERMWANT);
- simple_unlock(&vp->v_interlock);
- (void)tsleep((caddr_t) & vp->v_ubcinfo, PINOD, "vget1", 0);
- printf("VTERMWANT ended on %x\n", vp);
- continue;
- }
-#endif
break;
}
}
if (retry && *retry)
return 0;
#endif
+#ifdef AFS_DARWIN_ENV
+ tvc->states |= CUBCinit;
+ AFS_GUNLOCK();
+ if (UBCINFOMISSING(AFSTOV(tvc)) ||
+ UBCINFORECLAIMED(AFSTOV(tvc))) {
+ ubc_info_init(AFSTOV(tvc));
+ }
+ AFS_GLOCK();
+ tvc->states &= ~CUBCinit;
+#endif
/*
* only move to front of vlru if we have proper vcache locking)
*/
if (tvc && (tvc->states & CStatd))
vcache2inode(tvc); /* mainly to reset i_nlink */
#endif
-#ifdef AFS_DARWIN_ENV
- if (tvc)
- osi_VM_Setup(tvc, 0);
-#endif
return tvc;
} /*afs_FindVCache */
StartService
}
-RunService "$1"
+RunService "${1:-start}"
#define direct dirent
#define vnode_t struct vnode
-#define VN_RELE(vp) vrele(((struct vnode *)(vp)))
-#define VN_HOLD(vp) VREF(((struct vnode *)(vp)))
+//#define VN_RELE(vp) vrele(((struct vnode *)(vp)))
+//#define VN_HOLD(vp) VREF(((struct vnode *)(vp)))
#define BIND_8_COMPAT
#endif