mirror of
https://git.openafs.org/openafs.git
synced 2025-01-20 07:51:00 +00:00
FBSD CM: don't call afs_close when recycling
Don't call afs_close when handling VOP_CLOSE on a recycled vnode, since there was no matching open. This corrects the opens count, which was seen to go have gone negative in the reclaim vop. For clarity, assert if afs_vop_close is entered with a VI_DOOMED vnode and avc->opens != 0. Change-Id: I511a4f2a924c2f8e20f3ecdaa445fbe803289a47 Change-Id: I1b2307fd3318fa54e8f7fb72a5d3f843e2a38404 Reviewed-on: http://gerrit.openafs.org/2612 Reviewed-by: Derrick Brashear <shadow@dementia.org> Tested-by: Derrick Brashear <shadow@dementia.org>
This commit is contained in:
parent
3f7b70a28b
commit
5c0aebc421
@ -36,15 +36,15 @@ osi_TryEvictVCache(struct vcache *avc, int *slept) {
|
||||
*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);
|
||||
|
@ -89,15 +89,22 @@ osi_VM_FlushVCache(struct vcache *avc, int *slept)
|
||||
{
|
||||
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);
|
||||
|
||||
|
@ -666,8 +666,24 @@ afs_vop_close(ap)
|
||||
* 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);
|
||||
@ -1473,12 +1489,8 @@ afs_vop_reclaim(struct vop_reclaim_args *ap)
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1539,7 +1551,7 @@ afs_vop_print(ap)
|
||||
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);
|
||||
|
@ -815,6 +815,22 @@ afs_close(OSI_VC_DECL(avc), afs_int32 aflags, afs_ucred_t *acred)
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user