*slept = 1;
#if defined(AFS_FBSD80_ENV)
- /* vgone() is correct, but v_usecount is assumed not
- * to be 0, and I suspect that currently our usage ensures that
- * in fact it will */
- if (vrefcnt(vp) < 1) {
+ /* vgone() is correct, but vgonel() panics if v_usecount is 0--
+ * this is particularly confusing since vgonel() will trigger
+ * vop_reclaim, in the call path of which we'll check v_usecount
+ * and decide that the vnode is busy. Splat. */
+ if (vrefcnt(vp) < 1)
vref(vp);
- }
+
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); /* !glocked */
#endif
-
vgone(vp);
#if defined(AFS_FBSD80_ENV)
VOP_UNLOCK(vp, 0);
{
struct vm_object *obj;
struct vnode *vp;
- if (VREFCOUNT(avc) > 1)
+ if (VREFCOUNT(avc) > 1) {
return EBUSY;
+ }
- if (avc->opens)
+ /* XXX
+ * The value of avc->opens here came to be, at some point,
+ * typically -1. This was caused by incorrectly performing afs_close
+ * processing on vnodes being recycled */
+ if (avc->opens) {
return EBUSY;
+ }
/* if a lock is held, give up */
- if (CheckLock(&avc->lock))
+ if (CheckLock(&avc->lock)) {
return EBUSY;
+ }
return(0);
* struct thread *a_td;
* } */ *ap;
{
- int code;
- struct vcache *avc = VTOAFS(ap->a_vp);
+ int code, iflag;
+ struct vnode *vp = ap->a_vp;
+ struct vcache *avc = VTOAFS(vp);
+
+#if defined(AFS_FBSD80_ENV)
+ VI_LOCK(vp);
+ iflag = vp->v_iflag & VI_DOOMED;
+ VI_UNLOCK(vp);
+ if (iflag & VI_DOOMED) {
+ /* osi_FlushVCache (correctly) calls vgone() on recycled vnodes, we don't
+ * have an afs_close to process, in that case */
+ if (avc->opens != 0)
+ panic("afs_vop_close: doomed vnode %p has vcache %p with non-zero opens %d\n",
+ vp, avc, avc->opens);
+ return 0;
+ }
+#endif
+
AFS_GLOCK();
if (ap->a_cred)
code = afs_close(avc, ap->a_fflag, ap->a_cred);
if (!haveGlock)
AFS_GUNLOCK();
- /*
- * XXX Pretend it worked, to prevent panic on shutdown
- * Garrett, please fix - Jim Rees
- */
if (code) {
- printf("afs_vop_reclaim: afs_FlushVCache failed code %d vnode\n", code);
+ afs_warn("afs_vop_reclaim: afs_FlushVCache failed code %d vnode\n", code);
VOP_PRINT(vp);
}
struct vcache *vc = VTOAFS(ap->a_vp);
int s = vc->f.states;
- printf("tag %s, fid: %d.%d.%d.%d, opens %d, writers %d", vp->v_tag,
+ printf("vc %p vp %p tag %s, fid: %d.%d.%d.%d, opens %d, writers %d", vc, vp, vp->v_tag,
(int)vc->f.fid.Cell, (u_int) vc->f.fid.Fid.Volume,
(u_int) vc->f.fid.Fid.Vnode, (u_int) vc->f.fid.Fid.Unique, vc->opens,
vc->execsOrWriters);
code = avc->vc_error;
avc->vc_error = 0;
}
+#if defined(AFS_FBSD80_ENV)
+ /* XXX */
+ if (!avc->opens) {
+ afs_int32 opens, is_free, is_gone, is_doomed, iflag;
+ struct vnode *vp = AFSTOV(avc);
+ VI_LOCK(vp);
+ is_doomed = vp->v_iflag & VI_DOOMED;
+ is_free = vp->v_iflag & VI_FREE;
+ is_gone = vp->v_iflag & VI_DOINGINACT;
+ iflag = vp->v_iflag;
+ VI_UNLOCK(vp);
+ opens = avc->opens;
+ afs_warn("afs_close avc %p vp %p opens %d free %d doinginact %d doomed %d iflag %d\n",
+ avc, vp, opens, is_free, is_gone, is_doomed, iflag);
+ }
+#endif
avc->opens--;
ReleaseWriteLock(&avc->lock);
}