This is mostly a rewrite of src/afs/afs_cell.c, and associated changes
authorNickolai Zeldovich <kolya@mit.edu>
Fri, 23 Aug 2002 04:31:38 +0000 (04:31 +0000)
committerNickolai Zeldovich <kolya@mit.edu>
Fri, 23 Aug 2002 04:31:38 +0000 (04:31 +0000)
to other things.  Features of the new cell code:

 * Persistent name-to-cell-number mapping across reboots, to ensure the
   cell numbers in the dcache are meaningful.  Stored in the new cache
   file, /usr/vice/cache/CellInfo.
 * Allow cmdebug to query the cell number to cell name mapping.
 * Allow clients to have an empty CellServDB as long as AFSDB is enabled
   and ThisCell has AFSDB records.
 * The home cell retains the setuid bit even if looked up via AFSDB.
 * Dynroot gets its own cell, rather than piggybacking on cell 1.
 * Cell 1 is no longer special; cell numbers are now semi-opaque.
 * Convert cell traversal code to using GetCellByIndex rather than
   directly poking at CellLRU / afs_xcell.
 * Separate cells from aliases, which shouldn't have been the same
   in the first place.
 * Cleaner code (IMHO).

====================
This delta was composed from multiple commits as part of the CVS->Git migration.
The checkin message with each commit was inconsistent.
The following are the additional commit messages.
====================

make the arguments afs_CellNumValid takes match the prototype (since it
really is a afs_int32 it looks like)

====================

update irix to deal

====================

update irix to deal

====================

Fix some more references to the now-nonexistant cell->index

25 files changed:
src/afs/IRIX/osi_vfsops.c
src/afs/VNOPS/afs_vnop_lookup.c
src/afs/afs.h
src/afs/afs_analyze.c
src/afs/afs_call.c
src/afs/afs_callback.c
src/afs/afs_cell.c
src/afs/afs_daemons.c
src/afs/afs_dcache.c
src/afs/afs_dynroot.c
src/afs/afs_init.c
src/afs/afs_osi_vget.c
src/afs/afs_pioctl.c
src/afs/afs_prototypes.h
src/afs/afs_server.c
src/afs/afs_stats.h
src/afs/afs_vcache.c
src/afs/afs_volume.c
src/afsd/afsd.c
src/config/afs_args.h
src/fsint/afscbint.xg
src/fsprobe/fsprobe_callback.c
src/venus/cmdebug.c
src/venus/kdump.c
src/xstat/xstat_fs_callback.c

index 3ef415e..3c1b2fd 100644 (file)
@@ -522,7 +522,6 @@ afs_vget(OSI_VFS_DECL(afsp), vnode_t **avcp, struct fid *fidp)
 {
     struct VenusFid vfid;
     struct vrequest treq;
-    extern struct cell *afs_GetCellByIndex();
     register struct cell *tcell;
     register afs_int32 code = 0;
     afs_int32 ret;
@@ -541,13 +540,13 @@ afs_vget(OSI_VFS_DECL(afsp), vnode_t **avcp, struct fid *fidp)
     afid2 = (afs_fid2_t*)fidp;
     if (afid2->af_len == sizeof(afs_fid2_t) - sizeof(afid2->af_len)) {
        /* It's a checkpoint restart fid. */
-       tcell = afs_GetCellByIndex(afid2->af_cell, READ_LOCK, 0 /* !refresh */);
+       tcell = afs_GetCellByIndex(afid2->af_cell, READ_LOCK);
        if (!tcell) {
            code = ENOENT;
            goto out;
-        }
-       vfid.Cell = tcell->cell;
-       afs_PutCell(tcell, WRITE_LOCK);
+       }
+       vfid.Cell = tcell->cellNum;
+       afs_PutCell(tcell, READ_LOCK);
        vfid.Fid.Volume = afid2->af_volid;
        vfid.Fid.Vnode = afid2->af_vno;
        vfid.Fid.Unique = afid2->af_uniq;
index 11d5430..12e8006 100644 (file)
@@ -132,10 +132,10 @@ int EvalMountPoint(register struct vcache *avc, struct vcache *advc,
     }
     if (!tcell) return ENODEV;
 
-    mtptCell = tcell->cell;               /* The cell for the mountpoint */
+    mtptCell = tcell->cellNum;             /* The cell for the mountpoint */
     if (tcell->lcellp) {
-       hac = 1;                           /* has associated cell */
-       assocCell = tcell->lcellp->cell;   /* The associated cell */
+       hac = 1;                             /* has associated cell */
+       assocCell = tcell->lcellp->cellNum;  /* The associated cell */
     }
     afs_PutCell(tcell, READ_LOCK);         
 
@@ -244,6 +244,9 @@ int EvalMountPoint(register struct vcache *avc, struct vcache *advc,
  */
 void afs_InitFakeStat(struct afs_fakestat_state *state)
 {
+    if (!afs_fakestat_enable)
+       return;
+
     state->valid = 1;
     state->did_eval = 0;
     state->need_release = 0;
@@ -264,11 +267,13 @@ int afs_EvalFakeStat_int(struct vcache **avcp, struct afs_fakestat_state *state,
     struct volume *tvolp = NULL;
     int code = 0;
 
+    if (!afs_fakestat_enable)
+       return 0;
+
     osi_Assert(state->valid == 1);
     osi_Assert(state->did_eval == 0);
     state->did_eval = 1;
-    if (!afs_fakestat_enable)
-       return 0;
+
     tvc = *avcp;
     if (tvc->mvstat != 1)
        return 0;
@@ -378,6 +383,9 @@ int afs_TryEvalFakeStat(struct vcache **avcp, struct afs_fakestat_state *state,
  */
 void afs_PutFakeStat(struct afs_fakestat_state *state)
 {
+    if (!afs_fakestat_enable)
+       return;
+
     osi_Assert(state->valid == 1);
     if (state->need_release)
        afs_PutVCache(state->root_vp);
@@ -1296,20 +1304,14 @@ afs_lookup(adp, aname, avcp, acred)
     afs_PutDCache(tdc);
 
     if (code == ENOENT && afs_IsDynroot(adp) && dynrootRetry) {
-       struct cell *tcell;
-
        ReleaseReadLock(&adp->lock);
        dynrootRetry = 0;
-       if (*tname == '.')
-           tcell = afs_GetCellByName(tname + 1, READ_LOCK);
+       if (tname[0] == '.')
+           afs_LookupAFSDB(tname + 1);
        else
-           tcell = afs_GetCellByName(tname, READ_LOCK);
-       if (tcell) {
-           afs_PutCell(tcell, READ_LOCK);
-           afs_RefreshDynroot();
-           if (tname != aname && tname) osi_FreeLargeSpace(tname);
-           goto redo;
-       }
+           afs_LookupAFSDB(tname);
+       if (tname && tname != aname) osi_FreeLargeSpace(tname);
+       goto redo;
     } else {
        ReleaseReadLock(&adp->lock);
     }
index 0ef4b65..0f9e6da 100644 (file)
@@ -192,29 +192,43 @@ struct afs_cbr {
     struct AFSFid fid;
 };
 
-
-#define        LOCALCELL           1   /* local cell's number is always 1 */
+/* cellinfo file magic number */
+#define AFS_CELLINFO_MAGIC     0xf32817cd
 
 /* cell flags */
-#define        CPrimary            1       /* on if this is the primary cell */
-#define        CNoSUID             2       /* 1 if no suid progs can run from this cell */
-#define CHasVolRef        16       /* Volumes were referenced in this cell*/
-#define CLinkedCell       32
-#define CAlias            64       /* This cell entry is an alias */
+#define        CNoSUID                 0x02    /* disable suid bit for this cell */
+#define CLinkedCell4           0x04    /* reserved for ADDCELL2 pioctl */
+#define CNoAFSDB               0x08    /* never bother trying AFSDB */
+#define CHasVolRef             0x10    /* volumes were referenced */
+#define CLinkedCell            0x20    /* has a linked cell in lcellp */
 
 struct cell {
-    struct afs_q lruq;                      /* lru q next and prev */
-    afs_int32 cell;                                /* unique id assigned by venus */
+    struct afs_q lruq;                     /* lru q next and prev */
     char *cellName;                        /* char string name of cell */
-    struct server *cellHosts[MAXCELLHOSTS]; /* volume *location* hosts for this cell */
+    afs_int32 cellIndex;                   /* sequence number */
+    afs_int32 cellNum;                     /* semi-permanent cell number */
+    struct server *cellHosts[MAXCELLHOSTS]; /* volume *location* hosts */
     struct cell *lcellp;                   /* Associated linked cell */
     u_short fsport;                        /* file server port */
     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 */
+    struct cell_name *cnamep;              /* pointer to our cell_name */
+    afs_rwlock_t lock;                     /* protects cell data */
+};
+
+struct cell_name {
+    struct cell_name *next;
+    afs_int32 cellnum;
+    char *cellname;
+    char used;
+};
+
+struct cell_alias {
+    struct cell_alias *next;
+    afs_int32 index;
+    char *alias;
+    char *cell;
 };
 
 #define        afs_PutCell(cellp, locktype)
index ac5fa41..e74cd14 100644 (file)
@@ -164,7 +164,7 @@ static int VLDB_Same (struct VenusFid *afid, struct vrequest *areq)
     do {
         VSleep(2);     /* Better safe than sorry. */
        tconn = afs_ConnByMHosts(tcell->cellHosts, tcell->vlport,
-                                tcell->cell, &treq, SHARED_LOCK);
+                                tcell->cellNum, &treq, SHARED_LOCK);
        if (tconn) {
            if (tconn->srvr->server->flags & SNO_LHOSTS) {
                type = 0;
@@ -351,8 +351,8 @@ int afs_Analyze(register struct conn *aconn, afs_int32 acode,
            if (aerrP)
                (aerrP->err_Network)++;
            if (hm_retry_int && !(areq->flags & O_NONBLOCK) &&  /* "hard" mount */
-               ((afid && afid->Cell == LOCALCELL) || 
-                (cellp && cellp->cell == LOCALCELL))) { 
+               ((afid && afs_IsPrimaryCellNum(afid->Cell)) || 
+                (cellp && afs_IsPrimaryCell(cellp)))) { 
                if (!afid) {
                    afs_warnuser("afs: hard-mount waiting for a vlserver to return to service\n");
                    VSleep(hm_retry_int);
@@ -455,7 +455,7 @@ int afs_Analyze(register struct conn *aconn, afs_int32 acode,
        if (aerrP)
            (aerrP->err_Protection)++;
 
-       tu = afs_FindUser(areq->uid, tsp->cell->cell, READ_LOCK);
+       tu = afs_FindUser(areq->uid, tsp->cell->cellNum, READ_LOCK);
        if (tu) {
            if ((acode == VICETOKENDEAD) || (acode == RXKADEXPIRED))
                afs_warnuser("afs: Tokens for user of AFS id %d for cell %s have expired\n", 
index e9e804d..71ee1af 100644 (file)
@@ -83,6 +83,7 @@ static int afs_CacheInit_Done = 0;
 static int afs_Go_Done = 0;
 extern struct interfaceAddr afs_cb_interface;
 static int afs_RX_Running = 0;
+static int afs_InitSetup_done = 0;
 
 static int
 Afscall_icl(long opcode, long p1, long p2, long p3, long p4, long *retval);
@@ -99,6 +100,9 @@ static int afs_InitSetup(int preallocs)
     extern void afs_InitStats();
     int code;
 
+    if (afs_InitSetup_done)
+       return;
+
 #ifndef AFS_NOSTATS
     /*
      * Set up all the AFS statistics variables.  This should be done
@@ -121,6 +125,9 @@ static int afs_InitSetup(int preallocs)
     /* resource init creates the services */
     afs_ResourceInit(preallocs);
 
+    afs_InitSetup_done = 1;
+    afs_osi_Wakeup(&afs_InitSetup_done);
+
     return code;
 }
 
@@ -130,6 +137,11 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6)
 long parm, parm2, parm3, parm4, parm5, parm6;
 {
     afs_int32 code = 0;
+#if defined(AFS_SGI61_ENV) || defined(AFS_SUN57_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+    size_t bufferSize; 
+#else /* AFS_SGI61_ENV */
+    u_int bufferSize;  
+#endif /* AFS_SGI61_ENV */
 
     AFS_STATCNT(afs_syscall_call);
 #ifdef AFS_SUN5_ENV
@@ -205,23 +217,32 @@ long parm, parm2, parm3, parm4, parm5, parm6;
 #endif
     }
 #endif
-    else if (parm == AFSOP_START_AFS) {
-       /* afs daemon */
+    else if (parm == AFSOP_BASIC_INIT) {
        afs_int32 temp;
 
-       if (AFS_Running) goto out;
-       AFS_Running = 1;
-       while (afs_initState < AFSOP_START_AFS) 
-           afs_osi_Sleep(&afs_initState);
+       while (!afs_InitSetup_done)
+           afs_osi_Sleep(&afs_InitSetup_done);
 
 #if defined(AFS_SUN_ENV) || defined(AFS_SGI_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
        temp = AFS_MINBUFFERS;  /* Should fix this soon */
 #else
-       temp = ((afs_bufferpages * NBPG)>>11);  /* number of 2k buffers we could get from all of the buffer space */
+       /* number of 2k buffers we could get from all of the buffer space */
+       temp = ((afs_bufferpages * NBPG)>>11);
        temp = temp>>2; /* don't take more than 25% (our magic parameter) */
-       if (temp < AFS_MINBUFFERS) temp = AFS_MINBUFFERS;   /* although we really should have this many */
+       if (temp < AFS_MINBUFFERS)
+           temp = AFS_MINBUFFERS; /* though we really should have this many */
 #endif
        DInit(temp);
+       afs_rootFid.Fid.Volume = 0;
+       code = 0;
+    }
+    else if (parm == AFSOP_START_AFS) {
+       /* afs daemon */
+       if (AFS_Running) goto out;
+       AFS_Running = 1;
+       while (afs_initState < AFSOP_START_AFS) 
+           afs_osi_Sleep(&afs_initState);
+
        afs_initState = AFSOP_START_BKG;
        afs_osi_Wakeup(&afs_initState);
        afs_osi_Invisible();
@@ -287,7 +308,6 @@ long parm, parm2, parm3, parm4, parm5, parm6;
         home cell flag (0x1 bit) and the nosuid flag (0x2 bit) */
        struct afsop_cell tcell;
 
-       while (afs_initState < AFSOP_START_BKG) afs_osi_Sleep(&afs_initState);
        AFS_COPYIN((char *)parm2, (char *)tcell.hosts, sizeof(tcell.hosts), code);
        if (!code) {
            if (parm4 > sizeof(tcell.cellName)) 
@@ -296,18 +316,13 @@ long parm, parm2, parm3, parm4, parm5, parm6;
                AFS_COPYIN((char *)parm3, tcell.cellName, parm4, code);
                if (!code) 
                    afs_NewCell(tcell.cellName, tcell.hosts, parm5,
-                               0, 0, 0, 0, 0);
+                               NULL, 0, 0, 0);
            }
        }
     } else if (parm == AFSOP_ADDCELL2) {
        struct afsop_cell tcell;
        char *tbuffer = osi_AllocSmallSpace(AFS_SMALLOCSIZ), *lcnamep = 0;
        char *tbuffer1 = osi_AllocSmallSpace(AFS_SMALLOCSIZ), *cnamep = 0;
-#if defined(AFS_SGI61_ENV) || defined(AFS_SUN57_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
-       size_t bufferSize;      
-#else /* AFS_SGI61_ENV */
-       u_int bufferSize;       
-#endif /* AFS_SGI61_ENV */
        int cflags = parm4;
 
        /* wait for basic init */
@@ -325,8 +340,8 @@ long parm, parm2, parm3, parm4, parm5, parm6;
                    }
                }
                if (!code)
-                   afs_NewCell(tbuffer1, tcell.hosts, cflags, 
-                               lcnamep, 0, 0, 0, 0);
+                   code = afs_NewCell(tbuffer1, tcell.hosts, cflags,
+                                      lcnamep, 0, 0, 0);
            }
        }
        osi_FreeSmallSpace(tbuffer);
@@ -338,34 +353,32 @@ long parm, parm2, parm3, parm4, parm5, parm6;
         * parm2 is the alias name
         * parm3 is the real cell name
         */
-#if defined(AFS_SGI61_ENV) || defined(AFS_SUN57_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
-       size_t bufferSize;
-#else /* AFS_SGI61_ENV */
-       u_int bufferSize;       
-#endif /* AFS_SGI61_ENV */
        char *aliasName = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
        char *cellName = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
 
        AFS_COPYINSTR((char *)parm2, aliasName, AFS_SMALLOCSIZ, &bufferSize, code);
        if (!code) AFS_COPYINSTR((char *)parm3, cellName, AFS_SMALLOCSIZ, &bufferSize, code);
-       if (!code) afs_NewCell(aliasName,       /* new entry name */
-                              0,               /* host list */
-                              CAlias,          /* flags */
-                              NULL,    /* linked cell */
-                              0, 0,            /* fs & vl ports */
-                              0,               /* timeout */
-                              cellName);       /* real cell name */
-
+       if (!code) afs_NewCellAlias(aliasName, cellName);
        osi_FreeSmallSpace(aliasName);
        osi_FreeSmallSpace(cellName);
     }
+    else if (parm == AFSOP_SET_THISCELL) {
+       /*
+        * Call arguments:
+        * parm2 is the primary cell name
+        */
+       char *cell = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
+
+       AFS_COPYINSTR((char *) parm2, cell, AFS_SMALLOCSIZ, &bufferSize, code);
+       if (!code)
+           afs_SetPrimaryCell(cell);
+       osi_FreeSmallSpace(cell);
+    }
     else if (parm == AFSOP_CACHEINIT) {
        struct afs_cacheParams cparms;
 
        if (afs_CacheInit_Done) goto out;
 
-       /* wait for basic init */
-       while (afs_initState < AFSOP_START_BKG) afs_osi_Sleep(&afs_initState);
        AFS_COPYIN((char *)parm2, (caddr_t) &cparms, sizeof(cparms), code);
        if (code) {
 #if    defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined (AFS_SGI64_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
@@ -414,12 +427,6 @@ long parm, parm2, parm3, parm4, parm5, parm6;
        code = afs_InitCacheFile(NULL, ainode);
     }
     else if (parm == AFSOP_ROOTVOLUME) {
-#if defined(AFS_SGI61_ENV) || defined(AFS_SUN57_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
-       size_t bufferSize;
-#else /* AFS_SGI61_ENV */
-       u_int bufferSize;
-#endif /* AFS_SGI61_ENV */
-
        /* wait for basic init */
        while (afs_initState < AFSOP_START_BKG) afs_osi_Sleep(&afs_initState);
 
@@ -429,29 +436,31 @@ long parm, parm2, parm3, parm4, parm5, parm6;
        }
        else code = 0;
     }
-    else if (parm == AFSOP_CACHEFILE || parm == AFSOP_CACHEINFO ||
-             parm == AFSOP_VOLUMEINFO || parm == AFSOP_AFSLOG) {
+    else if (parm == AFSOP_CACHEFILE ||
+            parm == AFSOP_CACHEINFO ||
+            parm == AFSOP_VOLUMEINFO ||
+            parm == AFSOP_AFSLOG ||
+            parm == AFSOP_CELLINFO) {
        char *tbuffer = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
-#if defined(AFS_SGI61_ENV) || defined(AFS_SUN57_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
-       size_t bufferSize;
-#else /* AFS_SGI61_ENV */
-       u_int bufferSize;
-#endif /* AFS_SGI61_ENV */
 
-       /* wait for basic init */
-       while (afs_initState < AFSOP_START_BKG) afs_osi_Sleep(&afs_initState);
        code = 0;
-       AFS_COPYINSTR((char *)parm2, tbuffer, AFS_SMALLOCSIZ, &bufferSize, code);
+       AFS_COPYINSTR((char *) parm2, tbuffer, AFS_SMALLOCSIZ,
+                     &bufferSize, code);
        if (code) {
            osi_FreeSmallSpace(tbuffer);
            goto out;
        }
        if (!code) {
-           tbuffer[AFS_SMALLOCSIZ-1] = 0;      /* null-terminate the name */
-           /* we now have the cache dir copied in.  Call the cache init routines */
-           if (parm == AFSOP_CACHEFILE) code = afs_InitCacheFile(tbuffer, 0);
-           else if (parm == AFSOP_CACHEINFO) code = afs_InitCacheInfo(tbuffer);
-           else if (parm == AFSOP_VOLUMEINFO) code = afs_InitVolumeInfo(tbuffer);
+           tbuffer[AFS_SMALLOCSIZ-1] = '\0';   /* null-terminate the name */
+           /* We have the cache dir copied in.  Call the cache init routine */
+           if (parm == AFSOP_CACHEFILE)
+               code = afs_InitCacheFile(tbuffer, 0);
+           else if (parm == AFSOP_CACHEINFO)
+               code = afs_InitCacheInfo(tbuffer);
+           else if (parm == AFSOP_VOLUMEINFO)
+               code = afs_InitVolumeInfo(tbuffer);
+           else if (parm == AFSOP_CELLINFO)
+               code = afs_InitCellInfo(tbuffer);
        }
        osi_FreeSmallSpace(tbuffer);
     }
@@ -657,7 +666,7 @@ long parm, parm2, parm3, parm4, parm5, parm6;
        AFS_COPYIN((afs_int32 *)parm2, cellname, cellLen, code);
        AFS_COPYIN((afs_int32 *)parm3, kmsg, kmsgLen, code);
        if (!code) {
-           code = afs_AfsdbHandler(cellname, cellLen, kmsg);
+           code = afs_AFSDBHandler(cellname, cellLen, kmsg);
            if (*cellname == 1) *cellname = 0;
            if (code == -2) {   /* Shutting down? */
                *cellname = 1;
@@ -1281,7 +1290,7 @@ void afs_shutdown(void)
     }
 #ifdef AFS_AFSDB_ENV
     afs_warn("AFSDB... ");
-    afs_StopAfsdb();
+    afs_StopAFSDB();
     while (afs_termState == AFSOP_STOP_AFSDB)
        afs_osi_Sleep(&afs_termState);
 #endif
index 475b147..7873c82 100644 (file)
@@ -1118,7 +1118,7 @@ int SRXAFSCB_GetCellServDB(struct rx_call *a_call, afs_int32 a_index,
     RX_AFS_GLOCK();
     AFS_STATCNT(SRXAFSCB_GetCellServDB);
 
-    tcell = afs_GetCellByIndex(a_index, READ_LOCK, 0);
+    tcell = afs_GetCellByIndex(a_index, READ_LOCK);
 
     if (!tcell) {
        i = 0;
@@ -1178,7 +1178,6 @@ int SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name)
 {
     int plen;
     struct cell *tcell;
-    struct afs_q *cq, *tq;
     char *t_name, *p_name = NULL;
 
     RX_AFS_GLOCK();
@@ -1187,27 +1186,16 @@ int SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name)
     /* Search the list for the primary cell. Cell number 1 is only
      * the primary cell is when no other cell is explicitly marked as
      * the primary cell.  */
-    ObtainReadLock(&afs_xcell);
-
-    for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
-        tq = QNext(cq);
-       tcell = QTOC(cq);
-       if (tcell->states & CPrimary) {
-           p_name = tcell->cellName;
-           break;
-       }
-        if (tcell->cell == 1) {
-           p_name = tcell->cellName;
-       }
-    }
-
+    tcell = afs_GetPrimaryCell(READ_LOCK);
+    if (tcell)
+       p_name = tcell->cellName;
     if (p_name)
        plen = strlen(p_name);
     else
        plen = 0;
     t_name = (char *)afs_osi_Alloc(plen+1);
     if (t_name == NULL) {
-       ReleaseReadLock(&afs_xcell);
+       if (tcell) afs_PutCell(tcell, READ_LOCK);
        RX_AFS_GUNLOCK();
        return ENOMEM;
     }
@@ -1216,11 +1204,10 @@ int SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name)
     if (p_name)
        memcpy(t_name, p_name, plen);
 
-    ReleaseReadLock(&afs_xcell);
-
     RX_AFS_GUNLOCK();
 
     *a_name = t_name;
+    if (tcell) afs_PutCell(tcell, READ_LOCK);
     return 0;
 }
 
@@ -1386,3 +1373,63 @@ int SRXAFSCB_StoreData(struct rx_call *rxcall, struct AFSFid *Fid, afs_int32 Fd,
 {
     return ENOSYS;
 }
+
+/*------------------------------------------------------------------------
+ * EXPORTED SRXAFSCB_GetCellByNum
+ *
+ * Description:
+ *     Routine to get information about a cell specified by its
+ *     cell number (returned by GetCE/GetCE64).
+ *
+ * Arguments:
+ *     a_call    : Ptr to Rx call on which this request came in.
+ *     a_cellnum : Input cell number
+ *     a_name    : Output cell name (one zero byte when no such cell).
+ *     a_hosts   : Output cell database servers in host byte order.
+ *
+ * Returns:
+ *     0 on success
+ *
+ * Environment:
+ *     Nothing interesting.
+ *
+ * Side Effects:
+ *     As advertised.
+ *------------------------------------------------------------------------*/
+
+int SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_cellnum,
+    char **a_name, serverList *a_hosts)
+{
+    afs_int32 i, sn;
+    struct cell *tcell;
+
+    RX_AFS_GLOCK();
+    AFS_STATCNT(SRXAFSCB_GetCellByNum);
+
+    a_hosts->serverList_val = 0;
+    a_hosts->serverList_len = 0;
+
+    tcell = afs_GetCellStale(a_cellnum, READ_LOCK);
+    if (!tcell) {
+       *a_name = afs_strdup("");
+       RX_AFS_GUNLOCK();
+       return 0;
+    }
+
+    ObtainReadLock(&tcell->lock);
+    *a_name = afs_strdup(tcell->cellName);
+
+    for (sn = 0; sn < AFSMAXCELLHOSTS && tcell->cellHosts[sn]; sn++) 
+       ;
+    a_hosts->serverList_len = sn;
+    a_hosts->serverList_val = (afs_int32 *) afs_osi_Alloc(sn*sizeof(afs_int32));
+
+    for (i = 0; i < sn; i++)
+       a_hosts->serverList_val[i] = ntohl(tcell->cellHosts[i]->addr->sa_ip);
+    ReleaseReadLock(&tcell->lock);
+    afs_PutCell(tcell, READ_LOCK);
+
+    RX_AFS_GUNLOCK();
+    return 0;
+}
index 058b42f..5f97e4f 100644 (file)
@@ -17,476 +17,675 @@ RCSID("$Header$");
 
 #include "../afs/stds.h"
 #include "../afs/sysincludes.h"        /* Standard vendor system headers */
-
-#if !defined(UKERNEL)
-#include <net/if.h>
-#include <netinet/in.h>
-
-#ifdef AFS_SGI62_ENV
-#include "../h/hashing.h"
-#endif
-#if !defined(AFS_HPUX110_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN60_ENV)
-#include <netinet/in_var.h>
-#endif /* ! ASF_HPUX110_ENV */
-#endif /* !defined(UKERNEL) */
-
 #include "../afs/afsincludes.h"        /* Afs-based standard headers */
 #include "../afs/afs_stats.h"   /* afs statistics */
-
-#if    defined(AFS_SUN56_ENV)
-#include <inet/led.h>
-#include <inet/common.h>
-#if     defined(AFS_SUN58_ENV)
-#include <netinet/ip6.h>
-#endif
-#include <inet/ip.h>
-#endif
-
-/* Exported variables */
-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;
+#include "../afs/afs_osi.h"
 
 /* Local variables. */
-struct cell *afs_rootcell = 0;
-
-/* Handler waiting for request from client */
-static int afs_AfsdbHandlerWait;
-/* Client waiting for handler to become available or finish request */
-static int afs_AfsdbLookupWait;
-
-/* Set to 1 when we've seen the userspace AFSDB process at least once */
-char afs_AfsdbHandlerPresent = 0;
-/* Set to 1 when there is a client interacting with the AFSDB handler.
- * Protects the in and out variables below.  Protected by GLOCK. */
-char afs_AfsdbHandlerInuse = 0;
-/* Set to 1 when AFSDB has been shut down */
-char afs_AfsdbHandlerShutdown = 0;
-
-/* Input to handler from the client: cell name to look up */
-char *afs_AfsdbHandler_CellName;
-/* Outputs from handler to client: cell hosts, TTL, and real cell name */
-afs_int32 *afs_AfsdbHandler_CellHosts;
-int *afs_AfsdbHandler_Timeout;
-char **afs_AfsdbHandler_RealName;
-
-/* Client sets ReqPending to 1 whenever it queues a request for it */
-char afs_AfsdbHandler_ReqPending = 0;
-/* Handler sets Completed to 1 when it completes the client request */
-char afs_AfsdbHandler_Completed = 0;
+afs_rwlock_t afs_xcell;                /* Export for cmdebug peeking at locks */
+
+/*
+ * AFSDB implementation:
+ *
+ * afs_StopAFSDB: terminate the AFSDB handler, used on shutdown
+ * afs_AFSDBHandler: entry point for user-space AFSDB request handler
+ * afs_GetCellHostsAFSDB: query the AFSDB handler and wait for response
+ * afs_LookupAFSDB: look up AFSDB for given cell name and create locally
+ */
 
 #ifdef AFS_AFSDB_ENV
-void afs_StopAfsdb(void)
+static afs_rwlock_t afsdb_client_lock; /* Serializes client requests */
+static char afsdb_handler_running;     /* Protected by GLOCK */
+static char afsdb_handler_shutdown;    /* Protected by GLOCK */
+
+static struct {
+    afs_rwlock_t lock;
+    char pending;
+    char complete;
+    char *cellname;
+    afs_int32 *cellhosts;
+    int *timeout;
+    char **realname;
+} afsdb_req;
+
+void afs_StopAFSDB()
 {
-    if (afs_AfsdbHandlerPresent) {
-       afs_osi_Wakeup(&afs_AfsdbHandlerWait);
+    if (afsdb_handler_running) {
+       afs_osi_Wakeup(&afsdb_req);
     } else {
-       afs_AfsdbHandlerShutdown = 1;
+       afsdb_handler_shutdown = 1;
        afs_termState = AFSOP_STOP_RXEVENT;
     }
 }
 
-int afs_AfsdbHandler(char *acellName, int acellNameLen, afs_int32 *kernelMsg)
+int afs_AFSDBHandler(char *acellName, int acellNameLen, afs_int32 *kernelMsg)
 {
-    /* afs_syscall_call() has already grabbed the global lock */
-
-    if (afs_AfsdbHandlerShutdown) return -2;
-    afs_AfsdbHandlerPresent = 1;
+    if (afsdb_handler_shutdown) return -2;
+    afsdb_handler_running = 1;
 
-    if (afs_AfsdbHandler_ReqPending) {
+    ObtainSharedLock(&afsdb_req.lock, 683);
+    if (afsdb_req.pending) {
        int i, hostCount;
 
+       UpgradeSToWLock(&afsdb_req.lock, 684);
        hostCount = kernelMsg[0];
-       *afs_AfsdbHandler_Timeout = kernelMsg[1];
-       if (*afs_AfsdbHandler_Timeout) *afs_AfsdbHandler_Timeout += osi_Time();
-
-       *afs_AfsdbHandler_RealName = afs_osi_Alloc(strlen(acellName) + 1);
-       strcpy(*afs_AfsdbHandler_RealName, acellName);
+       *afsdb_req.timeout = kernelMsg[1];
+       if (*afsdb_req.timeout) *afsdb_req.timeout += osi_Time();
+       *afsdb_req.realname = afs_strdup(acellName);
 
        for (i=0; i<MAXCELLHOSTS; i++) {
            if (i >= hostCount)
-               afs_AfsdbHandler_CellHosts[i] = 0;
+               afsdb_req.cellhosts[i] = 0;
            else
-               afs_AfsdbHandler_CellHosts[i] = kernelMsg[2+i];
+               afsdb_req.cellhosts[i] = kernelMsg[2+i];
        }
 
        /* Request completed, wake up the relevant thread */
-       afs_AfsdbHandler_ReqPending = 0;
-       afs_AfsdbHandler_Completed = 1;
-       afs_osi_Wakeup(&afs_AfsdbLookupWait);
+       afsdb_req.pending = 0;
+       afsdb_req.complete = 1;
+       afs_osi_Wakeup(&afsdb_req);
+       ConvertWToSLock(&afsdb_req.lock);
     }
+    ConvertSToRLock(&afsdb_req.lock);
 
     /* Wait for a request */
-    while (afs_AfsdbHandler_ReqPending == 0 && afs_termState != AFSOP_STOP_AFSDB)
-       afs_osi_Sleep(&afs_AfsdbHandlerWait);
+    while (afsdb_req.pending == 0 && afs_termState != AFSOP_STOP_AFSDB) {
+       ReleaseReadLock(&afsdb_req.lock);
+       afs_osi_Sleep(&afsdb_req);
+       ObtainReadLock(&afsdb_req.lock);
+    }
 
     /* Check if we're shutting down */
     if (afs_termState == AFSOP_STOP_AFSDB) {
+       ReleaseReadLock(&afsdb_req.lock);
+
        /* Inform anyone waiting for us that we're going away */
-       afs_AfsdbHandlerShutdown = 1;
-       afs_AfsdbHandlerPresent = 0;
-       afs_osi_Wakeup(&afs_AfsdbLookupWait);
+       afsdb_handler_shutdown = 1;
+       afsdb_handler_running = 0;
+       afs_osi_Wakeup(&afsdb_req);
 
        afs_termState = AFSOP_STOP_RXEVENT;
        afs_osi_Wakeup(&afs_termState);
        return -2;
     }
 
-    /* Copy the requested cell name into the request buffer */
-    strncpy(acellName, afs_AfsdbHandler_CellName, acellNameLen);
-
     /* Return the lookup request to userspace */    
+    strncpy(acellName, afsdb_req.cellname, acellNameLen);
+    ReleaseReadLock(&afsdb_req.lock);
     return 0;
 }
-#endif
-
 
-int afs_GetCellHostsFromDns(char *acellName, afs_int32 *acellHosts, 
+static int afs_GetCellHostsAFSDB(char *acellName, afs_int32 *acellHosts,
        int *timeout, char **realName)
 {
-#ifdef AFS_AFSDB_ENV
-    char grab_glock = 0;
+    AFS_ASSERT_GLOCK();
+    if (!afsdb_handler_running) return ENOENT;
 
-    if (!afs_AfsdbHandlerPresent) return ENOENT;
+    ObtainWriteLock(&afsdb_client_lock, 685);
+    ObtainWriteLock(&afsdb_req.lock, 686);
 
-    /* Initialize host list to empty in case the handler is gone */
     *acellHosts = 0;
+    afsdb_req.cellname = acellName;
+    afsdb_req.cellhosts = acellHosts;
+    afsdb_req.timeout = timeout;
+    afsdb_req.realname = realName;
+
+    afsdb_req.complete = 0;
+    afsdb_req.pending = 1;
+    afs_osi_Wakeup(&afsdb_req);
+    ConvertWToRLock(&afsdb_req.lock);
+
+    while (afsdb_handler_running && !afsdb_req.complete) {
+       ReleaseReadLock(&afsdb_req.lock);
+       afs_osi_Sleep(&afsdb_req);
+       ObtainReadLock(&afsdb_req.lock);
+    };
+    ReleaseReadLock(&afsdb_req.lock);
+    ReleaseWriteLock(&afsdb_client_lock);
+
+    if (*acellHosts)
+       return 0;
+    else
+       return ENOENT;
+}
+#endif
 
-    if (!ISAFS_GLOCK()) {
-       grab_glock = 1;
-       AFS_GLOCK();
-    }
+void afs_LookupAFSDB(char *acellName)
+{
+#ifdef AFS_AFSDB_ENV
+    afs_int32 cellHosts[MAXCELLHOSTS];
+    char *realName = NULL;
+    struct cell *tc;
+    int code, timeout;
+    
+    code = afs_GetCellHostsAFSDB(acellName, cellHosts, &timeout, &realName);
+    if (code) goto done;
+    code = afs_NewCell(realName, cellHosts, CNoSUID, NULL, 0, 0, timeout);
+    if (code) goto done;
 
-    /* Wait until the AFSDB handler is available, and grab it */
-    while (afs_AfsdbHandlerInuse)
-       afs_osi_Sleep(&afs_AfsdbLookupWait);
-    afs_AfsdbHandlerInuse = 1;
+    /* If we found an alias, create it */
+    if (afs_strcasecmp(acellName, realName))
+       afs_NewCellAlias(acellName, realName);
 
-    /* Set up parameters for the handler */
-    afs_AfsdbHandler_CellName = acellName;
-    afs_AfsdbHandler_CellHosts = acellHosts;
-    afs_AfsdbHandler_Timeout = timeout;
-    afs_AfsdbHandler_RealName = realName;
+done:
+    if (realName)
+       afs_osi_FreeStr(realName);
+#endif
+}
 
-    /* Wake up the AFSDB handler */
-    afs_AfsdbHandler_Completed = 0;
-    afs_AfsdbHandler_ReqPending = 1;
-    afs_osi_Wakeup(&afs_AfsdbHandlerWait);
+/*
+ * Cell name-to-ID mapping
+ *
+ * afs_cellname_new: create a new cell name, optional cell number
+ * afs_cellname_lookup_id: look up a cell name
+ * afs_cellname_lookup_name: look up a cell number
+ * afs_cellname_ref: note that this cell name was referenced somewhere
+ * afs_cellname_init: load the list of cells from given inode
+ * afs_cellname_write: write in-kernel list of cells to disk
+ */
+
+struct cell_name *afs_cellname_head;   /* Export for kdump */
+static ino_t afs_cellname_inode;
+static int afs_cellname_inode_set;
+static int afs_cellname_dirty;
+static afs_int32 afs_cellnum_next;
 
-    /* Wait for the handler to get back to us with the reply */
-    while (afs_AfsdbHandlerPresent && !afs_AfsdbHandler_Completed)
-       afs_osi_Sleep(&afs_AfsdbLookupWait);
+static struct cell_name *afs_cellname_new(char *name, afs_int32 cellnum)
+{
+    struct cell_name *cn;
 
-    /* Release the AFSDB handler and wake up others waiting for it */
-    afs_AfsdbHandlerInuse = 0;
-    afs_osi_Wakeup(&afs_AfsdbLookupWait);
+    if (cellnum == 0)
+       cellnum = afs_cellnum_next;
 
-    if (grab_glock) AFS_GUNLOCK();
+    cn = (struct cell_name *) afs_osi_Alloc(sizeof(*cn));
+    cn->next = afs_cellname_head;
+    cn->cellnum = cellnum;
+    cn->cellname = afs_strdup(name);
+    cn->used = 0;
+    afs_cellname_head = cn;
 
-    if (*acellHosts) return 0;
-    return ENOENT;
-#else
-    return ENOENT;
-#endif
+    if (cellnum >= afs_cellnum_next)
+       afs_cellnum_next = cellnum + 1;
+
+    return cn;
 }
 
+static struct cell_name *afs_cellname_lookup_id(afs_int32 cellnum)
+{
+    struct cell_name *cn;
+
+    for (cn = afs_cellname_head; cn; cn = cn->next)
+       if (cn->cellnum == cellnum)
+           return cn;
 
-void afs_RefreshCell(register struct cell *ac)
+    return NULL;
+}
+
+static struct cell_name *afs_cellname_lookup_name(char *name)
 {
-    afs_int32 cellHosts[MAXCELLHOSTS];
-    char *realName = NULL;
-    struct cell *tc;
-    int timeout;
-
-    if (ac->cellHosts[0])      /* If we already have some servers.. */
-       if (!ac->timeout || ac->timeout > osi_Time())
-                               /* Don't refresh if not expired */
-           return;
-
-    if (afs_GetCellHostsFromDns(ac->cellName, cellHosts, &timeout, &realName))
-       /* In case of lookup failure, keep old data */
-       goto done;
-
-    /* Refresh the DB servers for the real cell; other values stay the same. */
-    afs_NewCell(realName, cellHosts, 0, NULL, 0, 0, timeout, NULL);
-
-    /* If this is an alias, update the alias entry too */
-    if (afs_strcasecmp(ac->cellName, realName)) {
-       /*
-        * Look up the entry we just updated, to compensate for
-        * uppercase-vs-lowercase lossage with DNS.
-        */
-       tc = afs_FindCellByName(realName, READ_LOCK);
-
-       if (tc) {
-           afs_NewCell(ac->cellName, 0, CAlias, NULL, 0, 0,
-                       timeout, tc->cellName);
-           afs_PutCell(tc, READ_LOCK);
-       }
-    }
+    struct cell_name *cn;
 
-done:
-    if (realName)
-       afs_osi_Free(realName, strlen(realName) + 1);
+    for (cn = afs_cellname_head; cn; cn = cn->next)
+       if (strcmp(cn->cellname, name) == 0)
+           return cn;
+
+    return NULL;
 }
 
+static void afs_cellname_ref(struct cell_name *cn)
+{
+    if (!cn->used) {
+       cn->used = 1;
+       afs_cellname_dirty = 1;
+    }
+}
 
-struct cell *afs_GetCellByName_Dns(register char *acellName, afs_int32 locktype)
+int afs_cellname_init(ino_t inode, int lookupcode)
 {
-    afs_int32 cellHosts[MAXCELLHOSTS];
-    char *realName = NULL;
-    struct cell *tc;
-    int timeout;
+    struct osi_file *tfile;
+    int cc, off = 0;
 
-    if (afs_GetCellHostsFromDns(acellName, cellHosts, &timeout, &realName))
-       goto bad;
-    if (afs_NewCell(realName, cellHosts, CNoSUID, NULL, 0, 0,
-                   timeout, NULL))
-       goto bad;
+    ObtainWriteLock(&afs_xcell, 692);
 
-    /* If this is an alias, create an entry for it too */
-    if (afs_strcasecmp(acellName, realName)) {
-       /*
-        * Look up the entry we just updated, to compensate for
-        * uppercase-vs-lowercase lossage with DNS.
-        */
-       tc = afs_FindCellByName(realName, READ_LOCK);
-       if (!tc)
-           goto bad;
+    afs_cellnum_next = 1;
+    afs_cellname_dirty = 0;
 
-       if (afs_NewCell(acellName, 0, CAlias, NULL, 0, 0,
-                       timeout, tc->cellName)) {
-           afs_PutCell(tc, READ_LOCK);
-           goto bad;
+    if (cacheDiskType == AFS_FCACHE_TYPE_MEM) {
+       ReleaseWriteLock(&afs_xcell);
+       return 0;
+    }
+    if (lookupcode) {
+       ReleaseWriteLock(&afs_xcell);
+       return lookupcode;
+    }
+
+    tfile = osi_UFSOpen(inode);
+    if (!tfile) {
+       ReleaseWriteLock(&afs_xcell);
+       return EIO;
+    }
+
+    afs_cellname_inode = inode;
+    afs_cellname_inode_set = 1;
+
+    while (1) {
+       afs_int32 cellnum, clen, magic;
+       struct cell_name *cn;
+       char *cellname;
+
+       cc = afs_osi_Read(tfile, off, &magic, sizeof(magic));
+       if (cc != sizeof(magic))
+           break;
+       if (magic != AFS_CELLINFO_MAGIC)
+           break;
+       off += cc;
+
+       cc = afs_osi_Read(tfile, off, &cellnum, sizeof(cellnum));
+       if (cc != sizeof(cellnum))
+           break;
+       off += cc;
+
+       cc = afs_osi_Read(tfile, off, &clen, sizeof(clen));
+       if (cc != sizeof(clen))
+           break;
+       off += cc;
+
+       cellname = afs_osi_Alloc(clen + 1);
+       if (!cellname)
+           break;
+
+       cc = afs_osi_Read(tfile, off, cellname, clen);
+       if (cc != clen) {
+           afs_osi_Free(cellname, clen + 1);
+           break;
        }
+       off += cc;
+       cellname[clen] = '\0';
 
-       afs_PutCell(tc, READ_LOCK);
+       if (afs_cellname_lookup_name(cellname) ||
+           afs_cellname_lookup_id(cellnum)) {
+           afs_osi_Free(cellname, clen + 1);
+           break;
+       }
+
+       cn = afs_cellname_new(cellname, cellnum);
+       afs_osi_Free(cellname, clen + 1);
     }
 
-    if (realName)
-       afs_osi_Free(realName, strlen(realName) + 1);
-    return afs_FindCellByName(acellName, locktype);
+    osi_UFSClose(tfile);
+    ReleaseWriteLock(&afs_xcell);
+    return 0;
+}
 
-bad:
-    if (realName)
-       afs_osi_Free(realName, strlen(realName) + 1);
-    return NULL;
+int afs_cellname_write()
+{
+    struct osi_file *tfile;
+    struct cell_name *cn;
+    int code, off;
+
+    if (!afs_cellname_dirty || !afs_cellname_inode_set)
+       return 0;
+    if (afs_initState != 300)
+       return 0;
+
+    ObtainWriteLock(&afs_xcell, 693);
+    afs_cellname_dirty = 0;
+    off = 0;
+    tfile = osi_UFSOpen(afs_cellname_inode);
+    if (!tfile) {
+       ReleaseWriteLock(&afs_xcell);
+       return EIO;
+    }
+
+    for (cn = afs_cellname_head; cn; cn = cn->next) {
+       afs_int32 magic, cellnum, clen;
+       int cc;
+
+       if (!cn->used)
+           continue;
+
+       magic = AFS_CELLINFO_MAGIC;
+       cc = afs_osi_Write(tfile, off, &magic, sizeof(magic));
+       if (cc != sizeof(magic))
+           break;
+       off += cc;
+
+       cellnum = cn->cellnum;
+       cc = afs_osi_Write(tfile, off, &cellnum, sizeof(cellnum));
+       if (cc != sizeof(cellnum))
+           break;
+       off += cc;
+
+       clen = strlen(cn->cellname);
+       cc = afs_osi_Write(tfile, off, &clen, sizeof(clen));
+       if (cc != sizeof(clen))
+           break;
+       off += cc;
+
+       cc = afs_osi_Write(tfile, off, cn->cellname, clen);
+       if (cc != clen)
+           break;
+       off += clen;
+    }
+
+    osi_UFSClose(tfile);
+    ReleaseWriteLock(&afs_xcell);
+    return 0;
 }
 
+/*
+ * Cell alias implementation
+ *
+ * afs_FindCellAlias: look up cell alias by alias name
+ * afs_GetCellAlias: get cell alias by index (starting at 0)
+ * afs_PutCellAlias: put back a cell alias returned by Find or Get
+ * afs_NewCellAlias: create new cell alias entry
+ */
 
-struct cell *afs_FindCellByName(register char *acellName, afs_int32 locktype)
+struct cell_alias *afs_cellalias_head; /* Export for kdump */
+static afs_int32 afs_cellalias_index;
+static int afs_CellOrAliasExists_nl(char *aname);  /* Forward declaration */
+
+static struct cell_alias *afs_FindCellAlias(char *alias)
 {
-    register struct cell *tc;
-    register struct afs_q *cq, *tq;
-    int didAlias = 0;
+    struct cell_alias *tc;
 
-    AFS_STATCNT(afs_GetCellByName);
-retry:
-    ObtainWriteLock(&afs_xcell,100);
-    for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
-       tc = QTOC(cq); tq = QNext(cq);
-       if (!afs_strcasecmp(tc->cellName, acellName)) {
-           QRemove(&tc->lruq);
-           QAdd(&CellLRU, &tc->lruq);
-           ReleaseWriteLock(&afs_xcell);
-           afs_RefreshCell(tc);
-           if ((tc->states & CAlias) && (didAlias == 0)) {
-               acellName = tc->realName;
-               if (!acellName) return NULL;
-               didAlias = 1;
-               goto retry;
-           }
-           return tc;
-       }
+    for (tc = afs_cellalias_head; tc != NULL; tc = tc->next)
+       if (!strcmp(alias, tc->alias))
+           break;
+    return tc;
+}
+
+struct cell_alias *afs_GetCellAlias(int index)
+{
+    struct cell_alias *tc;
+
+    ObtainReadLock(&afs_xcell);
+    for (tc = afs_cellalias_head; tc != NULL; tc = tc->next)
+       if (tc->index == index)
+           break;
+    ReleaseReadLock(&afs_xcell);
+
+    return tc;
+}
+
+void afs_PutCellAlias(struct cell_alias *a)
+{
+    return;
+}
+
+afs_int32 afs_NewCellAlias(char *alias, char *cell)
+{
+    struct cell_alias *tc;
+
+    ObtainSharedLock(&afs_xcell, 681);
+    if (afs_CellOrAliasExists_nl(alias)) {
+       ReleaseSharedLock(&afs_xcell);
+       return EEXIST;
     }
 
+    UpgradeSToWLock(&afs_xcell, 682);
+    tc = (struct cell_alias *) afs_osi_Alloc(sizeof(struct cell_alias));
+    tc->alias = afs_strdup(alias);
+    tc->cell = afs_strdup(cell);
+    tc->next = afs_cellalias_head;
+    tc->index = afs_cellalias_index++;
+    afs_cellalias_head = tc;
     ReleaseWriteLock(&afs_xcell);
-    return NULL;
+
+    afs_DynrootInvalidate();
+    return 0;
 }
 
-struct cell *afs_GetCellByName(register char *acellName, afs_int32 locktype)
+/*
+ * Actual cell list implementation
+ *
+ * afs_UpdateCellLRU: bump given cell up to the front of the LRU queue
+ * afs_RefreshCell: look up cell information in AFSDB if timeout expired
+ *
+ * afs_TraverseCells: execute a callback for each existing cell
+ * afs_TraverseCells_nl: same as above except without locking afs_xcell
+ * afs_choose_cell_by_{name,num,index}: useful traversal callbacks
+ *
+ * afs_FindCellByName: return a cell with a given name, if it exists
+ * afs_FindCellByName_nl: same as above, without locking afs_xcell
+ * afs_GetCellByName: same as FindCellByName but tries AFSDB if not found
+ * afs_GetCell: return a cell with a given cell number
+ * afs_GetCellStale: same as GetCell, but does not try to refresh the data
+ * afs_GetCellByIndex: return a cell with a given index number (starting at 0)
+ *
+ * afs_GetPrimaryCell: return the primary cell, if any
+ * afs_IsPrimaryCell: returns true iff the given cell is the primary cell
+ * afs_IsPrimaryCellNum: returns afs_IsPrimaryCell(afs_GetCell(cellnum))
+ * afs_SetPrimaryCell: set the primary cell name to the given cell name
+ *
+ * afs_NewCell: create or update a cell entry
+ */
+
+struct afs_q CellLRU;          /* Export for kdump */
+static char *afs_thiscell;
+static afs_int32 afs_cellindex;
+
+static void afs_UpdateCellLRU(struct cell *c)
 {
-    struct cell *tc;
+    ObtainWriteLock(&afs_xcell, 100);
+    QRemove(&c->lruq);
+    QAdd(&CellLRU, &c->lruq);
+    ReleaseWriteLock(&afs_xcell);
+}
 
-    tc = afs_FindCellByName(acellName, locktype);
-    if (!tc)
-       tc = afs_GetCellByName_Dns(acellName, locktype);
-  
-    return tc;
+static void afs_RefreshCell(struct cell *ac)
+{
+    if (ac->states & CNoAFSDB)
+       return;
+    if (!ac->cellHosts[0] || (ac->timeout && ac->timeout <= osi_Time()))
+       afs_LookupAFSDB(ac->cellName);
 }
 
-static struct cell *afs_GetCellInternal(register afs_int32 acell, 
-       afs_int32 locktype, int holdxcell)
+static void *afs_TraverseCells_nl(void *(*cb)(struct cell *, void *), void *arg)
 {
-    register struct cell *tc;
-    register struct afs_q *cq, *tq;
+    struct afs_q *cq, *tq;
+    struct cell *tc;
+    void *ret = NULL;
 
-    AFS_STATCNT(afs_GetCell);
-    if (acell == 1 && afs_rootcell) return afs_rootcell;
-    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);
-           if (holdxcell)
-               ReleaseWriteLock(&afs_xcell);
-           afs_RefreshCell(tc);
-           return tc;
-       }
+       ret = cb(tc, arg);
+       if (ret) break;
     }
-    if (holdxcell)
-       ReleaseWriteLock(&afs_xcell);
-    return NULL;
 
+    return ret;
 }
 
-struct cell *afs_GetCell(register afs_int32 acell, afs_int32 locktype)
+void *afs_TraverseCells(void *(*cb)(struct cell *, void *), void *arg)
 {
-    return afs_GetCellInternal(acell, locktype, 1);
+    void *ret;
+
+    ObtainReadLock(&afs_xcell);
+    ret = afs_TraverseCells_nl(cb, arg);
+    ReleaseReadLock(&afs_xcell);
+
+    return ret;
 }
 
-/* This is only to be called if the caller is already holding afs_xcell */
-struct cell *afs_GetCellNoLock(register afs_int32 acell, afs_int32 locktype)
+static void *afs_choose_cell_by_name(struct cell *cell, void *arg)
 {
-    return afs_GetCellInternal(acell, locktype, 0);
+    return strcmp(cell->cellName, (char *) arg) ? NULL : cell;
 }
 
-struct cell *afs_GetCellByIndex(register afs_int32 cellindex, 
-       afs_int32 locktype, afs_int32 refresh)
+static void *afs_choose_cell_by_num(struct cell *cell, void *arg)
 {
-    register struct cell *tc;
-    register struct afs_q *cq, *tq;
+    return (cell->cellNum == *((afs_int32 *) arg)) ? cell : NULL;
+}
 
-    AFS_STATCNT(afs_GetCellByIndex);
-    ObtainWriteLock(&afs_xcell,102);
-    for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
-       tc = QTOC(cq); tq = QNext(cq);
-       if (tc->cellIndex == cellindex) {
-           QRemove(&tc->lruq);
-           QAdd(&CellLRU, &tc->lruq);
-           ReleaseWriteLock(&afs_xcell);
-           if (refresh) afs_RefreshCell(tc);
-           return tc;
-       }
+static void *afs_choose_cell_by_index(struct cell *cell, void *arg)
+{
+    return (cell->cellIndex == *((afs_int32 *) arg)) ? cell : NULL;
+}
+
+static struct cell *afs_FindCellByName_nl(char *acellName, afs_int32 locktype)
+{
+    return afs_TraverseCells_nl(&afs_choose_cell_by_name, acellName);
+}
+
+static struct cell *afs_FindCellByName(char *acellName, afs_int32 locktype)
+{
+    return afs_TraverseCells(&afs_choose_cell_by_name, acellName);
+}
+
+struct cell *afs_GetCellByName(char *acellName, afs_int32 locktype)
+{
+    struct cell *tc;
+
+    tc = afs_FindCellByName(acellName, locktype);
+    if (!tc) {
+       afs_LookupAFSDB(acellName);
+       tc = afs_FindCellByName(acellName, locktype);
+    }
+    if (tc) {
+       afs_cellname_ref(tc->cnamep);
+       afs_UpdateCellLRU(tc);
+       afs_RefreshCell(tc);
     }
-    ReleaseWriteLock(&afs_xcell);
-    return NULL;
 
+    return tc;
 }
 
+struct cell *afs_GetCell(afs_int32 cellnum, afs_int32 locktype)
+{
+    struct cell *tc;
+    struct cell_name *cn;
 
-struct cell *afs_GetRealCellByIndex(register afs_int32 cellindex, afs_int32 locktype, afs_int32 refresh)
+    tc = afs_GetCellStale(cellnum, locktype);
+    if (tc) {
+       afs_RefreshCell(tc);
+    } else {
+       ObtainReadLock(&afs_xcell);
+       cn = afs_cellname_lookup_id(cellnum);
+       ReleaseReadLock(&afs_xcell);
+       if (cn)
+           tc = afs_GetCellByName(cn->cellname, locktype);
+    }
+    return tc;
+}
+
+struct cell *afs_GetCellStale(afs_int32 cellnum, afs_int32 locktype)
 {
-    register struct cell *tc;
-    register struct afs_q *cq, *tq;
+    struct cell *tc;
 
-    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;
-       }
+    tc = afs_TraverseCells(&afs_choose_cell_by_num, &cellnum);
+    if (tc) {
+       afs_cellname_ref(tc->cnamep);
+       afs_UpdateCellLRU(tc);
     }
-    ReleaseWriteLock(&afs_xcell);
-    return NULL;
-} /*afs_GetRealCellByIndex*/
+    return tc;
+}
+
+struct cell *afs_GetCellByIndex(afs_int32 index, afs_int32 locktype)
+{
+    struct cell *tc;
 
+    tc = afs_TraverseCells(&afs_choose_cell_by_index, &index);
+    if (tc)
+       afs_UpdateCellLRU(tc);
+    return tc;
+}
 
-afs_int32 afs_NewCell(char *acellName, register afs_int32 *acellHosts, int aflags, 
-       char *linkedcname, u_short fsport, u_short vlport, int timeout, char *aliasFor)
+struct cell *afs_GetPrimaryCell(afs_int32 locktype)
 {
-    register struct cell *tc, *tcl=0;
-    register afs_int32 i, newc=0, code=0;
-    register struct afs_q *cq, *tq;
+    return afs_GetCellByName(afs_thiscell, locktype);
+}
 
-    AFS_STATCNT(afs_NewCell);
+int afs_IsPrimaryCell(struct cell *cell)
+{
+    return strcmp(cell->cellName, afs_thiscell) ? 0 : 1;
+}
 
-    ObtainWriteLock(&afs_xcell,103);
+int afs_IsPrimaryCellNum(afs_int32 cellnum)
+{
+    struct cell *tc;
+    int primary = 0;
 
-    /* Find the cell and mark its servers as not down but gone */
-    for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
-       tc = QTOC(cq); tq = QNext(cq);
-       if (afs_strcasecmp(tc->cellName, acellName) == 0) {
-           /* If the cell we've found has the correct name but no timeout,
-            * and we're called with a non-zero timeout, bail out:  never
-            * override static configuration entries with AFSDB ones.
-            * One exception: if the original cell entry had no servers,
-            * it must get servers from AFSDB.
-            */
-           if (timeout && !tc->timeout && tc->cellHosts[0]) {
-               ReleaseWriteLock(&afs_xcell);
-               return 0;
-           }
-           /* we don't want to keep pinging old vlservers which were down,
-            * since they don't matter any more.  It's easier to do this than
-            * to remove the server from its various hash tables. */
-           for (i=0; i<MAXCELLHOSTS; i++) {
-               if (!tc->cellHosts[i]) break;
-               tc->cellHosts[i]->flags &= ~SRVR_ISDOWN;
-               tc->cellHosts[i]->flags |= SRVR_ISGONE;
-           }
-           break;
-       }
+    tc = afs_GetCellStale(cellnum, READ_LOCK);
+    if (tc) {
+       primary = afs_IsPrimaryCell(tc);
+       afs_PutCell(tc, READ_LOCK);
     }
 
-    if (cq != &CellLRU) {
+    return primary;
+}
+
+afs_int32 afs_SetPrimaryCell(char *acellName)
+{
+    ObtainWriteLock(&afs_xcell, 691);
+    if (afs_thiscell)
+       afs_osi_FreeStr(afs_thiscell);
+    afs_thiscell = afs_strdup(acellName);
+    ReleaseWriteLock(&afs_xcell);
+    return 0;
+}
+
+afs_int32 afs_NewCell(char *acellName, afs_int32 *acellHosts, int aflags,
+       char *linkedcname, u_short fsport, u_short vlport, int timeout)
+{
+    struct cell *tc, *tcl=0;
+    afs_int32 i, newc=0, code=0;
+
+    AFS_STATCNT(afs_NewCell);
+
+    ObtainWriteLock(&afs_xcell, 103);
+
+    tc = afs_FindCellByName_nl(acellName, READ_LOCK);
+    if (tc) {
        aflags &= ~CNoSUID;
-    }
-    else {
+    } else {
        tc = (struct cell *) afs_osi_Alloc(sizeof(struct cell));
-       memset((char *)tc, 0, sizeof(*tc));
-       QAdd(&CellLRU, &tc->lruq);                      /* put in lruq */
-       tc->cellName = (char *) afs_osi_Alloc(strlen(acellName)+1);
-       strcpy(tc->cellName, acellName);
-       tc->cellIndex = afs_cellindex++;
-       if (aflags & CPrimary) {
-           extern int afs_rootCellIndex;
-           tc->cell = 1;       /* primary cell is always 1 */
-           afs_rootcell = tc;
-           afs_rootCellIndex = tc->cellIndex;
-       } else {
-           tc->cell = afs_nextCellNum++;
-       }
-       tc->states = 0;
-       tc->lcellp = NULL;
-       tc->fsport = (fsport ? fsport : AFS_FSPORT);
-       tc->vlport = (vlport ? vlport : AFS_VLPORT);
-       afs_stats_cmperf.numCellsVisible++;
-       newc++;
-       if (!(aflags & CAlias)) {
-           tc->realcellIndex = afs_realcellindex++;
-       } else {
-           tc->realcellIndex = -1;
-       }
+       memset((char *) tc, 0, sizeof(*tc));
+       tc->cellName = afs_strdup(acellName);
+       tc->fsport = AFS_FSPORT;
+       tc->vlport = AFS_VLPORT;
+       RWLOCK_INIT(&tc->lock, "cell lock");
+       newc = 1;
+       if (afs_thiscell && !strcmp(acellName, afs_thiscell))
+           aflags &= ~CNoSUID;
+    }
+    ObtainWriteLock(&tc->lock, 688);
+
+    /* If the cell we've found has the correct name but no timeout,
+     * and we're called with a non-zero timeout, bail out:  never
+     * override static configuration entries with AFSDB ones.
+     * One exception: if the original cell entry had no servers,
+     * it must get servers from AFSDB.
+     */
+    if (timeout && !tc->timeout && tc->cellHosts[0]) {
+       code = EINVAL;
+       goto bad;
+    }
+
+    /* we don't want to keep pinging old vlservers which were down,
+     * since they don't matter any more.  It's easier to do this than
+     * to remove the server from its various hash tables. */
+    for (i=0; i<MAXCELLHOSTS; i++) {
+       if (!tc->cellHosts[i]) break;
+       tc->cellHosts[i]->flags &= ~SRVR_ISDOWN;
+       tc->cellHosts[i]->flags |= SRVR_ISGONE;
     }
 
+    if (fsport) tc->fsport = fsport;
+    if (vlport) tc->vlport = vlport;
+
     if (aflags & CLinkedCell) {
        if (!linkedcname) {
            code = EINVAL;
            goto bad;
        }
-       for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
-           tcl = QTOC(cq); tq = QNext(cq);
-           if (!afs_strcasecmp(tcl->cellName, linkedcname)) {
-               break;
-           }
-           tcl = 0;
-       }
+       tcl = afs_FindCellByName_nl(linkedcname, READ_LOCK);
        if (!tcl) {
            code = ENOENT;
            goto bad;
        }
        if (tcl->lcellp) {      /* XXX Overwriting if one existed before! XXX */
-           tcl->lcellp->lcellp = NULL;
+           tcl->lcellp->lcellp = (struct cell *)0;
            tcl->lcellp->states &= ~CLinkedCell;
        }
        tc->lcellp = tcl;
@@ -495,70 +694,154 @@ afs_int32 afs_NewCell(char *acellName, register afs_int32 *acellHosts, int aflag
     tc->states |= aflags;
     tc->timeout = timeout;
 
-    /* Allow converting an alias into a real cell */
-    if ((!(aflags & CAlias)) && (tc->states & CAlias)) {
-       tc->states &= ~CAlias;
-       tc->realcellIndex = afs_realcellindex++;
-    }
     memset((char *)tc->cellHosts, 0, sizeof(tc->cellHosts));
-    if (aflags & CAlias) {
-       if (!aliasFor) {
-           code = EINVAL;
-           goto bad;
-       }
-       if (tc->realName) afs_osi_Free(tc->realName, strlen(tc->realName)+1);
-       tc->realName = (char *) afs_osi_Alloc(strlen(aliasFor)+1);
-       strcpy(tc->realName, aliasFor);
-       goto done;
-    }
-
     for (i=0; i<MAXCELLHOSTS; i++) {
-        struct server *ts;
+       struct server *ts;
        afs_uint32 temp = acellHosts[i];
        if (!temp) break;
-       ts = afs_GetServer(&temp, 1, 0, tc->vlport, WRITE_LOCK, (afsUUID *)0, 0);
-        ts->cell = tc;
+       ts = afs_GetServer(&temp, 1, 0, tc->vlport, WRITE_LOCK, NULL, 0);
+       ts->cell = tc;
        ts->flags &= ~SRVR_ISGONE;
        tc->cellHosts[i] = ts;
        afs_PutServer(ts, WRITE_LOCK);
     }
     afs_SortServers(tc->cellHosts, MAXCELLHOSTS);      /* randomize servers */
-done:
+
+    if (newc) {
+       struct cell_name *cn;
+
+       cn = afs_cellname_lookup_name(acellName);
+       if (!cn)
+           cn = afs_cellname_new(acellName, 0);
+
+       tc->cnamep = cn;
+       tc->cellNum = cn->cellnum;
+       tc->cellIndex = afs_cellindex++;
+       afs_stats_cmperf.numCellsVisible++;
+       QAdd(&CellLRU, &tc->lruq);
+    }
+
+    ReleaseWriteLock(&tc->lock);
     ReleaseWriteLock(&afs_xcell);
+    afs_PutCell(tc, 0);
+    afs_DynrootInvalidate();
     return 0;
+
 bad:
     if (newc) {
-       QRemove(&tc->lruq);
-       afs_osi_Free(tc->cellName, strlen(tc->cellName)+1);
-       afs_osi_Free((char *)tc, sizeof(struct cell));
+       afs_osi_FreeStr(tc->cellName);
+       afs_osi_Free(tc, sizeof(struct cell));
     }
+    ReleaseWriteLock(&tc->lock);
     ReleaseWriteLock(&afs_xcell);
     return code;
 }
 
+/*
+ * Miscellaneous stuff
+ *
+ * afs_CellInit: perform whatever initialization is necessary
+ * shutdown_cell: called on shutdown, should deallocate memory, etc
+ * afs_RemoveCellEntry: remove a server from a cell's server list
+ * afs_CellOrAliasExists: check if the given name exists as a cell or alias
+ * afs_CellOrAliasExists_nl: same as above without locking afs_xcell
+ * afs_CellNumValid: check if a cell number is valid (also set the used flag)
+ */
+
+void afs_CellInit()
+{
+    RWLOCK_INIT(&afs_xcell, "afs_xcell");
+#ifdef AFS_AFSDB_ENV
+    RWLOCK_INIT(&afsdb_req.lock, "afsdb_req.lock");
+#endif
+    QInit(&CellLRU);
+
+    afs_cellindex = 0;
+    afs_cellalias_index = 0;
+}
+
+void shutdown_cell()
+{
+    struct afs_q *cq, *tq;
+    struct cell *tc;
+
+    RWLOCK_INIT(&afs_xcell, "afs_xcell");
+
+    for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
+       tc = QTOC(cq); tq = QNext(cq);
+       if (tc->cellName) afs_osi_FreeStr(tc->cellName);
+       afs_osi_Free(tc, sizeof(struct cell));
+    }
+    QInit(&CellLRU);
+}
+
 void afs_RemoveCellEntry(struct server *srvp)
 {
-  struct cell *tc;
-  afs_int32 j, k;
-
-  tc = srvp->cell;
-  if (!tc) return;
-
-  /* Remove the server structure from the cell list - if there */
-  ObtainWriteLock(&afs_xcell,200);
-  for (j=k=0; j<MAXCELLHOSTS; j++) {
-     if (!tc->cellHosts[j]) break;
-     if (tc->cellHosts[j] != srvp) {
-        tc->cellHosts[k++] = tc->cellHosts[j];
-     }
-  }
-  if (k == 0) {
-     /* What do we do if we remove the last one? */
-  }
-  for (; k<MAXCELLHOSTS; k++) {
-     tc->cellHosts[k] = 0;
-  }
-  ReleaseWriteLock(&afs_xcell);
+    struct cell *tc;
+    afs_int32 j, k;
+
+    tc = srvp->cell;
+    if (!tc) return;
+
+    /* Remove the server structure from the cell list - if there */
+    ObtainWriteLock(&tc->lock, 200);
+    for (j=k=0; j<MAXCELLHOSTS; j++) {
+       if (!tc->cellHosts[j]) break;
+       if (tc->cellHosts[j] != srvp) {
+           tc->cellHosts[k++] = tc->cellHosts[j];
+       }
+    }
+    if (k == 0) {
+       /* What do we do if we remove the last one? */
+    }
+    for (; k<MAXCELLHOSTS; k++) {
+       tc->cellHosts[k] = 0;
+    }
+    ReleaseWriteLock(&tc->lock);
 }
 
+static int afs_CellOrAliasExists_nl(char *aname)
+{
+    struct cell *c;
+    struct cell_alias *ca;
+
+    c = afs_FindCellByName_nl(aname, READ_LOCK);
+    if (c) {
+       afs_PutCell(c, READ_LOCK);
+       return 1;
+    }
+
+    ca = afs_FindCellAlias(aname);
+    if (ca) {
+       afs_PutCellAlias(ca);
+       return 1;
+    }
+
+    return 0;
+}
+
+int afs_CellOrAliasExists(char *aname)
+{
+    int ret;
+
+    ObtainReadLock(&afs_xcell);
+    ret = afs_CellOrAliasExists_nl(aname);
+    ReleaseReadLock(&afs_xcell);
+
+    return ret;
+}
+
+int afs_CellNumValid(afs_int32 cellnum)
+{
+    struct cell_name *cn;
+
+    ObtainReadLock(&afs_xcell);
+    cn = afs_cellname_lookup_id(cellnum);
+    ReleaseReadLock(&afs_xcell);
+    if (cn) {
+       cn->used = 1;
+       return 1;
+    } else {
+       return 0;
+    }
+}
index 310c568..b628379 100644 (file)
@@ -262,36 +262,46 @@ void afs_Daemon(void)
 int afs_CheckRootVolume (void)
 {
     char rootVolName[32];
-    register struct volume *tvp;
+    struct volume *tvp = NULL;
     int usingDynroot = afs_GetDynrootEnable();
+    int localcell;
 
     AFS_STATCNT(afs_CheckRootVolume);
     if (*afs_rootVolumeName == 0) {
        strcpy(rootVolName, "root.afs");
-    }
-    else {
+    } else {
        strcpy(rootVolName, afs_rootVolumeName);
     }
+
+    if (!usingDynroot) {
+       struct cell *lc = afs_GetPrimaryCell(READ_LOCK);
+
+       if (!lc)
+           return ENOENT;
+       localcell = lc->cellNum;
+       afs_PutCell(lc, READ_LOCK);
+    }
+
     if (usingDynroot) {
        afs_GetDynrootFid(&afs_rootFid);
        tvp = afs_GetVolume(&afs_rootFid, NULL, READ_LOCK);
     } else {
-       tvp = afs_GetVolumeByName(rootVolName, LOCALCELL, 1, NULL, READ_LOCK);
+       tvp = afs_GetVolumeByName(rootVolName, localcell, 1, NULL, READ_LOCK);
     }
-    if (!tvp) {
+    if (!tvp && !usingDynroot) {
        char buf[128];
        int len = strlen(rootVolName);
 
        if ((len < 9) || strcmp(&rootVolName[len - 9], ".readonly")) {
            strcpy(buf, rootVolName);
            afs_strcat(buf, ".readonly");
-           tvp = afs_GetVolumeByName(buf, LOCALCELL, 1, NULL, READ_LOCK);
+           tvp = afs_GetVolumeByName(buf, localcell, 1, NULL, READ_LOCK);
        }
     }
     if (tvp) {
        if (!usingDynroot) {
            int volid = (tvp->roVol? tvp->roVol : tvp->volume);
-           afs_rootFid.Cell = LOCALCELL;
+           afs_rootFid.Cell = localcell;
            if (afs_rootFid.Fid.Volume && afs_rootFid.Fid.Volume != volid
                && afs_globalVp) {
                /* If we had a root fid before and it changed location we reset
index 4472298..b3033e8 100644 (file)
@@ -2392,7 +2392,7 @@ done:
     /*
      * See if this was a reference to a file in the local cell.
      */
-    if (avc->fid.Cell == LOCALCELL)
+    if (afs_IsPrimaryCellNum(avc->fid.Cell))
        afs_stats_cmperf.dlocalAccesses++;
     else
        afs_stats_cmperf.dremoteAccesses++;
@@ -2680,6 +2680,7 @@ struct dcache *afs_UFSGetDSlot(register afs_int32 aslot, register struct dcache
     register afs_int32 code;
     register struct dcache *tdc;
     int existing = 0;
+    int entryok;
 
     AFS_STATCNT(afs_UFSGetDSlot);
     if (CheckLock(&afs_xdcache) != -1) osi_Panic("getdslot nolock");
@@ -2727,9 +2728,16 @@ struct dcache *afs_UFSGetDSlot(register afs_int32 aslot, register struct dcache
     /*
       * Seek to the aslot'th entry and read it in.
       */
-    code = afs_osi_Read(afs_cacheInodep, sizeof(struct fcache) * aslot + sizeof(struct afs_fheader),
-                   (char *)(&tdc->f), sizeof(struct fcache));
-    if (code != sizeof(struct fcache)) {
+    code = afs_osi_Read(afs_cacheInodep, sizeof(struct fcache) * aslot +
+                                        sizeof(struct afs_fheader),
+                       (char *)(&tdc->f), sizeof(struct fcache));
+    entryok = 1;
+    if (code != sizeof(struct fcache))
+       entryok = 0;
+    if (!afs_CellNumValid(tdc->f.fid.Cell))
+       entryok = 0;
+
+    if (!entryok) {
        tdc->f.fid.Cell = 0;
        tdc->f.fid.Fid.Volume = 0;
        tdc->f.chunk = -1;
@@ -2796,8 +2804,10 @@ int afs_WriteDCache(register struct dcache *adc, int atime)
     /*
      * Seek to the right dcache slot and write the in-memory image out to disk.
      */
-    code = afs_osi_Write(afs_cacheInodep, sizeof(struct fcache) * adc->index + sizeof(struct afs_fheader), 
-                    (char *)(&adc->f), sizeof(struct fcache));
+    afs_cellname_write();
+    code = afs_osi_Write(afs_cacheInodep, sizeof(struct fcache) * adc->index +
+                                         sizeof(struct afs_fheader), 
+                        (char *)(&adc->f), sizeof(struct fcache));
     if (code != sizeof(struct fcache)) return EIO;
     return 0;
 }
index ffbcf85..892a63d 100644 (file)
@@ -14,7 +14,7 @@
  * afs_IsDynrootFid
  * afs_GetDynrootFid
  * afs_IsDynroot
- * afs_RefreshDynroot
+ * afs_DynrootInvalidate
  * afs_GetDynroot
  * afs_PutDynroot
  * afs_DynrootNewVnode
@@ -38,7 +38,7 @@
 #include "../afs/prs_fs.h"
 #include "../afs/dir.h"
 
-#define AFS_DYNROOT_CELL       1
+#define AFS_DYNROOT_CELLNAME   "dynroot"
 #define AFS_DYNROOT_VOLUME     1
 #define AFS_DYNROOT_VNODE      1
 #define AFS_DYNROOT_UNIQUE     1
@@ -48,7 +48,8 @@
  * and a type-specific identifier in the lower 24 bits.
  */
 #define VN_TYPE_CELL           0x01    /* Corresponds to a struct cell */
-#define VN_TYPE_SYMLINK                0x02    /* User-created symlink in /afs */
+#define VN_TYPE_ALIAS          0x02    /* Corresponds to a struct cell_alias */
+#define VN_TYPE_SYMLINK                0x03    /* User-created symlink in /afs */
 
 #define VNUM_TO_VNTYPE(vnum)   ((vnum) >> 24)
 #define VNUM_TO_VNID(vnum)     ((vnum) & 0x00ffffff)
 #define VNUM_FROM_CIDX_RW(cidx, rw) \
                                VNUM_FROM_TYPEID(VN_TYPE_CELL, \
                                                 ((cidx) << 2 | (rw) << 1))
+#define VNUM_FROM_CAIDX_RW(caidx, rw) \
+                               VNUM_FROM_TYPEID(VN_TYPE_ALIAS, \
+                                                ((caidx) << 2 | (rw) << 1))
 
 static int afs_dynrootEnable = 0;
+static int afs_dynrootCell = 0;
 
 static afs_rwlock_t afs_dynrootDirLock;
 /* Start of variables protected by afs_dynrootDirLock */
 static char *afs_dynrootDir = NULL;
 static int afs_dynrootDirLen;
 static int afs_dynrootDirLinkcnt;
-static int afs_dynrootCellCount;
+static int afs_dynrootDirVersion;
 static int afs_dynrootVersion = 1;
 static int afs_dynrootVersionHigh = 1;
 /* End of variables protected by afs_dynrootDirLock */
@@ -87,13 +92,38 @@ static int afs_dynSymlinkIndex = 0;
 /* End of variables protected by afs_dynSymlinkLock */
 
 /*
+ * Set up a cell for dynroot if it's not there yet.
+ */
+static int afs_dynrootCellInit()
+{
+    if (afs_dynrootEnable && !afs_dynrootCell) {
+       afs_int32 cellHosts[MAXCELLHOSTS];
+       struct cell *tc;
+       int code;
+
+       memset(cellHosts, 0, sizeof(cellHosts));
+       code = afs_NewCell(AFS_DYNROOT_CELLNAME, cellHosts, CNoSUID | CNoAFSDB,
+                          NULL, 0, 0, 0);
+       if (code)
+           return code;
+       tc = afs_GetCellByName(AFS_DYNROOT_CELLNAME, READ_LOCK);
+       if (!tc)
+           return ENODEV;
+       afs_dynrootCell = tc->cellNum;
+       afs_PutCell(tc, READ_LOCK);
+    }
+
+    return 0;
+}
+
+/*
  * Returns non-zero iff fid corresponds to the top of the dynroot volume.
  */
 int afs_IsDynrootFid(struct VenusFid *fid)
 {
     return
        (afs_dynrootEnable &&
-        fid->Cell       == AFS_DYNROOT_CELL   &&
+        fid->Cell       == afs_dynrootCell    &&
         fid->Fid.Volume == AFS_DYNROOT_VOLUME &&
         fid->Fid.Vnode  == AFS_DYNROOT_VNODE  &&
         fid->Fid.Unique == AFS_DYNROOT_UNIQUE);
@@ -104,7 +134,7 @@ int afs_IsDynrootFid(struct VenusFid *fid)
  */
 void afs_GetDynrootFid(struct VenusFid *fid) 
 {
-    fid->Cell       = AFS_DYNROOT_CELL;
+    fid->Cell       = afs_dynrootCell;
     fid->Fid.Volume = AFS_DYNROOT_VOLUME;
     fid->Fid.Vnode  = AFS_DYNROOT_VNODE;
     fid->Fid.Unique = AFS_DYNROOT_UNIQUE;
@@ -185,28 +215,59 @@ static void afs_dynroot_addDirEnt(struct DirHeader *dirHeader,
 }
 
 /*
+ * Invalidate the /afs vnode for dynroot; called when the underlying
+ * directory has changed and needs to be re-read.
+ */
+void afs_DynrootInvalidate(void)
+{
+    afs_int32 retry;
+    struct vcache *tvc;
+    struct VenusFid tfid;
+
+    if (!afs_dynrootEnable)
+       return;
+
+    ObtainWriteLock(&afs_dynrootDirLock, 687);
+    afs_dynrootVersion++;
+    afs_dynrootVersionHigh = osi_Time();
+    ReleaseWriteLock(&afs_dynrootDirLock);
+
+    afs_GetDynrootFid(&tfid);
+    do {
+       retry = 0;
+       ObtainReadLock(&afs_xvcache);
+       tvc = afs_FindVCache(&tfid, &retry, 0);
+       ReleaseReadLock(&afs_xvcache);
+    } while (retry);
+    if (tvc) {
+       tvc->states &= ~(CStatd | CUnique);
+       osi_dnlc_purgedp(tvc);
+       afs_PutVCache(tvc);
+    }
+}
+
+/*
  * Regenerates the dynroot contents from the current list of
  * cells.  Useful when the list of cells has changed due to
  * an AFSDB lookup, for instance.
  */
-void afs_RefreshDynroot(void)
+static void afs_RebuildDynroot(void)
 {
     int cellidx, maxcellidx, i;
+    int aliasidx, maxaliasidx;
     struct cell *c;
+    struct cell_alias *ca;
     int curChunk, curPage;
     int dirSize, sizeOfCurEntry;
     char *newDir, *dotCell;
     struct DirHeader *dirHeader;
-    int doFlush = 0;
     int linkCount = 0;
     struct afs_dynSymlink *ts;
-    int newCellCount;
+    int newVersion;
 
-    /*
-     * Save afs_cellindex here, in case it changes between the
-     * two loops.
-     */
-    maxcellidx = afs_cellindex;
+    ObtainReadLock(&afs_dynrootDirLock);
+    newVersion = afs_dynrootVersion;
+    ReleaseReadLock(&afs_dynrootDirLock);
 
     /*
      * Compute the amount of space we need for the fake dir
@@ -217,9 +278,10 @@ void afs_RefreshDynroot(void)
     /* Reserve space for "." and ".." */
     curChunk += 2;
 
-    for (cellidx = 0; cellidx < maxcellidx; cellidx++) {
-       c = afs_GetCellByIndex(cellidx, READ_LOCK, 0 /* don't refresh */);
-       if (!c) continue;
+    for (cellidx = 0; ; cellidx++) {
+       c = afs_GetCellByIndex(cellidx, READ_LOCK);
+       if (!c) break;
+       if (c->cellNum == afs_dynrootCell) continue;
 
        sizeOfCurEntry = afs_dir_NameBlobs(c->cellName);
        if (curChunk + sizeOfCurEntry > EPP) {
@@ -240,6 +302,32 @@ void afs_RefreshDynroot(void)
 
        afs_PutCell(c, READ_LOCK);
     }
+    maxcellidx = cellidx;
+
+    for (aliasidx = 0; ; aliasidx++) {
+       ca = afs_GetCellAlias(aliasidx);
+       if (!ca) break;
+
+       sizeOfCurEntry = afs_dir_NameBlobs(ca->alias);
+       if (curChunk + sizeOfCurEntry > EPP) {
+           curPage++;
+           curChunk = 1;
+       }
+       curChunk += sizeOfCurEntry;
+
+       dotCell = afs_osi_Alloc(strlen(ca->alias) + 2);
+       strcpy(dotCell, ".");
+       strcat(dotCell, ca->alias);
+       sizeOfCurEntry = afs_dir_NameBlobs(dotCell);
+       if (curChunk + sizeOfCurEntry > EPP) {
+           curPage++;
+           curChunk = 1;
+       }
+       curChunk += sizeOfCurEntry;
+
+       afs_PutCellAlias(ca);
+    }
+    maxaliasidx = aliasidx;
 
     ObtainReadLock(&afs_dynSymlinkLock);
     ts = afs_dynSymlinkBase;
@@ -283,8 +371,9 @@ void afs_RefreshDynroot(void)
     linkCount += 2;
 
     for (cellidx = 0; cellidx < maxcellidx; cellidx++) {
-       c = afs_GetCellByIndex(cellidx, READ_LOCK, 0 /* don't refresh */);
+       c = afs_GetCellByIndex(cellidx, READ_LOCK);
        if (!c) continue;
+       if (c->cellNum == afs_dynrootCell) continue;
 
        dotCell = afs_osi_Alloc(strlen(c->cellName) + 2);
        strcpy(dotCell, ".");
@@ -294,10 +383,24 @@ void afs_RefreshDynroot(void)
        afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk,
                              dotCell, VNUM_FROM_CIDX_RW(cellidx, 1));
 
-       if (!(c->states & CAlias)) linkCount += 2;
+       linkCount += 2;
        afs_PutCell(c, READ_LOCK);
     }
 
+    for (aliasidx = 0; aliasidx < maxaliasidx; aliasidx++) {
+       ca = afs_GetCellAlias(aliasidx);
+       if (!ca) continue;
+
+       dotCell = afs_osi_Alloc(strlen(ca->alias) + 2);
+       strcpy(dotCell, ".");
+       strcat(dotCell, ca->alias);
+       afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk,
+                             ca->alias, VNUM_FROM_CAIDX_RW(aliasidx, 0));
+       afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk,
+                             dotCell, VNUM_FROM_CAIDX_RW(aliasidx, 1));
+       afs_PutCellAlias(ca);
+    }
+
     ts = afs_dynSymlinkBase;
     while (ts) {
        int vnum = VNUM_FROM_TYPEID(VN_TYPE_SYMLINK, ts->index);
@@ -306,7 +409,6 @@ void afs_RefreshDynroot(void)
        ts = ts->next;
     }
 
-    newCellCount = maxcellidx + afs_dynSymlinkIndex;
     ReleaseReadLock(&afs_dynSymlinkLock);
 
     ObtainWriteLock(&afs_dynrootDirLock, 549);
@@ -314,47 +416,21 @@ void afs_RefreshDynroot(void)
     afs_dynrootDir = newDir;
     afs_dynrootDirLen = dirSize;
     afs_dynrootDirLinkcnt = linkCount;
-    if (afs_dynrootCellCount != newCellCount) {
-       /*
-        * New cells/symlinks added -- bump data version, invalidate vcache.
-        */
-       afs_dynrootCellCount = newCellCount;
-       afs_dynrootVersion++;
-       afs_dynrootVersionHigh = osi_Time();
-       doFlush = 1;
-    }
+    afs_dynrootDirVersion = newVersion;
     ReleaseWriteLock(&afs_dynrootDirLock);
-
-    if (doFlush) {
-       afs_int32 retry;
-       struct vcache *tvc;
-       struct VenusFid tfid;
-
-       afs_GetDynrootFid(&tfid);
-       do {
-           retry = 0;
-           ObtainReadLock(&afs_xvcache);
-           tvc = afs_FindVCache(&tfid, &retry, 0);
-           ReleaseReadLock(&afs_xvcache);
-       } while (retry);
-       if (tvc) {
-           tvc->states &= ~(CStatd | CUnique);
-           osi_dnlc_purgedp(tvc);
-           afs_PutVCache(tvc);
-       }
-    }
 }
 
 /*
  * Returns a pointer to the base of the dynroot directory in memory,
  * length thereof, and a FetchStatus.
  */
-void afs_GetDynroot(char **dynrootDir, int *dynrootLen, struct AFSFetchStatus *status)
+void afs_GetDynroot(char **dynrootDir, int *dynrootLen,
+       struct AFSFetchStatus *status)
 {
     ObtainReadLock(&afs_dynrootDirLock);
-    if (!afs_dynrootDir) {
+    if (!afs_dynrootDir || afs_dynrootDirVersion != afs_dynrootVersion) {
        ReleaseReadLock(&afs_dynrootDirLock);
-       afs_RefreshDynroot();
+       afs_RebuildDynroot();
        ObtainReadLock(&afs_dynrootDirLock);
     }
 
@@ -402,10 +478,11 @@ int afs_DynrootNewVnode(struct vcache *avc, struct AFSFetchStatus *status)
     /*
      * Check if this is an entry under /afs, e.g. /afs/cellname.
      */
-    if (avc->fid.Cell       == AFS_DYNROOT_CELL &&
+    if (avc->fid.Cell       == afs_dynrootCell &&
        avc->fid.Fid.Volume == AFS_DYNROOT_VOLUME) {
 
        struct cell *c;
+       struct cell_alias *ca;
        int namelen, linklen, cellidx, rw;
 
        memset(status, 0, sizeof(struct AFSFetchStatus));
@@ -442,7 +519,8 @@ int afs_DynrootNewVnode(struct vcache *avc, struct AFSFetchStatus *status)
            return ts ? 1 : 0;
        }
 
-       if (VNUM_TO_VNTYPE(avc->fid.Fid.Vnode) != VN_TYPE_CELL) {
+       if (VNUM_TO_VNTYPE(avc->fid.Fid.Vnode) != VN_TYPE_CELL &&
+           VNUM_TO_VNTYPE(avc->fid.Fid.Vnode) != VN_TYPE_ALIAS) {
            afs_warn("dynroot vnode inconsistency, unknown VNTYPE %d\n",
                     VNUM_TO_VNTYPE(avc->fid.Fid.Vnode));
            return 0;
@@ -451,26 +529,26 @@ int afs_DynrootNewVnode(struct vcache *avc, struct AFSFetchStatus *status)
        cellidx = VNUM_TO_CIDX(avc->fid.Fid.Vnode);
        rw = VNUM_TO_RW(avc->fid.Fid.Vnode);
 
-       c = afs_GetCellByIndex(cellidx, READ_LOCK, 1 /* refresh */);
-       if (!c) {
-           afs_warn("dynroot vnode inconsistency, can't find cell %d\n",
-                    cellidx);
-           return 0;
-       }
+       if (VNUM_TO_VNTYPE(avc->fid.Fid.Vnode) == VN_TYPE_ALIAS) {
+           char *realName;
+
+           ca = afs_GetCellAlias(cellidx);
+           if (!ca) {
+               afs_warn("dynroot vnode inconsistency, can't find alias %d\n",
+                        cellidx);
+               return 0;
+           }
 
-       if (c->states & CAlias) {
            /*
             * linkData needs to contain the name of the cell
             * we're aliasing for.
             */
-           char *realName = c->realName;
-
+           realName = ca->cell;
            if (!realName) {
                afs_warn("dynroot: alias %s missing real cell name\n",
-                        c->cellName);
+                        ca->alias);
+               avc->linkData = afs_strdup("unknown");
                linklen = 7;
-               avc->linkData = afs_osi_Alloc(linklen + 1);
-               strcpy(avc->linkData, "unknown");
            } else {
                int namelen = strlen(realName);
                linklen = rw + namelen;
@@ -480,7 +558,15 @@ int afs_DynrootNewVnode(struct vcache *avc, struct AFSFetchStatus *status)
            }
 
            status->UnixModeBits = 0755;
+           afs_PutCellAlias(ca);
        } else {
+           c = afs_GetCellByIndex(cellidx, READ_LOCK);
+           if (!c) {
+               afs_warn("dynroot vnode inconsistency, can't find cell %d\n",
+                        cellidx);
+               return 0;
+           }
+
            /*
             * linkData needs to contain "#cell:root.cell" or "%cell:root.cell"
             */
@@ -492,10 +578,10 @@ int afs_DynrootNewVnode(struct vcache *avc, struct AFSFetchStatus *status)
            strcat(avc->linkData, ":root.cell");
 
            status->UnixModeBits = 0644;
+           afs_PutCell(c, READ_LOCK);
        }
 
        status->Length = linklen;
-       afs_PutCell(c, READ_LOCK);
        return 1;
     }
 
@@ -508,7 +594,7 @@ int afs_DynrootNewVnode(struct vcache *avc, struct AFSFetchStatus *status)
 int afs_SetDynrootEnable(int enable)
 {
     afs_dynrootEnable = enable;
-    return 0;
+    return afs_dynrootCellInit();
 }
 
 /*
@@ -522,11 +608,11 @@ int afs_GetDynrootEnable(void)
 /*
  * Remove a temporary symlink entry from /afs.
  */
-int afs_DynrootVOPRemove(struct vcache *avc, struct AFS_UCRED *acred, char *aname)
+int afs_DynrootVOPRemove(struct vcache *avc, struct AFS_UCRED *acred,
+       char *aname)
 {
     struct afs_dynSymlink **tpps;
     struct afs_dynSymlink *tps;
-    struct cell *c;
     int found = 0;
 
     if (acred->cr_uid)
@@ -549,18 +635,14 @@ int afs_DynrootVOPRemove(struct vcache *avc, struct AFS_UCRED *acred, char *anam
     }
     ReleaseWriteLock(&afs_dynSymlinkLock);
     if (found) {
-       afs_RefreshDynroot();
+       afs_DynrootInvalidate();
        return 0;
     }
 
-    /* Check if this is an actual cell? */
-    c = afs_FindCellByName(aname, READ_LOCK);
-    if (c) {
-       afs_PutCell(c, READ_LOCK);
+    if (afs_CellOrAliasExists(aname))
        return EROFS;
-    } else {
+    else
        return ENOENT;
-    }
 }
 
 /*
@@ -570,17 +652,11 @@ int afs_DynrootVOPSymlink(struct vcache *avc, struct AFS_UCRED *acred,
        char *aname, char *atargetName)
 {
     struct afs_dynSymlink *tps;
-    struct cell *c;
 
     if (acred->cr_uid)
        return EPERM;
-
-    /* Check if it's already a cell */
-    c = afs_FindCellByName(aname, READ_LOCK);
-    if (c) {
-       afs_PutCell(c, READ_LOCK);
+    if (afs_CellOrAliasExists(aname))
        return EEXIST;
-    }
 
     /* Check if it's already a symlink */
     ObtainWriteLock(&afs_dynSymlinkLock, 91);
@@ -604,6 +680,6 @@ int afs_DynrootVOPSymlink(struct vcache *avc, struct AFS_UCRED *acred,
     afs_dynSymlinkBase = tps;
     ReleaseWriteLock(&afs_dynSymlinkLock);
 
-    afs_RefreshDynroot();
+    afs_DynrootInvalidate();
     return 0;
 }
index 26c7869..2f6d0dd 100644 (file)
@@ -228,33 +228,50 @@ void afs_ComputeCacheParms(void)
  *     WARNING: Data will be written to this file over time by AFS.
  */
 
-int afs_InitVolumeInfo(register char *afile)
+static int LookupInodeByPath(char *filename, ino_t *inode)
 {
     afs_int32 code;
-    struct osi_file *tfile;
-    struct vnode *filevp;
-    struct fcache fce;
 
-    AFS_STATCNT(afs_InitVolumeInfo);
 #ifdef AFS_LINUX22_ENV
-    {
-       struct dentry *dp;
-       code = gop_lookupname(afile, AFS_UIOSYS, 0, NULL, &dp);
-       if (code) return ENOENT;
-       fce.inode = volumeInode = dp->d_inode->i_ino;
-       dput(dp);
-    }
+    struct dentry *dp;
+    code = gop_lookupname(filename, AFS_UIOSYS, 0, NULL, &dp);
+    if (code) return code;
+    *inode = dp->d_inode->i_ino;
+    dput(dp);
 #else
-    code = gop_lookupname(afile, AFS_UIOSYS, 0, NULL, &filevp);
-    if (code) return ENOENT;
-    fce.inode = volumeInode = afs_vnodeToInumber(filevp);
+    struct vnode *filevp;
+    code = gop_lookupname(filename, AFS_UIOSYS, 0, NULL, &filevp);
+    if (code) return code;
+    *inode = afs_vnodeToInumber(filevp);
 #ifdef AFS_DEC_ENV
     grele(filevp);
 #else
     AFS_RELE((struct vnode *)filevp);
 #endif
 #endif /* AFS_LINUX22_ENV */
-    tfile = afs_CFileOpen(fce.inode);
+
+    return 0;
+}
+
+int afs_InitCellInfo(char *afile)
+{
+    ino_t inode;
+    int code;
+
+    code = LookupInodeByPath(afile, &inode);
+    return afs_cellname_init(inode, code);
+}
+
+int afs_InitVolumeInfo(char *afile)
+{
+    int code;
+    struct osi_file *tfile;
+    struct vnode *filevp;
+
+    AFS_STATCNT(afs_InitVolumeInfo);
+    code = LookupInodeByPath(afile, &volumeInode);
+    if (code) return code;
+    tfile = afs_CFileOpen(volumeInode);
     afs_CFileTruncate(tfile, 0);
     afs_CFileClose(tfile);
     return 0;
@@ -428,7 +445,6 @@ int afs_ResourceInit(int preallocs)
     AFS_STATCNT(afs_ResourceInit);
     RWLOCK_INIT(&afs_xuser, "afs_xuser");
     RWLOCK_INIT(&afs_xvolume, "afs_xvolume");
-    RWLOCK_INIT(&afs_xcell, "afs_xcell");
     RWLOCK_INIT(&afs_xserver, "afs_xserver");
     RWLOCK_INIT(&afs_xinterface, "afs_xinterface");
     LOCK_INIT(&afs_puttofileLock, "afs_puttofileLock");
@@ -438,6 +454,7 @@ int afs_ResourceInit(int preallocs)
     LOCK_INIT(&osi_flplock, "osi_flplock");
     RWLOCK_INIT(&afs_xconn, "afs_xconn");
 
+    afs_CellInit();
     afs_InitCBQueue(1);  /* initialize callback queues */
 
     if (afs_resourceinit_flag == 0) {
@@ -449,7 +466,6 @@ int afs_ResourceInit(int preallocs)
        afs_sysname = afs_sysnamelist[0];
        strcpy(afs_sysname, SYS_NAME);
        afs_sysnamecount = 1;
-       QInit(&CellLRU);        
 #if    defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
     {  
 
@@ -642,19 +658,6 @@ void shutdown_AFS(void)
     if (afs_cold_shutdown) {
       afs_resourceinit_flag = 0; 
       /* 
-       * Free Cells table allocations 
-       */
-      { 
-       struct cell *tc;
-       register struct afs_q *cq, *tq;
-       for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
-           tc = QTOC(cq); tq = QNext(cq);
-           if (tc->cellName)
-               afs_osi_Free(tc->cellName, strlen(tc->cellName)+1);
-           afs_osi_Free(tc, sizeof(struct cell));
-       }
-      }
-      /* 
        * Free Volumes table allocations 
        */
       { 
@@ -750,20 +753,18 @@ void shutdown_AFS(void)
       afs_sysname = 0;
       afs_sysnamecount = 0;
       afs_marinerHost = 0;
-      QInit(&CellLRU);      
       afs_setTimeHost = NULL;
       afs_volCounter = 1;
       afs_waitForever = afs_waitForeverCount = 0;
-      afs_cellindex = 0;
-      afs_nextCellNum = 0x100;
       afs_FVIndex = -1;
       afs_server = (struct rx_service *)0;
       RWLOCK_INIT(&afs_xconn, "afs_xconn");
       memset((char *)&afs_rootFid, 0, sizeof(struct VenusFid));
       RWLOCK_INIT(&afs_xuser, "afs_xuser");
       RWLOCK_INIT(&afs_xvolume, "afs_xvolume");
-      RWLOCK_INIT(&afs_xcell, "afs_xcell");
       RWLOCK_INIT(&afs_xserver, "afs_xserver");
       LOCK_INIT(&afs_puttofileLock, "afs_puttofileLock");
+
+      shutdown_cell();
     }
 }
index b51b208..025470b 100644 (file)
@@ -22,8 +22,6 @@ RCSID("$Header$");
 
 
 
-extern int afs_NFSRootOnly;
-int afs_rootCellIndex = 0;
 #if !defined(AFS_LINUX20_ENV)
 /* This is the common part of the vget VFS call. */
 int afs_osi_vget(struct vcache **avcpp, struct fid *afidp,
@@ -31,7 +29,6 @@ int afs_osi_vget(struct vcache **avcpp, struct fid *afidp,
 {
     struct VenusFid vfid;
     struct SmallFid Sfid;
-    extern struct cell *afs_GetCellByIndex();
     register struct cell *tcell;
     struct vrequest treq;
     register afs_int32 code = 0, cellindex;
@@ -41,31 +38,19 @@ int afs_osi_vget(struct vcache **avcpp, struct fid *afidp,
 #ifdef AFS_OSF_ENV
     Sfid.Vnode = afidp->fid_reserved;
 #endif
-    if (afs_NFSRootOnly &&
-       Sfid.Volume == afs_rootFid.Fid.Volume &&
-       Sfid.Vnode == afs_rootFid.Fid.Vnode &&
-       (Sfid.CellAndUnique & 0xffffff) ==
-       (afs_rootFid.Fid.Unique & 0xffffff) &&
-       ((Sfid.CellAndUnique >> 24) & 0xff) == afs_rootCellIndex) {
-       vfid = afs_rootFid;
-    }
-    else {
-       /* Need to extract fid from SmallFid. Will need a wild card option for
-        * finding the right vcache entry.
-        */
-       struct cell *tcell;
-       cellindex = (Sfid.CellAndUnique >> 24) & 0xff;
-       tcell = afs_GetCellByIndex(cellindex, READ_LOCK, 0 /* don't refresh */);
-       if (!tcell) {
-           return ENOENT;
-        }
-       vfid.Cell = tcell->cell;
-       afs_PutCell(tcell, WRITE_LOCK);
-       vfid.Fid.Volume = Sfid.Volume;
-       vfid.Fid.Vnode = Sfid.Vnode;
-       vfid.Fid.Unique = Sfid.CellAndUnique & 0xffffff;
-    }
 
+    /* Need to extract fid from SmallFid. Will need a wild card option for
+     * finding the right vcache entry.
+     */
+    cellindex = (Sfid.CellAndUnique >> 24) & 0xff;
+    tcell = afs_GetCellByIndex(cellindex, READ_LOCK);
+    if (!tcell)
+       return ENOENT;
+    vfid.Cell = tcell->cellNum;
+    afs_PutCell(tcell, WRITE_LOCK);
+    vfid.Fid.Volume = Sfid.Volume;
+    vfid.Fid.Vnode = Sfid.Vnode;
+    vfid.Fid.Unique = Sfid.CellAndUnique & 0xffffff;
 
     /* First attempt to find in cache using wildcard. If that fails,
      * try the usual route to try to get the vcache from the server.
index 8a354af..1dd5839 100644 (file)
@@ -1290,29 +1290,18 @@ DECL_PIOCTL(PGetFileCell)
   
 DECL_PIOCTL(PGetWSCell)
 {
-    register struct cell *tcell=0, *cellOne=0;
-    register struct afs_q *cq, *tq;
+    struct cell *tcell = NULL;
     
     AFS_STATCNT(PGetWSCell);
     if ( !afs_resourceinit_flag )      /* afs deamons havn't started yet */
        return EIO;          /* Inappropriate ioctl for device */
 
-    ObtainReadLock(&afs_xcell);
-    cellOne = NULL;
-
-    for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
-       tcell = QTOC(cq); tq = QNext(cq);
-       if (tcell->states & CPrimary) break;
-       if (tcell->cell == 1) cellOne = tcell;
-       tcell = 0;
-    }
-    ReleaseReadLock(&afs_xcell);
-    if (!tcell)        {           /* no primary cell, use cell #1 */
-      if (!cellOne) return ESRCH;
-      tcell = cellOne;
-    }
+    tcell = afs_GetPrimaryCell(READ_LOCK);
+    if (!tcell)                /* no primary cell? */
+      return ESRCH;
     strcpy(aout, tcell->cellName);
     *aoutSize = strlen(aout) + 1;
+    afs_PutCell(tcell, READ_LOCK);
     return 0;
   }
   
@@ -1394,20 +1383,15 @@ DECL_PIOCTL(PSetTokens)
          set_parent_pag = 1;
       }
       tcell = afs_GetCellByName(ain, READ_LOCK);
-      if (tcell) {
-       i = tcell->cell;
-      }
-      else {
-       goto nocell;
-      }
+      if (!tcell) goto nocell;
     }
     else {
-      /* default to cell 1, primary id */
+      /* default to primary cell, primary id */
       flag = 1;                /* primary id */
-      i = 1;           /* cell number */
-      tcell = afs_GetCell(1, READ_LOCK);
+      tcell = afs_GetPrimaryCell(READ_LOCK);
       if (!tcell) goto nocell;
     }
+    i = tcell->cellNum;
     afs_PutCell(tcell, READ_LOCK);
     if (set_parent_pag) {
        int pag;
@@ -1722,7 +1706,7 @@ DECL_PIOCTL(PGetTokens)
            }
        }
        else {
-           if (tu->uid == areq->uid && tu->cell == 1) break;
+           if (tu->uid == areq->uid && afs_IsPrimaryCellNum(tu->cell)) break;
        }
     }
     if (tu) {
@@ -1890,7 +1874,7 @@ DECL_PIOCTL(PCheckServers)
     else cellp = NULL;
     if (!cellp && (temp & 2)) {
        /* use local cell */
-       cellp = afs_GetCell(1, READ_LOCK);
+       cellp = afs_GetPrimaryCell(READ_LOCK);
     }
     if (!(temp & 1)) { /* if not fast, call server checker routine */
        afs_CheckServers(1, cellp);     /* check down servers */
@@ -2176,18 +2160,17 @@ DECL_PIOCTL(PNewCell)
     }
 
     linkedstate |= CNoSUID; /* setuid is disabled by default for fs newcell */
-    code = afs_NewCell(newcell, cellHosts, linkedstate, linkedcell, fsport, vlport, (int)0, NULL);
+    code = afs_NewCell(newcell, cellHosts, linkedstate, linkedcell, fsport,
+                      vlport, (int)0);
     return code;
 }
 
 DECL_PIOCTL(PNewAlias)
 {
     /* create a new cell alias */
-    register struct cell *tcell;
     char *tp = ain;
     register afs_int32 code;
     char *realName, *aliasName;
-    register struct afs_q *cq, *tq;
     
     if ( !afs_resourceinit_flag )      /* afs deamons havn't started yet */
        return EIO;          /* Inappropriate ioctl for device */
@@ -2199,22 +2182,7 @@ DECL_PIOCTL(PNewAlias)
     tp += strlen(aliasName) + 1;
     realName = tp;
 
-    /*
-     * Prevent user from shooting themselves in the foot -- don't allow
-     * creation of aliases when a real cell already exists with that name.
-     */
-    ObtainReadLock(&afs_xcell);
-    for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
-       tcell = QTOC(cq); tq = QNext(cq);
-       if ((afs_strcasecmp(tcell->cellName, aliasName) == 0) &&
-           !(tcell->states & CAlias)) {
-           ReleaseReadLock(&afs_xcell);
-           return EEXIST;
-       }
-    }
-    ReleaseReadLock(&afs_xcell);
-
-    code = afs_NewCell(aliasName, 0, CAlias, 0, 0, 0, 0, realName);
+    code = afs_NewCellAlias(aliasName, realName);
     *aoutSize = 0;
     return code;
 }
@@ -2225,7 +2193,6 @@ DECL_PIOCTL(PListCells)
     register struct cell *tcell=0;
     register afs_int32 i;
     register char *cp, *tp = ain;
-    register struct afs_q *cq, *tq;
 
     AFS_STATCNT(PListCells);
     if ( !afs_resourceinit_flag )      /* afs deamons havn't started yet */
@@ -2233,7 +2200,7 @@ DECL_PIOCTL(PListCells)
 
     memcpy((char *)&whichCell, tp, sizeof(afs_int32));
     tp += sizeof(afs_int32);
-    tcell = afs_GetRealCellByIndex(whichCell, READ_LOCK, 0);
+    tcell = afs_GetCellByIndex(whichCell, READ_LOCK);
     if (tcell) {
        cp = aout;
        memset(cp, 0, MAXCELLHOSTS * sizeof(afs_int32));
@@ -2246,6 +2213,7 @@ DECL_PIOCTL(PListCells)
        strcpy(cp, tcell->cellName);
        cp += strlen(tcell->cellName)+1;
        *aoutSize = cp - aout;
+       afs_PutCell(tcell, READ_LOCK);
     }
     if (tcell) return 0;
     else return EDOM;
@@ -2254,9 +2222,8 @@ DECL_PIOCTL(PListCells)
 DECL_PIOCTL(PListAliases)
 {
     afs_int32 whichAlias;
-    register struct cell *tcell=0;
+    register struct cell_alias *tcalias=0;
     register char *cp, *tp = ain;
-    register struct afs_q *cq, *tq;
 
     if ( !afs_resourceinit_flag )      /* afs deamons havn't started yet */
        return EIO;          /* Inappropriate ioctl for device */
@@ -2266,27 +2233,17 @@ DECL_PIOCTL(PListAliases)
     memcpy((char *)&whichAlias, 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 (whichAlias == 0) break;
-       tcell = 0;
-       whichAlias--;
-    }
-    if (tcell) {       
+    tcalias = afs_GetCellAlias(whichAlias);
+    if (tcalias) {     
        cp = aout;
-       strcpy(cp, tcell->cellName);
-       cp += strlen(tcell->cellName)+1;
-       strcpy(cp, tcell->realName);
-       cp += strlen(tcell->realName)+1;
+       strcpy(cp, tcalias->alias);
+       cp += strlen(tcalias->alias)+1;
+       strcpy(cp, tcalias->cell);
+       cp += strlen(tcalias->cell)+1;
        *aoutSize = cp - aout;
+       afs_PutCellAlias(tcalias);
     }
-    ReleaseReadLock(&afs_xcell);
-    if (tcell) return 0;
+    if (tcalias) return 0;
     else return EDOM;
 }
 
@@ -2729,22 +2686,34 @@ DECL_PIOCTL(PSetSysName)
  * l - array of cell ids which have volumes that need to be sorted
  * vlonly - sort vl servers or file servers?
  */
-static void ReSortCells(int s, afs_int32 l[], int vlonly)  
+static void *ReSortCells_cb(struct cell *cell, void *arg)
+{
+    afs_int32 *p = (afs_int32 *) arg;
+    afs_int32 *l = p + 1;
+    int i, s = p[0];
+    for (i=0; i<s; i++) {
+       if (l[i] == cell->cellNum) {
+           ObtainWriteLock(&cell->lock, 690);
+           afs_SortServers(cell->cellHosts, MAXCELLHOSTS);
+           ReleaseWriteLock(&cell->lock);
+       }
+    }
+}
+
+static void ReSortCells(int s, afs_int32 *l, int vlonly)  
 {
   int i;
   struct volume *j;
   register int  k;
 
   if (vlonly) {
-      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);
+      afs_int32 *p;
+      p = (afs_int32 *) afs_osi_Alloc(sizeof(afs_int32) * (s+1));
+      p[0] = s;
+      memcpy(p+1, l, s * sizeof(afs_int32));
+      afs_TraverseCells(&ReSortCells_cb, p);
+      afs_osi_Free(p, sizeof(afs_int32) * (s+1));
       return;
   }
 
@@ -2806,10 +2775,10 @@ static int afs_setsprefs(sp, num, vlonly)
         
         if (srvr->cell) {
           /* if we don't know yet what cell it's in, this is moot */
-          for (j=touchedSize-1; j>=0 && touched[j] != srvr->cell->cell; j--)
+          for (j=touchedSize-1; j>=0 && touched[j] != srvr->cell->cellNum; j--)
                 /* is it in our list of touched cells ?  */ ;
           if (j < 0) {                   /* no, it's not */
-            touched[touchedSize++] = srvr->cell->cell;
+            touched[touchedSize++] = srvr->cell->cellNum;
             if (touchedSize >= 32) {                /* watch for ovrflow */
               ReleaseReadLock(&afs_xserver);
               ReSortCells(touchedSize, touched, vlonly);
index 9f5b70b..7d6396e 100644 (file)
@@ -152,27 +152,33 @@ extern void afs_InitCBQueue(int doLockInit);
 extern void afs_DequeueCallback(struct vcache *avc);
 
 /* afs_cell.c */
-extern struct afs_q CellLRU;
 extern afs_rwlock_t afs_xcell;
-extern afs_int32 afs_cellindex;
-extern afs_uint32 afs_nextCellNum;
-extern afs_int32 afs_NewCell(char *acellName, register afs_int32 *acellHosts, int aflags, 
-        char *linkedcname, u_short fsport, u_short vlport, int timeout, char *aliasFor);
-extern struct cell *afs_GetCell(register afs_int32 acell, afs_int32 locktype);
-extern struct cell *afs_GetCellByIndex(register afs_int32 cellindex, 
-        afs_int32 locktype, afs_int32 refresh);
-extern struct cell *afs_FindCellByName(register char *acellName, afs_int32 locktype);
-extern struct cell *afs_GetCellByName_Dns(register char *acellName, afs_int32 locktype);
-extern struct cell *afs_GetCellByName(register char *acellName, afs_int32 locktype);
-extern struct cell *afs_GetCellNoLock(register afs_int32 acell, afs_int32 locktype);
-extern void afs_StopAfsdb(void);
-extern int afs_AfsdbHandler(char *acellName, int acellNameLen, afs_int32 *kernelMsg);
-extern int afs_GetCellHostsFromDns(char *acellName, afs_int32 *acellHosts, 
-        int *timeout, char **realName);
-extern void afs_RefreshCell(register struct cell *ac);
+extern void afs_CellInit(void);
+extern void shutdown_cell(void);
+extern int afs_cellname_init(ino_t inode, int lookupcode);
+extern int afs_cellname_write();
+extern afs_int32 afs_NewCell(char *acellName, afs_int32 *acellHosts,
+       int aflags, char *linkedcname, u_short fsport, u_short vlport,
+       int timeout);
+extern afs_int32 afs_SetPrimaryCell(char *acellName);
+extern struct cell *afs_GetCell(afs_int32 acell, afs_int32 locktype);
+extern struct cell *afs_GetCellStale(afs_int32 acell, afs_int32 locktype);
+extern struct cell *afs_GetCellByIndex(afs_int32 cellidx, afs_int32 locktype);
+extern struct cell *afs_GetCellByName(char *acellName, afs_int32 locktype);
+extern struct cell *afs_GetPrimaryCell(afs_int32 locktype);
+extern int afs_IsPrimaryCellNum(afs_int32 cellnum);
+extern int afs_IsPrimaryCell(struct cell *cell);
+extern void *afs_TraverseCells(void *(*cb)(struct cell *, void *), void *arg);
+extern int afs_CellOrAliasExists(char *aname);
+extern int afs_CellNumValid(afs_int32 cellnum);
+extern afs_int32 afs_NewCellAlias(char *alias, char *cell);
+extern struct cell_alias *afs_GetCellAlias(int index);
+extern int afs_AFSDBHandler(char *acellName, int acellNameLen,
+       afs_int32 *kernelMsg);
+extern void afs_LookupAFSDB(char *acellName);
+extern void afs_StopAFSDB(void);
 extern void afs_RemoveCellEntry(struct server *srvp);
 
-
 /* afs_chunk.c */
 extern afs_int32 afs_FirstCSize;
 extern afs_int32 afs_OtherCSize;
@@ -272,15 +278,18 @@ extern int afs_InitCacheFile(char *afile, ino_t ainode);
 extern int afs_IsDynrootFid(struct VenusFid *fid);
 extern void afs_GetDynrootFid(struct VenusFid *fid);
 extern int afs_IsDynroot(struct vcache *avc);
-extern void afs_RefreshDynroot(void);
-extern void afs_GetDynroot(char **dynrootDir, int *dynrootLen, struct AFSFetchStatus *status);
+extern void afs_DynrootInvalidate(void);
+extern void afs_GetDynroot(char **dynrootDir, int *dynrootLen,
+       struct AFSFetchStatus *status);
 extern void afs_PutDynroot(void);
-extern int afs_DynrootNewVnode(struct vcache *avc, struct AFSFetchStatus *status);
+extern int afs_DynrootNewVnode(struct vcache *avc,
+       struct AFSFetchStatus *status);
 extern int afs_SetDynrootEnable(int enable);
 extern int afs_GetDynrootEnable(void);
-extern int afs_DynrootVOPRemove(struct vcache *avc, struct AFS_UCRED *acred, char *aname);
+extern int afs_DynrootVOPRemove(struct vcache *avc, struct AFS_UCRED *acred,
+       char *aname);
 extern int afs_DynrootVOPSymlink(struct vcache *avc, struct AFS_UCRED *acred, 
-        char *aname, char *atargetName);
+       char *aname, char *atargetName);
 
 /* afs_exporter.c */
 extern struct afs_exporter *root_exported;
@@ -616,7 +625,7 @@ extern void afs_SetPrimary(register struct unixuser *au, register int aflag);
 
 /* afs_util.c */
 extern char *afs_cv2string(char *ttp, afs_uint32 aval);
-extern int afs_strcasecmp(register char *s1, register char *s2);
+extern int afs_strcasecmp(char *s1, char *s2);
 extern char *afs_strdup(char *s);
 extern void print_internet_address(char *preamble, struct srvAddr *sa,
                            char *postamble, int flag);
index fc83995..2276433 100644 (file)
@@ -84,6 +84,26 @@ int afs_totalSrvAddrs = 0;
 
 
 
+static struct afs_stats_SrvUpDownInfo *
+GetUpDownStats(struct server *srv)
+{
+    struct afs_stats_SrvUpDownInfo *upDownP;
+    u_short fsport = AFS_FSPORT;
+
+    if (srv->cell)
+       fsport = srv->cell->fsport;
+
+    if (srv->addr->sa_portal == fsport)
+       upDownP = afs_stats_cmperf.fs_UpDown;
+    else
+       upDownP = afs_stats_cmperf.vl_UpDown;
+
+    if (srv->cell && afs_IsPrimaryCell(srv->cell))
+       return &upDownP[AFS_STATS_UPDOWN_IDX_SAME_CELL];
+    else
+       return &upDownP[AFS_STATS_UPDOWN_IDX_DIFF_CELL];
+}
+
 
 /*------------------------------------------------------------------------
  * afs_MarkServerUpOrDown
@@ -159,16 +179,7 @@ void afs_MarkServerUpOrDown(struct srvAddr *sa, int a_isDown)
     currTimeP = &currTime;
     osi_GetuTime(currTimeP);
 
-    if (sa->sa_portal == AFS_FSPORT) {
-       upDownP = (a_serverP->cell->cell == 1) ?
-           &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]) :
-           &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]);
-    } /*File Server record*/
-    else {
-       upDownP = (a_serverP->cell->cell == 1) ?
-           &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]) :
-           &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]);
-    } /*VL Server record*/
+    upDownP = GetUpDownStats(a_serverP);
 
     if (a_isDown) {
        /*
@@ -285,7 +296,7 @@ static void CheckVLServer(register struct srvAddr *sa, struct vrequest *areq)
        return; /* can't do much */
 
     tc = afs_ConnByHost(aserver, aserver->cell->vlport, 
-                       aserver->cell->cell, areq, 1, SHARED_LOCK);
+                       aserver->cell->cellNum, areq, 1, SHARED_LOCK);
     if (!tc)
        return;
     rx_SetConnDeadTime(tc->id, 3);
@@ -413,17 +424,7 @@ void afs_CountServers(void)
                 * in the appropriate places.
                 */
                srvRecordAge = currTime.tv_sec - currSrvP->activationTime;
-               if (currSrvP->addr->sa_portal == AFS_FSPORT) {
-                   upDownP = (currSrvP->cell->cell == 1) ?
-                       &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]):
-                       &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]);
-               } /*File Server record*/
-               else {
-                   upDownP = (currSrvP->cell->cell == 1) ?
-                       &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]):
-                       &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]);
-               } /*VL Server record*/
-
+               upDownP = GetUpDownStats(currSrvP);
                upDownP->sumOfRecordAges += srvRecordAge;
                if ((upDownP->ageOfYoungestRecord == 0) ||
                    (srvRecordAge < upDownP->ageOfYoungestRecord))
@@ -549,8 +550,8 @@ void afs_CheckServers(int adown, struct cell *acellp)
            continue;  /* have just been added by setsprefs */ 
 
        /* get a connection, even if host is down; bumps conn ref count */
-       tu = afs_GetUser(treq.uid, ts->cell->cell, SHARED_LOCK);
-       tc = afs_ConnBySA(sa, ts->cell->fsport, ts->cell->cell, tu,
+       tu = afs_GetUser(treq.uid, ts->cell->cellNum, SHARED_LOCK);
+       tc = afs_ConnBySA(sa, ts->cell->fsport, ts->cell->cellNum, tu,
                          1/*force*/, 1/*create*/, SHARED_LOCK);
        afs_PutUser(tu, SHARED_LOCK);
        if (!tc) continue;
@@ -579,12 +580,9 @@ void afs_CheckServers(int adown, struct cell *acellp)
             */
            if (code == 0 && start == end && afs_setTime != 0 &&
                (tc->srvr->server == afs_setTimeHost ||
-               /*
-                * Sync only to a server in the local cell: cell(id)==1
-                * or CPrimary.
-                */
+               /* Sync only to a server in the local cell */
                (afs_setTimeHost == (struct server *)0 &&
-                (ts->cell->cell == 1 || (ts->cell->states&CPrimary))))) {
+                afs_IsPrimaryCell(ts->cell)))) {
 
                char msgbuf[90];  /* strlen("afs: setting clock...") + slop */
                /* set the time */
@@ -1572,16 +1570,8 @@ struct server *afs_GetServer(afs_uint32 *aserverp, afs_int32 nservers,
        /* With the introduction of this new record, we need to adjust the
        * proper individual & global server up/down info.
        */
-       if (aport == fsport) {   /* File Server record */
-         upDownP = (acell == 1) ?
-           &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]) :
-           &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]);
-       } else {                   /* VL Server record */
-         upDownP = (acell == 1) ?
-           &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]) :
-           &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]);
-       } 
-       (upDownP->numTtlRecords)    += srvcount;
+       upDownP = GetUpDownStats(newts);
+       upDownP->numTtlRecords      += srvcount;
        afs_stats_cmperf.srvRecords += srvcount;
        if (afs_stats_cmperf.srvRecords > afs_stats_cmperf.srvRecordsHWM)
          afs_stats_cmperf.srvRecordsHWM = afs_stats_cmperf.srvRecords;
@@ -1608,21 +1598,12 @@ void afs_ActivateServer(struct srvAddr *sap)
       currTimeP = &currTime;
       osi_GetuTime(currTimeP);
       aserver->activationTime = currTime.tv_sec;
-      if (sap->sa_portal == AFS_FSPORT) {
-        upDownP = (aserver->cell->cell == 1) ?
-             &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]) :
-                  &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]);
-      } /*File Server record*/
-      else {
-        upDownP = (aserver->cell->cell == 1) ?
-             &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]) :
-                  &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]);
-      } /*VL Server record*/
-      if (aserver->flags & SRVR_ISDOWN)
-          (upDownP->numDownRecords)++;
-      else {
-        (upDownP->numUpRecords)++;
-        (upDownP->numRecordsNeverDown)++;
+      upDownP = GetUpDownStats(aserver);
+      if (aserver->flags & SRVR_ISDOWN) {
+        upDownP->numDownRecords++;
+      } else {
+        upDownP->numUpRecords++;
+        upDownP->numRecordsNeverDown++;
       }
    }
 }
index 2f46071..c23e95c 100644 (file)
@@ -638,6 +638,7 @@ struct afs_CMCallStats {
     afs_int32 C_afs_MarshallCacheConfig;       /* afs_callback.c*/
     afs_int32 C_SRXAFSCB_GetCacheConfig;       /* afs_callback.c*/
     afs_int32 C_SRXAFSCB_GetCE64;      /* afs_callback.c*/
+    afs_int32 C_SRXAFSCB_GetCellByNum; /* afs_callback.c*/
 };
 
 struct afs_CMMeanStats {
index 54a8c11..36a094f 100644 (file)
@@ -346,7 +346,7 @@ afs_int32 afs_FlushVCBs (afs_int32 lockit)
                    callBacks[0].CallBackType = CB_EXCLUSIVE;
                    for (safety3 = 0; safety3 < MAXHOSTS*2; safety3++) {
                        tc = afs_ConnByHost(tsp, tsp->cell->fsport,
-                                           tsp->cell->cell, &treq, 0,
+                                           tsp->cell->cellNum, &treq, 0,
                                            SHARED_LOCK);
                        if (tc) {
                          XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_GIVEUPCALLBACKS);
@@ -451,7 +451,7 @@ static afs_int32 afs_QueueVCB(struct vcache *avc)
  *     entries locked.
  */
 
-int afs_RemoveVCB(register struct VenusFid *afid)
+int afs_RemoveVCB(struct VenusFid *afid)
 {
     register int i;
     register struct server *tsp;
@@ -464,7 +464,7 @@ int afs_RemoveVCB(register struct VenusFid *afid)
     for(i=0;i<NSERVERS;i++) {
        for(tsp=afs_servers[i]; tsp; tsp=tsp->next) {
            /* if cell is known, and is wrong, then skip this server */
-           if (tsp->cell && tsp->cell->cell != afid->Cell) continue;
+           if (tsp->cell && tsp->cell->cellNum != afid->Cell) continue;
 
            /*
             * Otherwise, iterate through file IDs we're sending to the
@@ -2459,7 +2459,7 @@ struct vcache *afs_FindVCache(struct VenusFid *afid, afs_int32 *retry, afs_int32
     if (flag & DO_STATS) {
       if (tvc)         afs_stats_cmperf.vcacheHits++;
       else     afs_stats_cmperf.vcacheMisses++;
-      if (afid->Cell == LOCALCELL)
+      if (afs_IsPrimaryCellNum(afid->Cell))
         afs_stats_cmperf.vlocalAccesses++;
       else
         afs_stats_cmperf.vremoteAccesses++;
@@ -2599,7 +2599,7 @@ afs_int32 afs_NFSFindVCache(struct vcache **avcp, struct VenusFid *afid)
 
     if (tvc)   afs_stats_cmperf.vcacheHits++;
     else       afs_stats_cmperf.vcacheMisses++;
-    if (afid->Cell == LOCALCELL)
+    if (afs_IsPrimaryCellNum(afid->Cell))
         afs_stats_cmperf.vlocalAccesses++;
     else
         afs_stats_cmperf.vremoteAccesses++;
index 4a2062e..665187f 100644 (file)
@@ -101,7 +101,7 @@ afs_int32 afs_FVIndex = -1;
 struct volume *afs_UFSGetVolSlot(void)
 {
     register struct volume *tv, **lv;
-    register char *tfile;
+    struct osi_file *tfile;
     register afs_int32 i, code;
     afs_int32 bestTime;
     struct volume *bestVp, **bestLp;
@@ -440,7 +440,7 @@ static struct volume *afs_SetupVolume(afs_int32 volid, char *aname,
     ObtainWriteLock(&afs_xvolume,108);
     i = VHash(volid);
     for (tv = afs_volumes[i]; tv; tv=tv->next) {
-       if (tv->volume == volid && tv->cell == tcell->cell) {
+       if (tv->volume == volid && tv->cell == tcell->cellNum) {
            break;
        }
     }
@@ -449,14 +449,14 @@ static struct volume *afs_SetupVolume(afs_int32 volid, char *aname,
 
        tv = afs_GetVolSlot();
        memset((char *)tv, 0, sizeof(struct volume));
-       tv->cell = tcell->cell;
+       tv->cell = tcell->cellNum;
        RWLOCK_INIT(&tv->lock, "volume lock");
        tv->next = afs_volumes[i];      /* thread into list */
        afs_volumes[i] = tv;
        tv->volume = volid;
        for (j=fvTable[FVHash(tv->cell,volid)]; j!=0; j=tf->next) {
            if (afs_FVIndex != j) {
-               char *tfile;
+               struct osi_file *tfile;
                tfile = osi_UFSOpen(volumeInode);
                err = afs_osi_Read(tfile, sizeof(struct fvolume) * j, &staticFVolume, sizeof(struct fvolume));
                if (err != sizeof(struct fvolume))
@@ -485,12 +485,12 @@ static struct volume *afs_SetupVolume(afs_int32 volid, char *aname,
     ReleaseWriteLock(&afs_xvolume);
     ObtainWriteLock(&tv->lock,111);
     if (type == 2) {
-       InstallUVolumeEntry(tv, uve, tcell->cell, tcell, areq);
+       InstallUVolumeEntry(tv, uve, tcell->cellNum, tcell, areq);
     }
     else if (type == 1)
-       InstallNVolumeEntry(tv, nve, tcell->cell);
+       InstallNVolumeEntry(tv, nve, tcell->cellNum);
     else
-       InstallVolumeEntry(tv, ove, tcell->cell);
+       InstallVolumeEntry(tv, ove, tcell->cellNum);
     if (agood) {
        if (!tv->name) {
            tv->name = afs_osi_Alloc(strlen(aname) + 1);
@@ -549,7 +549,7 @@ static struct volume *afs_NewDynrootVolume(struct VenusFid *fid)
     tve.volumeId[ROVOL] = fid->Fid.Volume;
     tve.flags = VLF_ROEXISTS;
 
-    tv = afs_SetupVolume(0, bp, &tve, tcell, 0, 0, 0);
+    tv = afs_SetupVolume(0, bp, (char *) &tve, tcell, 0, 0, 0);
     afs_PutCell(tcell, READ_LOCK);
     return tv;
 }
@@ -590,7 +590,7 @@ static struct volume *afs_NewVolumeByName(char *aname, afs_int32 acell, int agoo
     afs_InitReq(&treq, &afs_osi_cred); /* *must* be unauth for vldb */
     do {
        tconn = afs_ConnByMHosts(tcell->cellHosts, tcell->vlport,
-                                tcell->cell, &treq, SHARED_LOCK);
+                                tcell->cellNum, &treq, SHARED_LOCK);
        if (tconn) {
            if (tconn->srvr->server->flags & SNO_LHOSTS) {
                type = 0;
@@ -921,7 +921,7 @@ void InstallUVolumeEntry(struct volume *av, struct uvldbentry *ve,
                memset((char *)&addrs, 0, sizeof(addrs));
                do {
                    tconn = afs_ConnByMHosts(tcell->cellHosts, tcell->vlport,
-                                            tcell->cell, areq, SHARED_LOCK);
+                                            tcell->cellNum, areq, SHARED_LOCK);
                    if (tconn) {
                        RX_AFS_GUNLOCK();
                        code = VL_GetAddrsU(tconn->id, &attrs, &uuid, &unique, &nentries, &addrs);
index f9004be..4f9059f 100644 (file)
@@ -170,6 +170,7 @@ void set_staticaddrs(void);
 #define        AFSLOGFILE      "AFSLog"
 #define        DCACHEFILE      "CacheItems"
 #define        VOLINFOFILE     "VolumeItems"
+#define CELLINFOFILE   "CellItems"
 
 #define MAXIPADDRS 1024
 
@@ -211,6 +212,7 @@ char cacheBaseDir[1024];            /*Where the workstation AFS cache lives*/
 char confDir[1024];                    /*Where the workstation AFS configuration lives*/
 char fullpn_DCacheFile[1024];          /*Full pathname of DCACHEFILE*/
 char fullpn_VolInfoFile[1024];         /*Full pathname of VOLINFOFILE*/
+char fullpn_CellInfoFile[1024];                /*Full pathanem of CELLINFOFILE*/
 char fullpn_AFSLogFile[1024];          /*Full pathname of AFSLOGFILE*/
 char fullpn_CacheInfo[1024];           /*Full pathname of CACHEINFO*/
 char fullpn_VFile[1024];               /*Full pathname of data cache files*/
@@ -224,7 +226,6 @@ char cacheMountDir[1024];           /*Mount directory for AFS*/
 char rootVolume[64] = "root.afs";      /*AFS root volume name*/
 afs_int32 cacheSetTime = 1;                    /*Keep checking time to avoid drift?*/
 afs_int32 isHomeCell;                  /*Is current cell info for the home cell?*/
-afs_int32 lookingForHomeCell;          /*Are we still looking for the home cell?*/
 int createAndTrunc = O_CREAT | O_TRUNC; /*Create & truncate on open*/
 int ownerRWmode        = 0600;                 /*Read/write OK by owner*/
 static int filesSet = 0;               /*True if number of files explicitly set*/
@@ -270,10 +271,11 @@ int *dir_for_V = NULL;                    /* Array: dir of each cache file.
                                         */
 AFSD_INO_T *inode_for_V;               /* Array of inodes for desired
                                         * cache files */
-int missing_DCacheFile = 1;            /*Is the DCACHEFILE missing?*/
-int missing_VolInfoFile        = 1;            /*Is the VOLINFOFILE missing?*/
-int afsd_rmtsys = 0;                           /* Default: don't support rmtsys */
-struct afs_cacheParams cparams;          /* params passed to cache manager */
+int missing_DCacheFile  = 1;           /*Is the DCACHEFILE missing?*/
+int missing_VolInfoFile  = 1;          /*Is the VOLINFOFILE missing?*/
+int missing_CellInfoFile = 1;          /*Is the CELLINFOFILE missing?*/
+int afsd_rmtsys = 0;                   /* Default: don't support rmtsys */
+struct afs_cacheParams cparams;         /* params passed to cache manager */
 
 static int HandleMTab();
 
@@ -626,6 +628,16 @@ int CreateCacheFile(fname, statp)
     return(0);
 }
 
+static void CreateFileIfMissing(char *fullpn, int missing)
+{
+    if (missing) {
+       if (afsd_verbose)
+           printf("CreateFileIfMissing: Creating '%s'\n", fullpn);
+       if (CreateCacheFile(fullpn, NULL))
+           printf("CreateFileIfMissing: Can't create '%s'\n", fullpn);
+    }
+}
+
 /*-----------------------------------------------------------------------------
   * SweepAFSCache
   *
@@ -802,6 +814,12 @@ static int doSweepAFSCache(vFilesFound,directory,dirNum,maxDir)
             */
            missing_VolInfoFile = 0;
        }
+       else if (dirNum < 0 && strcmp(currp->d_name, CELLINFOFILE) == 0) {
+           /*
+            * Found the file holding the cell info.
+            */
+           missing_CellInfoFile = 0;
+       }
        else  if ((strcmp(currp->d_name,          ".") == 0) ||
                  (strcmp(currp->d_name,         "..") == 0) ||
 #ifdef AFS_DECOSF_ENV
@@ -842,25 +860,12 @@ static int doSweepAFSCache(vFilesFound,directory,dirNum,maxDir)
 
     if (dirNum < 0) {
 
-        /*
+       /*
         * Create all the cache files that are missing.
         */
-        if (missing_DCacheFile) {
-           if (afsd_verbose)
-               printf("%s: Creating '%s'\n",
-                      rn, fullpn_DCacheFile);
-           if (CreateCacheFile(fullpn_DCacheFile, NULL))
-               printf("%s: Can't create '%s'\n",
-                      rn, fullpn_DCacheFile);
-       }
-       if (missing_VolInfoFile) {
-           if (afsd_verbose)
-               printf("%s: Creating '%s'\n",
-                      rn, fullpn_VolInfoFile);
-           if (CreateCacheFile(fullpn_VolInfoFile, NULL))
-               printf("%s: Can't create '%s'\n",
-                      rn, fullpn_VolInfoFile);
-       }
+       CreateFileIfMissing(fullpn_DCacheFile, missing_DCacheFile);
+       CreateFileIfMissing(fullpn_VolInfoFile, missing_VolInfoFile);
+       CreateFileIfMissing(fullpn_CellInfoFile, missing_CellInfoFile);
 
        /* ADJUST CACHE FILES */
 
@@ -1035,19 +1040,14 @@ register struct afsconf_cell *aci;
 char *arock;
 struct afsconf_dir *adir; {
     register int isHomeCell;
-    register int i;
-    afs_int32 cellFlags;
+    register int i, code;
+    afs_int32 cellFlags = 0;
     afs_int32 hosts[MAXHOSTSPERCELL];
     
     /* figure out if this is the home cell */
     isHomeCell = (strcmp(aci->name, LclCellName) == 0);
-    if (isHomeCell) {
-       lookingForHomeCell = 0;
-       cellFlags = 1;      /* home cell, suid is ok */
-    }
-    else {
+    if (!isHomeCell)
        cellFlags = 2;      /* not home, suid is forbidden */
-    }
     
     /* build address list */
     for(i=0;i<MAXHOSTSPERCELL;i++)
@@ -1057,11 +1057,13 @@ struct afsconf_dir *adir; {
                                            for upwards compatibility */
 
     /* configure one cell */
-    call_syscall(AFSOP_ADDCELL2,
+    code = call_syscall(AFSOP_ADDCELL2,
             hosts,                     /* server addresses */
             aci->name,                 /* cell name */
             cellFlags,                 /* is this the home cell? */
             aci->linkedCell);          /* Linked cell, if any */
+    if (code)
+       printf("Adding cell '%s': error %d\n", aci->name, code);
     return 0;
 }
 
@@ -1468,8 +1470,9 @@ mainproc(as, arock)
     /*
      * Set up all the pathnames we'll need for later.
      */
-    sprintf(fullpn_DCacheFile,  "%s/%s", cacheBaseDir, DCACHEFILE);
-    sprintf(fullpn_VolInfoFile, "%s/%s", cacheBaseDir, VOLINFOFILE);
+    sprintf(fullpn_DCacheFile,   "%s/%s", cacheBaseDir, DCACHEFILE);
+    sprintf(fullpn_VolInfoFile,  "%s/%s", cacheBaseDir, VOLINFOFILE);
+    sprintf(fullpn_CellInfoFile, "%s/%s", cacheBaseDir, CELLINFOFILE);
     sprintf(fullpn_VFile,       "%s/",  cacheBaseDir);
     vFilePtr = fullpn_VFile + strlen(fullpn_VFile);
 
@@ -1568,6 +1571,83 @@ mainproc(as, arock)
     }
 #endif
 
+    code = call_syscall(AFSOP_BASIC_INIT, 1);
+    if (code)
+       printf("%s: Error %d in basic initialization.\n", rn, code);
+
+    /*
+     * Tell the kernel some basic information about the workstation's cache.
+     */
+    if (afsd_verbose)
+       printf("%s: Calling AFSOP_CACHEINIT: %d stat cache entries, %d optimum cache files, %d blocks in the cache, flags = 0x%x, dcache entries %d\n",
+              rn, cacheStatEntries, cacheFiles, cacheBlocks, cacheFlags,
+              dCacheSize);
+    memset(&cparams, '\0', sizeof(cparams));
+    cparams.cacheScaches = cacheStatEntries;
+    cparams.cacheFiles = cacheFiles;
+    cparams.cacheBlocks = cacheBlocks;
+    cparams.cacheDcaches = dCacheSize;
+    cparams.cacheVolumes = vCacheSize;
+    cparams.chunkSize = chunkSize;
+    cparams.setTimeFlag = cacheSetTime;
+    cparams.memCacheFlag = cacheFlags;
+#ifdef notdef
+    cparams.inodes       = inodes;
+#endif
+    call_syscall(AFSOP_CACHEINIT, &cparams);
+    if (afsd_CloseSynch) 
+       call_syscall(AFSOP_CLOSEWAIT);
+
+    /*
+     * Sweep the workstation AFS cache directory, remembering the inodes of
+     * valid files and deleting extraneous files.  Keep sweeping until we
+     * have the right number of data cache files or we've swept too many
+     * times.
+     *
+     * This also creates files in the cache directory like VolumeItems and
+     * CellItems, and thus must be ran before those are sent to the kernel.
+     */
+    if (afsd_verbose)
+       printf("%s: Sweeping workstation's AFS cache directory.\n",
+              rn);
+    cacheIteration = 0;
+    /* Memory-cache based system doesn't need any of this */
+    if(!(cacheFlags & AFSCALL_INIT_MEMCACHE)) {
+       do {
+           cacheIteration++;
+           if (SweepAFSCache(&vFilesFound)) {
+               printf("%s: Error on sweep %d of workstation AFS cache \
+                       directory.\n", rn, cacheIteration);
+               exit(1);
+           }
+           if (afsd_verbose)
+               printf("%s: %d out of %d data cache files found in sweep %d.\n",
+                      rn, vFilesFound, cacheFiles, cacheIteration);
+       } while ((vFilesFound < cacheFiles) &&
+                (cacheIteration < MAX_CACHE_LOOPS));
+    } else if(afsd_verbose)
+       printf("%s: Using memory cache, not swept\n", rn);
+
+    /*
+     * Pass the kernel the name of the workstation cache file holding the 
+     * dcache entries.
+     */
+    if (afsd_debug)
+       printf("%s: Calling AFSOP_CACHEINFO: dcache file is '%s'\n",
+              rn, fullpn_DCacheFile);
+    /* once again, meaningless for a memory-based cache. */
+    if(!(cacheFlags & AFSCALL_INIT_MEMCACHE))
+       call_syscall(AFSOP_CACHEINFO, fullpn_DCacheFile);
+
+    /*
+     * Pass the kernel the name of the workstation cache file holding the
+     * cell information.
+     */
+    if (afsd_debug)
+       printf("%s: Calling AFSOP_CELLINFO: cell info file is '%s'\n",
+              rn, fullpn_CellInfoFile);
+    call_syscall(AFSOP_CELLINFO, fullpn_CellInfoFile);
+
     if (enable_dynroot) {
        if (afsd_verbose)
            printf("%s: Enabling dynroot support in kernel.\n", rn);
@@ -1642,19 +1722,13 @@ mainproc(as, arock)
     /*
      * Tell the kernel about each cell in the configuration.
      */
-    lookingForHomeCell = 1;
-
     afsconf_CellApply(cdir, ConfigCell, NULL);
     afsconf_CellAliasApply(cdir, ConfigCellAlias, NULL);
 
     /*
-     * If we're still looking for the home cell after the whole cell configuration database
-     * has been parsed, there's something wrong.
+     * Set the primary cell name.
      */
-    if (lookingForHomeCell) {
-       printf("%s: Can't find information for home cell '%s' in cell database!\n",
-              rn, LclCellName);
-    }
+    call_syscall(AFSOP_SET_THISCELL, LclCellName);
 
     /*
      * If the root volume has been explicitly set, tell the kernel.
@@ -1667,67 +1741,6 @@ mainproc(as, arock)
     }
 
     /*
-     * Tell the kernel some basic information about the workstation's cache.
-     */
-    if (afsd_verbose)
-       printf("%s: Calling AFSOP_CACHEINIT: %d stat cache entries, %d optimum cache files, %d blocks in the cache, flags = 0x%x, dcache entries %d\n",
-              rn, cacheStatEntries, cacheFiles, cacheBlocks, cacheFlags,
-              dCacheSize);
-    memset(&cparams, '\0', sizeof(cparams));
-    cparams.cacheScaches = cacheStatEntries;
-    cparams.cacheFiles = cacheFiles;
-    cparams.cacheBlocks = cacheBlocks;
-    cparams.cacheDcaches = dCacheSize;
-    cparams.cacheVolumes = vCacheSize;
-    cparams.chunkSize = chunkSize;
-    cparams.setTimeFlag = cacheSetTime;
-    cparams.memCacheFlag = cacheFlags;
-#ifdef notdef
-    cparams.inodes       = inodes;
-#endif
-    call_syscall(AFSOP_CACHEINIT, &cparams);
-    if (afsd_CloseSynch) 
-      call_syscall(AFSOP_CLOSEWAIT);
-
-    /*
-     * Sweep the workstation AFS cache directory, remembering the inodes of
-     * valid files and deleting extraneous files.  Keep sweeping until we
-     * have the right number of data cache files or we've swept too many
-     * times.
-     */
-    if (afsd_verbose)
-       printf("%s: Sweeping workstation's AFS cache directory.\n",
-              rn);
-    cacheIteration = 0;
-    /* Memory-cache based system doesn't need any of this */
-    if(!(cacheFlags & AFSCALL_INIT_MEMCACHE)) {
-       do {
-           cacheIteration++;
-           if (SweepAFSCache(&vFilesFound)) {
-               printf("%s: Error on sweep %d of workstation AFS cache \
-                       directory.\n", rn, cacheIteration);
-               exit(1);
-           }
-           if (afsd_verbose)
-               printf("%s: %d out of %d data cache files found in sweep %d.\n",
-                      rn, vFilesFound, cacheFiles, cacheIteration);
-       } while ((vFilesFound < cacheFiles) &&
-                (cacheIteration < MAX_CACHE_LOOPS));
-    } else if(afsd_verbose)
-       printf("%s: Using memory cache, not swept\n", rn);
-
-    /*
-     * Pass the kernel the name of the workstation cache file holding the 
-     * dcache entries.
-     */
-    if (afsd_debug)
-       printf("%s: Calling AFSOP_CACHEINFO: dcache file is '%s'\n",
-              rn, fullpn_DCacheFile);
-    /* once again, meaningless for a memory-based cache. */
-    if(!(cacheFlags & AFSCALL_INIT_MEMCACHE))
-       call_syscall(AFSOP_CACHEINFO, fullpn_DCacheFile);
-
-    /*
      * Pass the kernel the name of the workstation cache file holding the
      * volume information.
      */
index ab8d095..688fa68 100644 (file)
@@ -42,6 +42,9 @@
 #define        AFSOP_SET_DYNROOT        31     /* enable/disable dynroot support */
 #define        AFSOP_ADDCELLALIAS       32     /* create alias for existing cell */
 #define        AFSOP_SET_FAKESTAT       33     /* enable/disable fakestat support */
+#define        AFSOP_CELLINFO           34     /* set the cellinfo file name */
+#define        AFSOP_SET_THISCELL       35     /* set the primary cell */
+#define AFSOP_BASIC_INIT        36     /* used to be part of START_AFS */
 
 /* The range 20-30 is reserved for AFS system offsets in the afs_syscall */
 #define        AFSCALL_PIOCTL          20
index 0c82cc2..e658915 100644 (file)
@@ -101,3 +101,9 @@ proc GetCE64(
   OUT AFSDBCacheEntry64 *ce
 ) = 65536;
 
+proc GetCellByNum(
+  IN  afs_int32 cellNumber,
+  OUT string cellName<AFSNAMEMAX>,
+  OUT serverList *cellHosts
+) = 65537;
+
index c7f1c07..bffcf06 100644 (file)
@@ -681,6 +681,15 @@ afs_int32 SRXAFSCB_GetCellServDB(
     return RXGEN_OPCODE;
 }
 
+afs_int32 SRXAFSCB_GetCellByNum(
+    struct rx_call *a_call,
+    afs_int32 a_cellnum,
+    char **a_name,
+    serverList *a_hosts)
+{
+    return RXGEN_OPCODE;
+}
+
 /*------------------------------------------------------------------------
  * EXPORTED SRXAFSCB_GetLocalCell
  *
index c59b1ba..b7a7709 100644 (file)
@@ -163,12 +163,55 @@ register struct rx_connection *aconn; {
     return 0;
 }
 
-static PrintCacheEntries(aconn, aint32)
-int aint32;
-register struct rx_connection *aconn; {
+struct cell_cache {
+    afs_int32 cellnum;
+    char *cellname;
+    struct cell_cache *next;
+};
+
+static char *GetCellName(struct rx_connection *aconn, afs_int32 cellnum)
+{
+    static int no_getcellbynum;
+    static struct cell_cache *cache;
+    struct cell_cache *tcp;
+    int code;
+    char *cellname;
+    serverList sl;
+
+    if (no_getcellbynum)
+       return NULL;
+
+    for (tcp = cache; tcp; tcp = tcp->next)
+       if (tcp->cellnum == cellnum)
+           return tcp->cellname;
+
+    cellname = NULL;
+    sl.serverList_len = 0;
+    sl.serverList_val = NULL;
+    code = RXAFSCB_GetCellByNum(aconn, cellnum, &cellname, &sl);
+    if (code) {
+       if (code == RXGEN_OPCODE)
+           no_getcellbynum = 1;
+       return NULL;
+    }
+
+    if (sl.serverList_val)
+       free (sl.serverList_val);
+    tcp = malloc(sizeof(struct cell_cache));
+    tcp->next = cache;
+    tcp->cellnum = cellnum;
+    tcp->cellname = cellname;
+    cache = tcp;
+
+    return cellname;
+}
+
+static PrintCacheEntries(struct rx_connection *aconn, int aint32)
+{
     register int i;
     register afs_int32 code;
     struct AFSDBCacheEntry centry;
+    char *cellname;
 
     for(i=0;i<10000;i++) {
        code = RXAFSCB_GetCE(aconn, i, &centry);
@@ -189,8 +232,16 @@ register struct rx_connection *aconn; {
        if (!aint32 && !IsLocked(&centry.lock)) continue;
 
        /* otherwise print this entry */
-       printf("** Cache entry @ 0x%08x for %d.%d.%d.%d\n", centry.addr, centry.cell,
-              centry.netFid.Volume, centry.netFid.Vnode, centry.netFid.Unique);
+       printf("** Cache entry @ 0x%08x for %d.%d.%d.%d", centry.addr,
+              centry.cell, centry.netFid.Volume, centry.netFid.Vnode,
+              centry.netFid.Unique);
+
+       cellname = GetCellName(aconn, centry.cell);
+       if (cellname)
+           printf(" [%s]\n", cellname);
+       else
+           printf("\n");
+
        if (IsLocked(&centry.lock)) {
            printf("    locks: ");
            PrintLock(&centry.lock);
index 4b60827..24c6b83 100644 (file)
@@ -1028,6 +1028,8 @@ kdump()
 
     if (Dcells || Dall) {
        print_cells(1); /* Handle the afs_cells structures */
+       print_cellaliases(1);
+       print_cellnames(1);
     }
 
     if (Dusers || Dall) {
@@ -1145,6 +1147,7 @@ kdump()
 #if !defined(AFS_DARWIN_ENV) && !defined(AFS_FBSD_ENV)
 int Sum_cellnames=0, Sum_userstp=0, Sum_volnames=0, Sum_exps=0, Sum_nfssysnames=0;
 int Sum_vcachemvids=0, Sum_vcachelinkData=0, Sum_vcacheacc=0, Sum_vcachelocks=0;
+int Sum_cellaliases=0, Sum_cellname_names=0;
 
 int print_cells(pnt)
 int pnt;
@@ -1168,6 +1171,64 @@ int pnt;
        j++;
     }
     if (pnt) printf("... found %d 'afs_cells' entries\n", j);
+
+    return j;
+}
+
+int print_cellaliases(int pnt)
+{
+    off_t symoff;
+    struct cell_alias *ca, cae;
+    long j = 0;
+
+    if (pnt) printf("\n\nPrinting cell_alias list...\n");
+    findsym( "afs_cellalias_head", &symoff);
+    kread(kmem, symoff, (char *) &ca, sizeof ca);
+    while (ca) {
+       char alias[100], cell[100];
+
+       kread(kmem, (off_t) ca, (char *) &cae, sizeof cae);
+       kread(kmem, (off_t) cae.alias, alias, (KDUMP_SIZE_T)40);
+       alias[40] = '\0';
+       Sum_cellaliases += strlen(alias) + 1;
+       kread(kmem, (off_t) cae.cell, cell, (KDUMP_SIZE_T)40);
+       cell[40] = '\0';
+       Sum_cellaliases += strlen(cell) + 1;
+       if (pnt)
+           printf("%x: alias=%s cell=%s index=%d\n",
+                  ca, alias, cell, cae.index);
+       ca = cae.next;
+       j++;
+    }
+    if (pnt) printf("... found %d 'cell_alias' entries\n", j);
+
+    return j;
+}
+
+int print_cellnames(int pnt)
+{
+    off_t symoff;
+    struct cell_name *cn, cne;
+    long j = 0;
+
+    if (pnt) printf("\n\nPrinting cell_name list...\n");
+    findsym( "afs_cellname_head", &symoff);
+    kread(kmem, symoff, (char *) &cn, sizeof cn);
+    while (cn) {
+       char cellname[100];
+
+       kread(kmem, (off_t) cn, (char *) &cne, sizeof cne);
+       kread(kmem, (off_t) cne.cellname, cellname, (KDUMP_SIZE_T)40);
+       cellname[40] = '\0';
+       Sum_cellname_names += strlen(cellname) + 1;
+       if (pnt)
+           printf("%x: cellnum=%d cellname=%s used=%d\n",
+                  cn, cne.cellnum, cellname, cne.used);
+       cn = cne.next;
+       j++;
+    }
+    if (pnt) printf("... found %d 'cell_name' entries\n", j);
+
     return j;
 }
 
@@ -1736,6 +1797,18 @@ int pnt;
     T += j;
     printf("%20s:\t%8d bytes\t[%d cells/%d bytes each + %d bytes for cell names]\n", "Cell package", j, i, sizeof(struct cell), Sum_cellnames);
 
+    Sum_cellaliases=0;
+    i = print_cellaliases(0);
+    j = (i * sizeof(struct cell_alias)) + Sum_cellaliases;
+    T += j;
+    printf("%20s:\t%8d bytes\t[%d cell_aliases/%d bytes each + %d bytes for cell names]\n", "Cell package", j, i, sizeof(struct cell_alias), Sum_cellaliases);
+
+    Sum_cellname_names=0;
+    i = print_cellnames(0);
+    j = (i * sizeof(struct cell_name)) + Sum_cellname_names;
+    T += j;
+    printf("%20s:\t%8d bytes\t[%d cell_names/%d bytes each + %d bytes for cell name strings]\n", "Cell package", j, i, sizeof(struct cell_name), Sum_cellname_names);
+
     Sum_userstp=0;
     i = print_users(0);
     j = (i * sizeof(struct unixuser)) + Sum_userstp;
@@ -2243,9 +2316,9 @@ void print_cell(kmem, clep, ptr, pnt)
     cellName[40] = 0;
     Sum_cellnames += strlen(cellName)+1;
     if (pnt) {
-       printf("%lx: cell=%s, cellname=%s, states=%x, cindex=%d fsport=%d vlport=%d timeout=%d\n", ptr,
-              PrintIPAddr(clep->cell), cellName, clep->states, clep->cellIndex,
-              clep->fsport, clep->vlport, clep->timeout);
+       printf("%lx: cellname=%s, states=%x, cnum=%d, cindex=%d fsport=%d vlport=%d timeout=%d cnamep=%x\n", ptr,
+              cellName, clep->states, clep->cellNum, clep->cellIndex,
+              clep->fsport, clep->vlport, clep->timeout, clep->cnamep);
 #ifdef AFS33
        if (clep->lcellp)
            printf("\tlinked cellp %lx\n", clep->lcellp);
index 76722fd..c385748 100644 (file)
@@ -697,6 +697,16 @@ afs_int32 SRXAFSCB_GetCellServDB(
 }
 
 
+afs_int32 SRXAFSCB_GetCellByNum(
+    struct rx_call *a_call,
+    afs_int32 a_cellnum,
+    char **a_name,
+    serverList *a_hosts)
+{
+    return RXGEN_OPCODE;
+}
+
+
 /*------------------------------------------------------------------------
  * EXPORTED SRXAFSCB_GetLocalCell
  *