fix-dcache-deadlock-20011225
authorNickolai Zeldovich <kolya@mit.edu>
Tue, 25 Dec 2001 18:10:39 +0000 (18:10 +0000)
committerDerrick Brashear <shadow@dementia.org>
Tue, 25 Dec 2001 18:10:39 +0000 (18:10 +0000)
"This patch fixes a deadlock in the new dcache locking scheme.
  The underlying bug apparently existed before, but due to the
  absence of locking, it probably resulted in spuriously high
  refcounts rather than deadlock.

  The problem happens when there are zero-length dcache entries
  associated with a file; this is demonstrated by fsx, which
  hangs after running on AFS for a while.  The writeback loop
  never releases dcache entries unless they're stored back to
  the server as part of a sequential byte range."

src/afs/afs_segments.c

index 39f29bb..a21793e 100644 (file)
@@ -613,6 +613,8 @@ restart:
                tdc->dflags |= DFEntryMod;
                ReleaseWriteLock(&tdc->lock);
                afs_PutDCache(tdc);
+               /* Mark the entry as released */
+               dclist[i] = NULL;
            }
 
            if (code) {
@@ -620,6 +622,8 @@ restart:
                    if ( dcList[j] ) {
                        ReleaseSharedLock(&(dcList[j]->lock));
                        afs_PutDCache(dcList[j]);
+                       /* Releasing entry */
+                       dcList[j] = NULL;
                    }
                }
            }
@@ -629,6 +633,18 @@ restart:
            bytes = 0;
          }
        }
+       
+       /* Release any zero-length dcache entries in our interval
+        * that we locked but didn't store back above.
+        */
+       for (j = 0; j<=high; j++) {
+         tdc = dcList[j];
+         if (tdc) {
+           osi_Assert(tdc->f.chunkBytes == 0);
+           ReleaseSharedLock(&tdc->lock);
+           afs_PutDCache(tdc);
+         }
+       }
       } /* if (j) */
 
     minj += NCHUNKSATONCE;