From 46727481ec5c47c2d3402acb572bf0d6167690ec Mon Sep 17 00:00:00 2001 From: Ben Kaduk Date: Wed, 30 Jun 2010 00:21:10 -0400 Subject: [PATCH] FBSD TryToSmush locking fixup We need to hold the interlock when we check v_flags, so do so. TryToSmush is sometimes called with the vnode already locked, as the current code appears to hold the vnode lock for the current working directory (which is probably a bug). Check if the lock is already held (panic if someone else has it!), and unlock as appropriate when we're done. Change-Id: Id09ef1e10632c7f63b590271a6339a069176deac Reviewed-on: http://gerrit.openafs.org/2294 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- src/afs/FBSD/osi_vm.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/afs/FBSD/osi_vm.c b/src/afs/FBSD/osi_vm.c index f8807fcd6..7ad17c897 100644 --- a/src/afs/FBSD/osi_vm.c +++ b/src/afs/FBSD/osi_vm.c @@ -185,15 +185,28 @@ osi_VM_TryToSmush(struct vcache *avc, afs_ucred_t *acred, int sync) { struct vnode *vp; int tries, code; + int islocked; SPLVAR; vp = AFSTOV(avc); + VI_LOCK(vp); if (vp->v_iflag & VI_DOOMED) { + VI_UNLOCK(vp); USERPRI; return; } + VI_UNLOCK(vp); + + islocked = VOP_ISLOCKED(vp); + if (islocked == LK_EXCLOTHER) + panic("Trying to Smush over someone else's lock"); + else if (islocked == LK_SHARED) { + afs_warn("Trying to Smush with a shared lock"); + vn_lock(vp, LK_UPGRADE); + } else if (!islocked) + vn_lock(vp, LK_EXCLUSIVE); if (vp->v_bufobj.bo_object != NULL) { VM_OBJECT_LOCK(vp->v_bufobj.bo_object); @@ -218,9 +231,14 @@ osi_VM_TryToSmush(struct vcache *avc, afs_ucred_t *acred, int sync) tries = 5; code = osi_vinvalbuf(vp, V_SAVE, PCATCH, 0); while (code && (tries > 0)) { + afs_warn("TryToSmush retrying vinvalbuf"); code = osi_vinvalbuf(vp, V_SAVE, PCATCH, 0); --tries; } + if (islocked == LK_SHARED) + vn_lock(vp, LK_DOWNGRADE); + else if (!islocked) + VOP_UNLOCK(vp, 0); USERPRI; } -- 2.39.5