hold-afs-xcell-lock-during-setserverprefs-20011113
authorDerrick Brashear <shadow@dementia.org>
Tue, 13 Nov 2001 17:24:05 +0000 (17:24 +0000)
committerDerrick Brashear <shadow@dementia.org>
Tue, 13 Nov 2001 17:24:05 +0000 (17:24 +0000)
afs_RemoveCellEntry holds afs_xcell; setserverprefs modified the same
structure but did not which was problematic if something changed out from under
it

src/afs/afs.h
src/afs/afs_cell.c
src/afs/afs_pioctl.c

index 86a9996..4656f9d 100644 (file)
@@ -968,6 +968,7 @@ extern struct brequest afs_brs[NBRS];               /* request structures */
 #define        FVHash(acell,avol)  (((avol)+(acell)) & (NFENTRIES-1))
 
 extern struct cell         *afs_GetCell();
+extern struct cell         *afs_GetCellNoLock();
 extern struct cell         *afs_GetCellByName();
 extern struct cell         *afs_GetCellByName2();
 extern struct cell         *afs_GetCellByIndex();
index 7416249..1061d3d 100644 (file)
@@ -347,28 +347,46 @@ struct cell *afs_GetCellByName(acellName, locktype)
 
 } /*afs_GetCellByName*/
 
-
 struct cell *afs_GetCell(acell, locktype)
     register afs_int32 acell;
     afs_int32 locktype;
 {
+    return afs_GetCellInternal(acell, locktype, 1);
+}
+
+/* This is only to be called if the caller is already holding afs_xcell */
+struct cell *afs_GetCellNoLock(acell, locktype)
+    register afs_int32 acell;
+    afs_int32 locktype;
+{
+    return afs_GetCellInternal(acell, locktype, 0);
+}
+
+static struct cell *afs_GetCellInternal(acell, locktype, holdxcell)
+    register afs_int32 acell;
+    afs_int32 locktype;
+    int holdxcell;
+{
     register struct cell *tc;
     register struct afs_q *cq, *tq;
 
     AFS_STATCNT(afs_GetCell);
     if (acell == 1 && afs_rootcell) return afs_rootcell;
-    ObtainWriteLock(&afs_xcell,101);
+    if (holdxcell)
+       ObtainWriteLock(&afs_xcell,101);
     for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
        tc = QTOC(cq); tq = QNext(cq);
        if (tc->cell == acell) {
            QRemove(&tc->lruq);
            QAdd(&CellLRU, &tc->lruq);
-           ReleaseWriteLock(&afs_xcell);
+           if (holdxcell)
+               ReleaseWriteLock(&afs_xcell);
            afs_RefreshCell(tc);
            return tc;
        }
     }
-    ReleaseWriteLock(&afs_xcell);
+    if (holdxcell)
+       ReleaseWriteLock(&afs_xcell);
     return (struct cell *) 0;
 
 } /*afs_GetCell*/
index ae55c75..ab2fe28 100644 (file)
@@ -2941,27 +2941,29 @@ static void ReSortCells(s,l, vlonly)
   register int  k;
 
   if (vlonly) {
-     struct cell *tcell;
-     for(k=0;k<s;k++) {
-        tcell = afs_GetCell(l[k], WRITE_LOCK);
-       if (!tcell) continue;
-       afs_SortServers(tcell->cellHosts, MAXCELLHOSTS);
-       afs_PutCell(tcell, WRITE_LOCK);
-     }
-     return;
+      struct cell *tcell;
+      ObtainWriteLock(&afs_xcell,300);
+      for(k=0;k<s;k++) {
+         tcell = afs_GetCellNoLock(l[k], WRITE_LOCK);
+         if (!tcell) continue;
+         afs_SortServers(tcell->cellHosts, MAXCELLHOSTS);
+         afs_PutCell(tcell, WRITE_LOCK);
+      }
+      ReleaseWriteLock(&afs_xcell);
+      return;
   }
 
   ObtainReadLock(&afs_xvolume);
   for (i= 0; i< NVOLS; i++) {
-     for (j=afs_volumes[i];j;j=j->next) {
-        for (k=0;k<s;k++)
-          if (j->cell == l[k]) {
-             ObtainWriteLock(&j->lock,233);
-             afs_SortServers(j->serverHost, MAXHOSTS);
-             ReleaseWriteLock(&j->lock);
-             break; 
-          }
-     }
+      for (j=afs_volumes[i];j;j=j->next) {
+         for (k=0;k<s;k++)
+             if (j->cell == l[k]) {
+                 ObtainWriteLock(&j->lock,233);
+                 afs_SortServers(j->serverHost, MAXHOSTS);
+                 ReleaseWriteLock(&j->lock);
+                 break; 
+             }
+      }
   }
   ReleaseReadLock(&afs_xvolume);
 }