From: Derrick Brashear Date: Thu, 2 Dec 2010 06:55:34 +0000 (-0500) Subject: freebsd: properly track vcache references X-Git-Tag: openafs-devel-1_7_1~1159 X-Git-Url: http://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=6eb1088a freebsd: properly track vcache references previously both root and reclaim could end up leaking refs. fix it. Change-Id: Ib3c9dab2f31b988a2887821f5192ff1fad0e732c Reviewed-on: http://gerrit.openafs.org/3424 Reviewed-by: Benjamin Kaduk Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- diff --git a/src/afs/FBSD/osi_vfsops.c b/src/afs/FBSD/osi_vfsops.c index c0673f0..b956b80 100644 --- a/src/afs/FBSD/osi_vfsops.c +++ b/src/afs/FBSD/osi_vfsops.c @@ -189,19 +189,33 @@ afs_unmount(struct mount *mp, int flags, struct thread *p) { int error = 0; + AFS_GLOCK(); + if (afs_globalVp && + ((flags & MNT_FORCE) || !VREFCOUNT_GT(afs_globalVp, 1))) { + /* Put back afs_root's ref */ + struct vcache *gvp = afs_globalVp; + afs_globalVp = NULL; + afs_PutVCache(gvp); + } + if (afs_globalVp) + error = EBUSY; + AFS_GUNLOCK(); + /* * Release any remaining vnodes on this mount point. * The `1' means that we hold one extra reference on * the root vnode (this is just a guess right now). * This has to be done outside the global lock. */ + if (!error) { #if defined(AFS_FBSD80_ENV) - error = vflush(mp, 1, (flags & MNT_FORCE) ? FORCECLOSE : 0, curthread); + error = vflush(mp, 1, (flags & MNT_FORCE) ? FORCECLOSE : 0, curthread); #elif defined(AFS_FBSD53_ENV) - error = vflush(mp, 1, (flags & MNT_FORCE) ? FORCECLOSE : 0, p); + error = vflush(mp, 1, (flags & MNT_FORCE) ? FORCECLOSE : 0, p); #else - error = vflush(mp, 1, (flags & MNT_FORCE) ? FORCECLOSE : 0); + error = vflush(mp, 1, (flags & MNT_FORCE) ? FORCECLOSE : 0); #endif + } if (error) goto out; AFS_GLOCK(); diff --git a/src/afs/FBSD/osi_vnodeops.c b/src/afs/FBSD/osi_vnodeops.c index 5affb10..7ae6571 100644 --- a/src/afs/FBSD/osi_vnodeops.c +++ b/src/afs/FBSD/osi_vnodeops.c @@ -1498,6 +1498,12 @@ afs_vop_reclaim(struct vop_reclaim_args *ap) ObtainWriteLock(&afs_xvcache, 901); /* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */ code = afs_FlushVCache(avc, &slept); + + if (avc->f.states & CVInit) { + avc->f.states &= ~CVInit; + afs_osi_Wakeup(&avc->f.states); + } + if (!haveVlock) ReleaseWriteLock(&afs_xvcache); if (!haveGlock)