freebsd: properly track vcache references
authorDerrick Brashear <shadow@dementia.org>
Thu, 2 Dec 2010 06:55:34 +0000 (01:55 -0500)
committerDerrick Brashear <shadow@dementia.org>
Thu, 2 Dec 2010 17:26:25 +0000 (09:26 -0800)
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 <kaduk@mit.edu>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

src/afs/FBSD/osi_vfsops.c
src/afs/FBSD/osi_vnodeops.c

index c0673f0..b956b80 100644 (file)
@@ -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();
index 5affb10..7ae6571 100644 (file)
@@ -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)