From: Andrew Deason Date: Fri, 1 Apr 2011 18:43:13 +0000 (-0500) Subject: afs: Retry unlock after afs_StoreAllSegments X-Git-Tag: upstream/1.6.1.pre1^2~136 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=c096127f73348a470e0e478b31c3fe132304b009;p=packages%2Fo%2Fopenafs.git afs: Retry unlock after afs_StoreAllSegments HandleFlock calls afs_StoreAllSegments when unlocking an exclusive flock lock. This can drop the write lock on avc, so we must effectively retry the entire lock operation again, since the world may have changed while we were waiting to reacquire the lock on avc. So, retry once all of the lock checks up to that point, to ensure that a lock on the file actually still exists. FIXES 125446 Reviewed-on: http://gerrit.openafs.org/4393 Reviewed-by: Derrick Brashear Tested-by: BuildBot (cherry picked from commit 601fcf1d7f7c88cfc0ffd877c5458340b3e59098) Change-Id: Ibd215d586485d8f18f77665f5f85e6bee579e35e Reviewed-on: http://gerrit.openafs.org/5766 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- diff --git a/src/afs/VNOPS/afs_vnop_flock.c b/src/afs/VNOPS/afs_vnop_flock.c index 2eeb427c3..33c679fef 100644 --- a/src/afs/VNOPS/afs_vnop_flock.c +++ b/src/afs/VNOPS/afs_vnop_flock.c @@ -271,6 +271,8 @@ HandleFlock(struct vcache *avc, int acom, struct vrequest *areq, #endif ObtainWriteLock(&avc->lock, 118); if (acom & LOCK_UN) { + int stored_segments = 0; + retry_unlock: /* defect 3083 */ @@ -317,7 +319,14 @@ HandleFlock(struct vcache *avc, int acom, struct vrequest *areq, } } } else if (avc->flockCount == -1) { - afs_StoreAllSegments(avc, areq, AFS_SYNC | AFS_VMSYNC); /* fsync file early */ + if (!stored_segments) { + afs_StoreAllSegments(avc, areq, AFS_SYNC | AFS_VMSYNC); /* fsync file early */ + /* afs_StoreAllSegments can drop and reacquire the write lock + * on avc and GLOCK, so the flocks may be completely different + * now. Go back and perform all checks again. */ + stored_segments = 1; + goto retry_unlock; + } avc->flockCount = 0; /* And remove the (only) exclusive lock entry from the list... */ osi_FreeSmallSpace(avc->slocks);