afs: Assert avc->lock is held in afs_IAS_once 92/14592/3
authorAndrew Deason <adeason@sinenomine.net>
Mon, 12 Apr 2021 23:21:23 +0000 (18:21 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Thu, 13 May 2021 16:54:35 +0000 (12:54 -0400)
Commit 3be5880d (afs: Avoid panics in afs_InvalidateAllSegments) added
an assert to check that vcache->lock is write-locked before we call
afs_InvalidateAllSegments_once from a background operation.

However, afs_InvalidateAllSegments_once should always be called with
vcache->lock write-locked; there's nothing specific about the
backgrounded call that requires this. So to make sure we catch all
cases, move this assert to afs_InvalidateAllSegments_once itself.

Also remove the conditional check for WriteLocked(&avc->lock) in here,
since clearly avc->lock must be write-locked (and actually is, since
change Ic309e4006bf47bcb38fa2b53bf103e0c645a856d "afs: write-lock
vcache->lock in afs_InactiveVCache").

Add some comments to this function while we're here, to more clearly
indicate what locks are needed.

Change-Id: I10c47021e94220879cd79c0f7390c52a13ee0eee
Reviewed-on: https://gerrit.openafs.org/14592
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>

src/afs/afs_daemons.c
src/afs/afs_segments.c

index 8913958..bd9fb56 100644 (file)
@@ -600,7 +600,6 @@ BInvalidateSegments(struct brequest *ab)
 {
     int code;
     struct vcache *tvc = ab->vc;
-    osi_Assert(WriteLocked(&tvc->lock));
 
     code = afs_InvalidateAllSegments_once(tvc);
 
index 91e6f28..7531723 100644 (file)
@@ -496,6 +496,17 @@ afs_StoreAllSegments(struct vcache *avc, struct vrequest *areq,
 
 }                              /*afs_StoreAllSegments (new 03/02/94) */
 
+/*!
+ * Attempt to invalidate all chunks for a given file.
+ *
+ * \pre avc->lock is write-locked
+ * \pre afs_xdcache is not held
+ *
+ * \param   avc        vcache to invalidate segments for
+ * \return  errno-style error codes. when an error is returned, the caller must
+ *         retry the invalidation until successful (see comments in
+ *         afs_InvalidateAllSegments)
+ */
 int
 afs_InvalidateAllSegments_once(struct vcache *avc)
 {
@@ -508,14 +519,16 @@ afs_InvalidateAllSegments_once(struct vcache *avc)
     AFS_STATCNT(afs_InvalidateAllSegments);
     afs_Trace2(afs_iclSetp, CM_TRACE_INVALL, ICL_TYPE_POINTER, avc,
               ICL_TYPE_OFFSET, ICL_HANDLE_OFFSET(avc->f.m.Length));
+
+    osi_Assert(WriteLocked(&avc->lock));
+
     hash = DVHash(&avc->f.fid);
     avc->f.truncPos = AFS_NOTRUNC;     /* don't truncate later */
     avc->f.states &= ~CExtendedFile;   /* not any more */
     afs_StaleVCacheFlags(avc, 0, CDirty);
     /* Blow away pages; for now, only for Solaris */
 #if    (defined(AFS_SUN5_ENV))
-    if (WriteLocked(&avc->lock))
-       osi_ReleaseVM(avc, (afs_ucred_t *)0);
+    osi_ReleaseVM(avc, (afs_ucred_t *)0);
 #endif
     /*
      * Block out others from screwing with this table; is a read lock