hold-afs-xcell-lock-during-setserverprefs-20011113

afs_RemoveCellEntry holds afs_xcell; setserverprefs modified the same
structure but did not which was problematic if something changed out from under
it
This commit is contained in:
Derrick Brashear 2001-11-13 17:24:05 +00:00
parent b2821b103c
commit cb99519f77
3 changed files with 42 additions and 21 deletions

View 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();

View 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*/

View 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);
}