mirror of
https://git.openafs.org/openafs.git
synced 2025-01-31 21:47:45 +00:00
FBSD: Add osi_fbsd_checkinuse
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>
This commit is contained in:
parent
dda5cc0c5f
commit
a3ef19e199
@ -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;
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
@ -24,20 +24,39 @@
|
||||
#endif
|
||||
|
||||
int
|
||||
osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
|
||||
osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep)
|
||||
{
|
||||
struct vnode *vp;
|
||||
int code;
|
||||
|
||||
/*
|
||||
* 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)
|
||||
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 *
|
||||
|
@ -75,34 +75,22 @@
|
||||
int
|
||||
osi_VM_FlushVCache(struct vcache *avc, int *slept)
|
||||
{
|
||||
struct vnode *vp = AFSTOV(avc);
|
||||
struct vnode *vp;
|
||||
int code;
|
||||
|
||||
if (!VI_TRYLOCK(vp)) /* need interlock to check usecount */
|
||||
vp = AFSTOV(avc);
|
||||
|
||||
if (!VI_TRYLOCK(vp))
|
||||
return EBUSY;
|
||||
|
||||
if (vp->v_usecount > 0) {
|
||||
code = osi_fbsd_checkinuse(avc);
|
||||
if (code) {
|
||||
VI_UNLOCK(vp);
|
||||
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) {
|
||||
VI_UNLOCK(vp);
|
||||
return EBUSY;
|
||||
}
|
||||
|
||||
/* if a lock is held, give up */
|
||||
if (CheckLock(&avc->lock)) {
|
||||
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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user