]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
FBSD: Add osi_fbsd_checkinuse
authorAndrew Deason <adeason@sinenomine.net>
Sun, 20 May 2012 22:05:12 +0000 (17:05 -0500)
committerDerrick Brashear <shadow@dementix.org>
Wed, 27 Jun 2012 12:32:23 +0000 (05:32 -0700)
Add the osi_fbsd_checkinuse function, which contains code common to
the FreeBSD osi_TryEvictVCache and osi_VM_FlushVCache. Implement the
latter two in terms of osi_fbsd_checkinuse.

This commit should incur no behavior changes. This is just a
reorganization so future commits can change the implementations of
osi_TryEvictVCache and osi_VM_FlushVCache.

Change-Id: I42df9d6efb7b573bd933d0bf04924f668a3608da
Reviewed-on: http://gerrit.openafs.org/7432
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Derrick Brashear <shadow@dementix.org>
src/afs/FBSD/osi_misc.c
src/afs/FBSD/osi_prototypes.h
src/afs/FBSD/osi_vcache.c
src/afs/FBSD/osi_vm.c

index 04fe165a8fa50398ab6f2275c16609a5e32bf605..debc35474fc1890922c020bf323eb0ebc209ccf9 100644 (file)
@@ -91,3 +91,43 @@ osi_fbsd_free(void *p)
 {
        free(p, M_AFS);
 }
+
+/**
+ * check if a vcache is in use
+ *
+ * @return status
+ *  @retcode 0 success
+ *  @retcode EBUSY vcache is in use by someone else
+ *  @retcode otherwise other error
+ *
+ * @pre  The caller must hold the vnode interlock for the associated vnode
+ * @post The vnode interlock for the associated vnode will still be held
+ *       and must be VI_UNLOCK'd by the caller
+ */
+int
+osi_fbsd_checkinuse(struct vcache *avc)
+{
+    struct vnode *vp = AFSTOV(avc);
+
+    ASSERT_VI_LOCKED(vp, "osi_fbsd_checkinuse");
+
+    /* The interlock is needed to check the usecount. */
+    if (vp->v_usecount > 0) {
+       return EBUSY;
+    }
+
+    /* 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)) {
+       return EBUSY;
+    }
+
+    return 0;
+}
index b62a4f863ae9fe6e4707fc45db596afafe11c35f..c3c3b60423df30217d9c91ba4b51deb5c41f84a3 100644 (file)
@@ -32,4 +32,6 @@ extern int afs_statfs(struct mount *mp, struct statfs *abp);
 extern int afs_statfs(struct mount *mp, struct statfs *abp, struct thread *td);
 #endif
 
+extern int osi_fbsd_checkinuse(struct vcache *avc);
+
 #endif /* _OSI_PROTO_H_ */
index 07c332723f99df33d71338173ae9fcb6e35aee6b..8f4df57670d2865e1fb5f8b13c45899f64b0d988 100644 (file)
 #endif
 
 int
-osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
-
-    /*
-     * essentially all we want to do here is check that the
-     * vcache is not in use, then call vgone() (which will call
-     * inactive and reclaim as needed).  This requires some
-     * kind of complicated locking, which we already need to implement
-     * for FlushVCache, so just call that routine here and check
-     * its return value for whether the vcache was evict-able.
-     */
-    if (osi_VM_FlushVCache(avc, slept) != 0)
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep)
+{
+    struct vnode *vp;
+    int code;
+
+    vp = AFSTOV(avc);
+
+    if (!VI_TRYLOCK(vp))
        return 0;
-    else
+    code = osi_fbsd_checkinuse(avc);
+    if (code != 0) {
+       VI_UNLOCK(vp);
+       return 0;
+    }
+
+    if ((vp->v_iflag & VI_DOOMED) != 0) {
+       VI_UNLOCK(vp);
        return 1;
+    }
+
+    /* must hold the vnode before calling vgone()
+     * This code largely copied from vfs_subr.c:vlrureclaim() */
+    vholdl(vp);
+    AFS_GUNLOCK();
+    *slept = 1;
+    /* use the interlock while locking, so no one else can DOOM this */
+    ma_vn_lock(vp, LK_INTERLOCK|LK_EXCLUSIVE|LK_RETRY, curthread);
+    vgone(vp);
+    MA_VOP_UNLOCK(vp, 0, curthread);
+    vdrop(vp);
+
+    AFS_GLOCK();
+    return 1;
 }
 
 struct vcache *
index 072142d7991c0012339fe15eee7a474ac8db4a13..c2f7ce1801d0c685e257458f58c1b549f1d30f3b 100644 (file)
 int
 osi_VM_FlushVCache(struct vcache *avc, int *slept)
 {
-    struct vnode *vp = AFSTOV(avc);
-
-    if (!VI_TRYLOCK(vp)) /* need interlock to check usecount */
-       return EBUSY;
+    struct vnode *vp;
+    int code;
 
-    if (vp->v_usecount > 0) {
-       VI_UNLOCK(vp);
-       return EBUSY;
-    }
+    vp = AFSTOV(avc);
 
-    /* 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) {
-       VI_UNLOCK(vp);
+    if (!VI_TRYLOCK(vp))
        return EBUSY;
-    }
-
-    /* if a lock is held, give up */
-    if (CheckLock(&avc->lock)) {
+    code = osi_fbsd_checkinuse(avc);
+    if (code) {
        VI_UNLOCK(vp);
-       return EBUSY;
+       return code;
     }
 
     if ((vp->v_iflag & VI_DOOMED) != 0) {
        VI_UNLOCK(vp);
-       return (0);
+       return 0;
     }
 
     /* must hold the vnode before calling vgone()