]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
STABLE12-dir-hold-afs-bufferlock-across-increment-of-buffer-lockers-to-prevent-newslo...
authorDerrick Brashear <shadow@dementia.org>
Sat, 8 Jun 2002 01:16:59 +0000 (01:16 +0000)
committerDerrick Brashear <shadow@dementia.org>
Sat, 8 Jun 2002 01:16:59 +0000 (01:16 +0000)
liberal debugging code and hammering produced a failure where newslot was
actually walking on another call to newslot because the bufferlock was
being dropped before newslot incremented lockers on the buffer it
was allocating, allowing someone else to come along and also think they
could allocate it.

by holding the bufferlock just a little longer we avoid this

(cherry picked from commit 0eb68f307aac84472a13523a0ce8b7a865f01ac7)

src/dir/buffer.c

index c7cca713f7d27d07e20b02d3424f733434d41541..bc5d6d0ca7f25bfc1ad89a5749d107ea82c4af16 100644 (file)
@@ -132,8 +132,8 @@ char *DRead(fid,page)
     if ( tb = phTable[pHash(fid)] ) {  /* ASSMT HERE */
        if (bufmatch(tb)) {
            ObtainWriteLock(&tb->lock);
-           ReleaseWriteLock(&afs_bufferLock);
            tb->lockers++;
+           ReleaseWriteLock(&afs_bufferLock);
            tb->accesstime = ++timecounter;
            ReleaseWriteLock(&tb->lock);
            return tb->data;
@@ -144,8 +144,8 @@ char *DRead(fid,page)
            if (bufmatch(tb2)) {
              buf_Front(bufhead,tb,tb2);
              ObtainWriteLock(&tb2->lock);
-             ReleaseWriteLock(&afs_bufferLock);
              tb2->lockers++;
+             ReleaseWriteLock(&afs_bufferLock);
              tb2->accesstime = ++timecounter;
              ReleaseWriteLock(&tb2->lock);
              return tb2->data;
@@ -154,8 +154,8 @@ char *DRead(fid,page)
              if (bufmatch(tb)) {
                buf_Front(bufhead,tb2,tb);
                ObtainWriteLock(&tb->lock);
-               ReleaseWriteLock(&afs_bufferLock);
                tb->lockers++;
+               ReleaseWriteLock(&afs_bufferLock);
                tb->accesstime = ++timecounter;
                ReleaseWriteLock(&tb->lock);
                return tb->data;
@@ -175,8 +175,8 @@ char *DRead(fid,page)
     tb = newslot(fid, page, (tb ? tb : tb2));
     ios++;
     ObtainWriteLock(&tb->lock);
-    ReleaseWriteLock(&afs_bufferLock);
     tb->lockers++;
+    ReleaseWriteLock(&afs_bufferLock);
     if (ReallyRead(tb->fid,tb->page,tb->data)) {
        tb->lockers--;
         FidZap(tb->fid);       /* disaster */
@@ -396,8 +396,8 @@ char *DNew (fid,page)
     ObtainWriteLock(&afs_bufferLock);
     tb = newslot(fid,page,0);
     ObtainWriteLock(&tb->lock);
-    ReleaseWriteLock(&afs_bufferLock);
     tb->lockers++;
+    ReleaseWriteLock(&afs_bufferLock);
     ReleaseWriteLock(&tb->lock);
     return tb->data;
 }