diff --git a/src/afs/afs.h b/src/afs/afs.h index d164b58921..e3fa64ad60 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -201,6 +201,7 @@ struct cell { u_short vlport; /* volume server port */ short states; /* state flags */ short cellIndex; /* relative index number per cell */ + short realcellIndex; /* as above but ignoring aliases */ time_t timeout; /* data expire time, if non-zero */ char *realName; /* who this cell is an alias for */ }; diff --git a/src/afs/afs_cell.c b/src/afs/afs_cell.c index d8c01da190..7b3a42e779 100644 --- a/src/afs/afs_cell.c +++ b/src/afs/afs_cell.c @@ -46,9 +46,9 @@ RCSID("$Header$"); afs_rwlock_t afs_xcell; /* allocation lock for cells */ struct afs_q CellLRU; afs_int32 afs_cellindex=0; +afs_int32 afs_realcellindex=0; afs_uint32 afs_nextCellNum = 0x100; - /* Local variables. */ struct cell *afs_rootcell = 0; @@ -420,6 +420,31 @@ struct cell *afs_GetCellByIndex(cellindex, locktype, refresh) } /*afs_GetCellByIndex*/ +struct cell *afs_GetRealCellByIndex(cellindex, locktype, refresh) + register afs_int32 cellindex; + afs_int32 locktype; + afs_int32 refresh; +{ + register struct cell *tc; + register struct afs_q *cq, *tq; + + AFS_STATCNT(afs_GetCellByIndex); + ObtainWriteLock(&afs_xcell,102); + for (cq = CellLRU.next; cq != &CellLRU; cq = tq) { + tc = QTOC(cq); tq = QNext(cq); + if (tc->realcellIndex == cellindex) { + QRemove(&tc->lruq); + QAdd(&CellLRU, &tc->lruq); + ReleaseWriteLock(&afs_xcell); + if (refresh) afs_RefreshCell(tc); + return tc; + } + } + ReleaseWriteLock(&afs_xcell); + return (struct cell *) 0; +} /*afs_GetRealCellByIndex*/ + + afs_int32 afs_NewCell(acellName, acellHosts, aflags, linkedcname, fsport, vlport, timeout, aliasFor) int aflags; char *acellName; @@ -487,6 +512,11 @@ afs_int32 afs_NewCell(acellName, acellHosts, aflags, linkedcname, fsport, vlport tc->vlport = (vlport ? vlport : AFS_VLPORT); afs_stats_cmperf.numCellsVisible++; newc++; + if (!aflags & CAlias) { + tc->realcellIndex = afs_realcellindex++; + } else { + tc->realcellIndex = -1; + } } if (aflags & CLinkedCell) { @@ -516,7 +546,10 @@ afs_int32 afs_NewCell(acellName, acellHosts, aflags, linkedcname, fsport, vlport tc->timeout = timeout; /* Allow converting an alias into a real cell */ - if (!(aflags & CAlias)) tc->states &= ~CAlias; + if (!(aflags & CAlias)) { + tc->states &= ~CAlias; + tc->realcellIndex = afs_realcellindex++; + } memset((char *)tc->cellHosts, 0, sizeof(tc->cellHosts)); if (aflags & CAlias) { diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index fe5c6c67bf..945c07e742 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -2392,17 +2392,7 @@ static PListCells(avc, afun, areq, ain, aout, ainSize, aoutSize) memcpy((char *)&whichCell, tp, sizeof(afs_int32)); tp += sizeof(afs_int32); - ObtainReadLock(&afs_xcell); - for (cq = CellLRU.next; cq != &CellLRU; cq = tq) { - tcell = QTOC(cq); tq = QNext(cq); - if (tcell->states & CAlias) { - tcell = 0; - continue; - } - if (whichCell == 0) break; - tcell = 0; - whichCell--; - } + tcell = afs_GetRealCellByIndex(whichCell, READ_LOCK, 0); if (tcell) { cp = aout; memset(cp, 0, MAXCELLHOSTS * sizeof(afs_int32)); @@ -2416,7 +2406,6 @@ static PListCells(avc, afun, areq, ain, aout, ainSize, aoutSize) cp += strlen(tcell->cellName)+1; *aoutSize = cp - aout; } - ReleaseReadLock(&afs_xcell); if (tcell) return 0; else return EDOM; } diff --git a/src/afs/afs_stats.h b/src/afs/afs_stats.h index 6fe1da442c..189ae73aec 100644 --- a/src/afs/afs_stats.h +++ b/src/afs/afs_stats.h @@ -455,6 +455,7 @@ struct afs_CMCallStats { afs_int32 C_afs_GetCell; /* afs_resource.c*/ afs_int32 C_afs_GetCellByIndex; /* afs_resource.c*/ afs_int32 C_afs_GetCellByName; /* afs_resource.c*/ + afs_int32 C_afs_GetRealCellByIndex; /* afs_resource.c*/ afs_int32 C_afs_NewCell; /* afs_resource.c*/ afs_int32 C_afs_GetUser; /* afs_resource.c*/ afs_int32 C_afs_PutUser; /* afs_resource.c*/ diff --git a/src/venus/kdump.c b/src/venus/kdump.c index 35995bfd22..2ee696142c 100644 --- a/src/venus/kdump.c +++ b/src/venus/kdump.c @@ -3950,6 +3950,7 @@ void print_cmstats(cmp) printf("\t%10d afs_GetCell\n", cmp->callInfo.C_afs_GetCell); printf("\t%10d afs_GetCellByIndex\n", cmp->callInfo.C_afs_GetCellByIndex); printf("\t%10d afs_GetCellByName\n", cmp->callInfo.C_afs_GetCellByName); + printf("\t%10d afs_GetRealCellByIndex\n", cmp->callInfo.C_afs_GetRealCellByIndex); printf("\t%10d afs_NewCell\n", cmp->callInfo.C_afs_NewCell); printf("\t%10d CheckVLDB\n", cmp->callInfo.C_CheckVLDB); printf("\t%10d afs_GetVolume\n", cmp->callInfo.C_afs_GetVolume); diff --git a/src/xstat/xstat_cm_test.c b/src/xstat/xstat_cm_test.c index 3c5d4c9a09..33e8364e00 100644 --- a/src/xstat/xstat_cm_test.c +++ b/src/xstat/xstat_cm_test.c @@ -451,6 +451,7 @@ print_cmCallStats() printf("\t%10d afs_GetCell\n", cmp->callInfo.C_afs_GetCell); printf("\t%10d afs_GetCellByIndex\n", cmp->callInfo.C_afs_GetCellByIndex); printf("\t%10d afs_GetCellByName\n", cmp->callInfo.C_afs_GetCellByName); + printf("\t%10d afs_GetRealCellByIndex\n", cmp->callInfo.C_afs_GetRealCellByIndex); printf("\t%10d afs_NewCell\n", cmp->callInfo.C_afs_NewCell); printf("\t%10d CheckVLDB\n", cmp->callInfo.C_CheckVLDB); printf("\t%10d afs_GetVolume\n", cmp->callInfo.C_afs_GetVolume);