afsd -dynroot-sparse mode for hushed cells
[openafs.git] / src / afs / afs_cell.c
index 62fab7e..89d385d 100644 (file)
@@ -13,8 +13,6 @@
 #include <afsconfig.h>
 #include "afs/param.h"
 
-RCSID
-    ("$Header$");
 
 #include "afs/stds.h"
 #include "afs/sysincludes.h"   /* Standard vendor system headers */
@@ -35,36 +33,49 @@ afs_rwlock_t afs_xcell;             /* Export for cmdebug peeking at locks */
  * afs_LookupAFSDB: look up AFSDB for given cell name and create locally
  */
 
-#ifdef AFS_AFSDB_ENV
 afs_rwlock_t afsdb_client_lock;        /* Serializes client requests */
 afs_rwlock_t afsdb_req_lock;   /* Serializes client requests */
 static char afsdb_handler_running;     /* Protected by GLOCK */
 static char afsdb_handler_shutdown;    /* Protected by GLOCK */
 
+/* from cellconfig.h */
+#define MAXCELLCHARS    64
 static struct {
-    afs_rwlock_t lock;
+    /* lock moved to afsdb_req_lock for cmdebug */
     char pending;
     char complete;
     char *cellname;
-    afs_int32 *cellhosts;
-    int *timeout;
-    char **realname;
 } afsdb_req;
 
+/*!
+ * Terminate the AFSDB handler, used on shutdown.
+ */
 void
-afs_StopAFSDB()
+afs_StopAFSDB(void)
 {
     if (afsdb_handler_running) {
        afs_osi_Wakeup(&afsdb_req);
     } else {
        afsdb_handler_shutdown = 1;
        afs_termState = AFSOP_STOP_RXEVENT;
+       afs_osi_Wakeup(&afs_termState);
     }
 }
 
+/*!
+ * \brief Entry point for user-space AFSDB request handler.
+ * Reads cell data from kerlenMsg and add new cell, or alias.
+ * \param acellName Cell name. If a cell is found, it's name will be filled in here.
+ * \param acellNameLen Cell name length.
+ * \param kernelMsg Buffer containing data about host count, time out, and cell hosts ids.
+ * \return 0 for success, < 0 for error.
+ */
 int
 afs_AFSDBHandler(char *acellName, int acellNameLen, afs_int32 * kernelMsg)
 {
+    afs_int32 timeout, code;
+    afs_int32 cellHosts[AFS_MAXCELLHOSTS];
+
     if (afsdb_handler_shutdown)
        return -2;
     afsdb_handler_running = 1;
@@ -75,18 +86,29 @@ afs_AFSDBHandler(char *acellName, int acellNameLen, afs_int32 * kernelMsg)
 
        UpgradeSToWLock(&afsdb_req_lock, 684);
        hostCount = kernelMsg[0];
-       *afsdb_req.timeout = kernelMsg[1];
-       if (*afsdb_req.timeout)
-           *afsdb_req.timeout += osi_Time();
-       *afsdb_req.realname = afs_strdup(acellName);
+       timeout = kernelMsg[1];
+       if (timeout)
+           timeout += osi_Time();
 
-       for (i = 0; i < MAXCELLHOSTS; i++) {
+       for (i = 0; i < AFS_MAXCELLHOSTS; i++) {
            if (i >= hostCount)
-               afsdb_req.cellhosts[i] = 0;
+               cellHosts[i] = 0;
            else
-               afsdb_req.cellhosts[i] = kernelMsg[2 + i];
+               cellHosts[i] = kernelMsg[2 + i];
        }
 
+       if (hostCount)
+           code = afs_NewCell(acellName, cellHosts, CNoSUID, NULL, 0, 0, 
+                              timeout);
+
+       if (!hostCount || (code && code != EEXIST)) 
+           /* null out the cellname if the lookup failed */
+           afsdb_req.cellname = NULL;
+       else
+           /* If we found an alias, create it */
+           if (afs_strcasecmp(afsdb_req.cellname, acellName))
+               afs_NewCellAlias(afsdb_req.cellname, acellName);
+
        /* Request completed, wake up the relevant thread */
        afsdb_req.pending = 0;
        afsdb_req.complete = 1;
@@ -122,9 +144,13 @@ afs_AFSDBHandler(char *acellName, int acellNameLen, afs_int32 * kernelMsg)
     return 0;
 }
 
+/*!
+ * \brief Query the AFSDB handler and wait for response.
+ * \param  acellName
+ * \return 0 for success. < 0 is error.
+ */
 static int
-afs_GetCellHostsAFSDB(char *acellName, afs_int32 * acellHosts, int *timeout,
-                     char **realName)
+afs_GetCellHostsAFSDB(char *acellName)
 {
     AFS_ASSERT_GLOCK();
     if (!afsdb_handler_running)
@@ -133,11 +159,7 @@ afs_GetCellHostsAFSDB(char *acellName, afs_int32 * acellHosts, int *timeout,
     ObtainWriteLock(&afsdb_client_lock, 685);
     ObtainWriteLock(&afsdb_req_lock, 686);
 
-    *acellHosts = 0;
-    afsdb_req.cellname = afs_strdup(acellName);
-    afsdb_req.cellhosts = acellHosts;
-    afsdb_req.timeout = timeout;
-    afsdb_req.realname = realName;
+    afsdb_req.cellname = acellName;
 
     afsdb_req.complete = 0;
     afsdb_req.pending = 1;
@@ -150,59 +172,30 @@ afs_GetCellHostsAFSDB(char *acellName, afs_int32 * acellHosts, int *timeout,
        ObtainReadLock(&afsdb_req_lock);
     };
 
-    afs_osi_FreeStr(afsdb_req.cellname);
     ReleaseReadLock(&afsdb_req_lock);
     ReleaseWriteLock(&afsdb_client_lock);
 
-    if (*acellHosts)
+    if (afsdb_req.cellname) {
        return 0;
-    else
+    } else
        return ENOENT;
 }
-#endif
 
+
+/*! 
+ * Look up AFSDB for given cell name and create locally.
+ * \param acellName Cell name. 
+ */
 void
 afs_LookupAFSDB(char *acellName)
 {
-#ifdef AFS_AFSDB_ENV
-    afs_int32 *cellHosts;
-    char **realName=NULL;
     int code;
-    int *timeout=NULL;
-
-    if(!(cellHosts = afs_osi_Alloc(MAXCELLHOSTS * sizeof(afs_int32))))
-       goto done;
-
-    if(!(realName = afs_osi_Alloc(sizeof(char *))))
-       goto done;
-    *realName = NULL;
-
-    if(!(timeout = afs_osi_Alloc(sizeof(int))))
-       goto done;
-
-    code = afs_GetCellHostsAFSDB(acellName, cellHosts, timeout, realName);
-    if (code)
-       goto done;
-    code = afs_NewCell(*realName, cellHosts, CNoSUID, NULL, 0, 0, *timeout);
-    if (code && code != EEXIST)
-       goto done;
-
-    /* If we found an alias, create it */
-    if (afs_strcasecmp(acellName, *realName))
-       afs_NewCellAlias(acellName, *realName);
-
-      done:
-    afs_Trace2(afs_iclSetp, CM_TRACE_AFSDB, ICL_TYPE_STRING, acellName, 
-              ICL_TYPE_INT32, code);
-    if(timeout)
-       afs_osi_Free(timeout, sizeof(int));
-    if (realName && *realName)
-       afs_osi_FreeStr(*realName);
-    if(realName)
-       afs_osi_Free(realName, sizeof(char *));
-    if(cellHosts)
-       afs_osi_Free(cellHosts, MAXCELLHOSTS * sizeof(afs_int32));
-#endif
+    char *cellName = afs_strdup(acellName);
+
+    code = afs_GetCellHostsAFSDB(cellName);
+    afs_Trace2(afs_iclSetp, CM_TRACE_AFSDB, ICL_TYPE_STRING, cellName, 
+               ICL_TYPE_INT32, code);
+    afs_osi_FreeStr(cellName);
 }
 
 /*
@@ -217,11 +210,17 @@ afs_LookupAFSDB(char *acellName)
  */
 
 struct cell_name *afs_cellname_head;   /* Export for kdump */
-static ino_t afs_cellname_inode;
+static afs_dcache_id_t afs_cellname_inode;
 static int afs_cellname_inode_set;
 static int afs_cellname_dirty;
 static afs_int32 afs_cellnum_next;
 
+/*!
+ * Create a new cell name, optional cell number.
+ * \param  name Name of cell.
+ * \param cellnum Cellname number.
+ * \return Initialized structure.
+ */
 static struct cell_name *
 afs_cellname_new(char *name, afs_int32 cellnum)
 {
@@ -243,6 +242,11 @@ afs_cellname_new(char *name, afs_int32 cellnum)
     return cn;
 }
 
+/*!
+ * Look up a cell name by id.
+ * \param cellnum
+ * \return 
+ */
 static struct cell_name *
 afs_cellname_lookup_id(afs_int32 cellnum)
 {
@@ -255,6 +259,11 @@ afs_cellname_lookup_id(afs_int32 cellnum)
     return NULL;
 }
 
+/*!
+ * Look up a cell name.
+ * \param name Cell name.
+ * \return 
+ */
 static struct cell_name *
 afs_cellname_lookup_name(char *name)
 {
@@ -267,6 +276,10 @@ afs_cellname_lookup_name(char *name)
     return NULL;
 }
 
+/*!
+ * Note that this cell name was referenced somewhere.
+ * \param  cn
+ */
 static void
 afs_cellname_ref(struct cell_name *cn)
 {
@@ -276,8 +289,14 @@ afs_cellname_ref(struct cell_name *cn)
     }
 }
 
+/*!
+ * \brief Load the list of cells from given inode.
+ * \param inode Source inode.
+ * \param lookupcode 
+ * \return 0 for success. < 0 for error.
+ */
 int
-afs_cellname_init(ino_t inode, int lookupcode)
+afs_cellname_init(afs_dcache_id_t *inode, int lookupcode)
 {
     struct osi_file *tfile;
     int cc, off = 0;
@@ -302,7 +321,7 @@ afs_cellname_init(ino_t inode, int lookupcode)
        return EIO;
     }
 
-    afs_cellname_inode = inode;
+    afs_copy_inode(&afs_cellname_inode, inode);
     afs_cellname_inode_set = 1;
 
     while (1) {
@@ -354,6 +373,9 @@ afs_cellname_init(ino_t inode, int lookupcode)
     return 0;
 }
 
+/*!
+ * Write in-kernel list of cells to disk.
+ */
 int
 afs_cellname_write(void)
 {
@@ -369,7 +391,7 @@ afs_cellname_write(void)
     ObtainWriteLock(&afs_xcell, 693);
     afs_cellname_dirty = 0;
     off = 0;
-    tfile = osi_UFSOpen(afs_cellname_inode);
+    tfile = osi_UFSOpen(&afs_cellname_inode);
     if (!tfile) {
        ReleaseWriteLock(&afs_xcell);
        return EIO;
@@ -424,6 +446,11 @@ struct cell_alias *afs_cellalias_head;     /* Export for kdump */
 static afs_int32 afs_cellalias_index;
 static int afs_CellOrAliasExists_nl(char *aname);      /* Forward declaration */
 
+/*!
+ * Look up cell alias by alias name.
+ * \param  alias 
+ * \return Found struct or NULL.
+ */
 static struct cell_alias *
 afs_FindCellAlias(char *alias)
 {
@@ -435,6 +462,11 @@ afs_FindCellAlias(char *alias)
     return tc;
 }
 
+/*!
+ * Get cell alias by index (starting at 0).
+ * \param index Cell index. 
+ * \return Found struct or null.
+ */
 struct cell_alias *
 afs_GetCellAlias(int index)
 {
@@ -449,12 +481,24 @@ afs_GetCellAlias(int index)
     return tc;
 }
 
+
+ /*!
+  * Put back a cell alias returned by Find or Get.
+  * \param a Alias. 
+  * \return 
+  */
 void
 afs_PutCellAlias(struct cell_alias *a)
 {
     return;
 }
 
+/*!
+ * Create new cell alias entry and update dynroot vnode.
+ * \param alias
+ * \param cell
+ * \return 
+ */
 afs_int32
 afs_NewCellAlias(char *alias, char *cell)
 {
@@ -505,9 +549,13 @@ afs_NewCellAlias(char *alias, char *cell)
  */
 
 struct afs_q CellLRU;          /* Export for kdump */
-static char *afs_thiscell;
+static char *afs_thiscell = NULL;
 afs_int32 afs_cellindex;       /* Export for kdump */
 
+/*!
+ * Bump given cell up to the front of the LRU queue.
+ * \param c Cell to set. 
+ */
 static void
 afs_UpdateCellLRU(struct cell *c)
 {
@@ -517,6 +565,11 @@ afs_UpdateCellLRU(struct cell *c)
     ReleaseWriteLock(&afs_xcell);
 }
 
+/*!
+ * Look up cell information in AFSDB if timeout expired
+ * \param ac Cell to be refreshed.
+ * \return 
+ */
 static void
 afs_RefreshCell(struct cell *ac)
 {
@@ -526,6 +579,14 @@ afs_RefreshCell(struct cell *ac)
        afs_LookupAFSDB(ac->cellName);
 }
 
+/*! 
+ * Execute a callback for each existing cell, without a lock on afs_xcell.
+ * Iterate on CellLRU, and execute a callback for each cell until given arguments are met.
+ * \see afs_TraverseCells
+ * \param cb Traversal callback for each cell.
+ * \param arg Callback arguments.
+ * \return Found data or NULL.
+ */
 static void *
 afs_TraverseCells_nl(void *(*cb) (struct cell *, void *), void *arg)
 {
@@ -551,6 +612,13 @@ afs_TraverseCells_nl(void *(*cb) (struct cell *, void *), void *arg)
     return ret;
 }
 
+/*!
+ * Execute a callback for each existing cell, with a lock on afs_xcell.
+ * \see afs_TraverseCells_nl
+ * \param cb Traversal callback for each cell.
+ * \param arg 
+ * \return Found data or NULL.
+ */
 void *
 afs_TraverseCells(void *(*cb) (struct cell *, void *), void *arg)
 {
@@ -563,6 +631,12 @@ afs_TraverseCells(void *(*cb) (struct cell *, void *), void *arg)
     return ret;
 }
 
+/*!
+ * Useful traversal callback: Match by name.
+ * \param cell 
+ * \param arg Cell name (compared with cell->cellName).
+ * \return Returns found cell or NULL.
+ */
 static void *
 afs_choose_cell_by_name(struct cell *cell, void *arg)
 {
@@ -574,6 +648,12 @@ afs_choose_cell_by_name(struct cell *cell, void *arg)
     }
 }
 
+/*!
+ * Useful traversal callback: Match by handle.
+ * \param cell 
+ * \param arg Cell handle (compared with cell->cellHandle).
+ * \return Returns found cell or NULL.
+ */
 static void *
 afs_choose_cell_by_handle(struct cell *cell, void *arg)
 {
@@ -585,30 +665,62 @@ afs_choose_cell_by_handle(struct cell *cell, void *arg)
     }
 }
 
+/*!
+ * Useful traversal callback: Match by cell number.
+ * \param cell 
+ * \param arg Cell number (compared with cell->cellNum).
+ * \return Returns found cell or NULL.
+ */
 static void *
 afs_choose_cell_by_num(struct cell *cell, void *arg)
 {
     return (cell->cellNum == *((afs_int32 *) arg)) ? cell : NULL;
 }
 
+/*!
+ * Useful traversal callback: Match by index.
+ * \param cell 
+ * \param arg Cell index (compared with cell->cellIndex).
+ * \return Returns found cell or NULL.
+ */
 static void *
 afs_choose_cell_by_index(struct cell *cell, void *arg)
 {
     return (cell->cellIndex == *((afs_int32 *) arg)) ? cell : NULL;
 }
 
+/*!
+ * Return a cell with a given name, if it exists. No lock version.
+ * Does not check AFSDB.
+ * \param acellName Cell name.
+ * \param locktype Type of lock to be used (not used).
+ * \return 
+ */
 static struct cell *
 afs_FindCellByName_nl(char *acellName, afs_int32 locktype)
 {
     return afs_TraverseCells_nl(&afs_choose_cell_by_name, acellName);
 }
 
+/*!
+ * Return a cell with a given name, if it exists.It uses locks.
+ * Does not check AFSDB.
+ * \param acellName Cell name.
+ * \param locktype Type of lock to be used.
+ * \return 
+ */
 static struct cell *
 afs_FindCellByName(char *acellName, afs_int32 locktype)
 {
     return afs_TraverseCells(&afs_choose_cell_by_name, acellName);
 }
 
+/*!
+ * Same as FindCellByName but tries AFSDB if not found.
+ * \param acellName Cell name.
+ * \param locktype Type of lock to be used.
+ * \return 
+ */
 struct cell *
 afs_GetCellByName(char *acellName, afs_int32 locktype)
 {
@@ -628,6 +740,12 @@ afs_GetCellByName(char *acellName, afs_int32 locktype)
     return tc;
 }
 
+/*!
+ * Return a cell with a given cell number.
+ * \param cellnum Cell number.
+ * \param locktype Lock to be used. 
+ * \return 
+ */
 struct cell *
 afs_GetCell(afs_int32 cellnum, afs_int32 locktype)
 {
@@ -647,6 +765,12 @@ afs_GetCell(afs_int32 cellnum, afs_int32 locktype)
     return tc;
 }
 
+/*!
+ * Same as GetCell, but does not try to refresh the data.
+ * \param cellnum Cell number.
+ * \param locktype What lock should be used.
+ * \return 
+ */
 struct cell *
 afs_GetCellStale(afs_int32 cellnum, afs_int32 locktype)
 {
@@ -660,6 +784,12 @@ afs_GetCellStale(afs_int32 cellnum, afs_int32 locktype)
     return tc;
 }
 
+/*!
+ * Return a cell with a given index number (starting at 0). Update CellLRU as well.
+ * \param index
+ * \param locktype Type of lock used.
+ * \return 
+ */
 struct cell *
 afs_GetCellByIndex(afs_int32 index, afs_int32 locktype)
 {
@@ -671,6 +801,12 @@ afs_GetCellByIndex(afs_int32 index, afs_int32 locktype)
     return tc;
 }
 
+/*!
+ * Return a cell with a given handle..
+ * \param index
+ * \param locktype Type of lock used.
+ * \return 
+ */
 struct cell *
 afs_GetCellByHandle(void *handle, afs_int32 locktype)
 {
@@ -682,12 +818,22 @@ afs_GetCellByHandle(void *handle, afs_int32 locktype)
     return tc;
 }
 
+/*!
+ * Return primary cell, if any.
+ * \param locktype Type of lock used.
+ * \return 
+ */
 struct cell *
 afs_GetPrimaryCell(afs_int32 locktype)
 {
     return afs_GetCellByName(afs_thiscell, locktype);
 }
 
+/*!
+ * Returns true if the given cell is the primary cell.
+ * \param cell
+ * \return 
+ */
 int
 afs_IsPrimaryCell(struct cell *cell)
 {
@@ -705,6 +851,11 @@ afs_IsPrimaryCell(struct cell *cell)
     }
 }
 
+/*!
+ * Returns afs_IsPrimaryCell(afs_GetCell(cellnum)).
+ * \param cellnum 
+ * \return 
+ */
 int
 afs_IsPrimaryCellNum(afs_int32 cellnum)
 {
@@ -720,6 +871,11 @@ afs_IsPrimaryCellNum(afs_int32 cellnum)
     return primary;
 }
 
+/*!
+ * Set the primary cell name to the given cell name.
+ * \param acellName Cell name. 
+ * \return 0 for success, < 0 for error.
+ */
 afs_int32
 afs_SetPrimaryCell(char *acellName)
 {
@@ -731,6 +887,17 @@ afs_SetPrimaryCell(char *acellName)
     return 0;
 }
 
+/*!
+ * Create or update a cell entry. 
+ * \param acellName Name of cell.
+ * \param acellHosts Array of hosts that this cell has.
+ * \param aflags Cell flags.
+ * \param linkedcname 
+ * \param fsport File server port.
+ * \param vlport Volume server port.
+ * \param timeout Cell timeout value, 0 means static AFSDB entry.
+ * \return 
+ */
 afs_int32
 afs_NewCell(char *acellName, afs_int32 * acellHosts, int aflags,
            char *linkedcname, u_short fsport, u_short vlport, int timeout)
@@ -747,12 +914,12 @@ afs_NewCell(char *acellName, afs_int32 * acellHosts, int aflags,
        aflags &= ~CNoSUID;
     } else {
        tc = (struct cell *)afs_osi_Alloc(sizeof(struct cell));
-       memset((char *)tc, 0, sizeof(*tc));
+       memset(tc, 0, sizeof(*tc));
        tc->cellName = afs_strdup(acellName);
        tc->fsport = AFS_FSPORT;
        tc->vlport = AFS_VLPORT;
        AFS_MD5_String(tc->cellHandle, tc->cellName, strlen(tc->cellName));
-       RWLOCK_INIT(&tc->lock, "cell lock");
+       AFS_RWLOCK_INIT(&tc->lock, "cell lock");
        newc = 1;
        aflags |= CNoSUID;
     }
@@ -772,7 +939,7 @@ afs_NewCell(char *acellName, afs_int32 * acellHosts, int aflags,
     /* 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++) {
+    for (i = 0; i < AFS_MAXCELLHOSTS; i++) {
        if (!tc->cellHosts[i])
            break;
        tc->cellHosts[i]->flags &= ~SRVR_ISDOWN;
@@ -803,9 +970,10 @@ afs_NewCell(char *acellName, afs_int32 * acellHosts, int aflags,
     }
     tc->states |= aflags;
     tc->timeout = timeout;
-
-    memset((char *)tc->cellHosts, 0, sizeof(tc->cellHosts));
-    for (i = 0; i < MAXCELLHOSTS; i++) {
+    
+    memset(tc->cellHosts, 0, sizeof(tc->cellHosts));
+    for (i = 0; i < AFS_MAXCELLHOSTS; i++) {
+       /* Get server for each host and link this cell in.*/    
        struct server *ts;
        afs_uint32 temp = acellHosts[i];
        if (!temp)
@@ -813,11 +981,13 @@ afs_NewCell(char *acellName, afs_int32 * acellHosts, int aflags,
        ts = afs_GetServer(&temp, 1, 0, tc->vlport, WRITE_LOCK, NULL, 0);
        ts->cell = tc;
        ts->flags &= ~SRVR_ISGONE;
+       /* Set the server as a host of the new cell. */
        tc->cellHosts[i] = ts;
        afs_PutServer(ts, WRITE_LOCK);
     }
-    afs_SortServers(tc->cellHosts, MAXCELLHOSTS);      /* randomize servers */
-
+    afs_SortServers(tc->cellHosts, AFS_MAXCELLHOSTS);  /* randomize servers */
+       
+    /* New cell: Build and add to LRU cell queue. */
     if (newc) {
        struct cell_name *cn;
 
@@ -835,7 +1005,8 @@ afs_NewCell(char *acellName, afs_int32 * acellHosts, int aflags,
     ReleaseWriteLock(&tc->lock);
     ReleaseWriteLock(&afs_xcell);
     afs_PutCell(tc, 0);
-    afs_DynrootInvalidate();
+    if (!aflags & CHush)
+       afs_DynrootInvalidate();
     return 0;
 
   bad:
@@ -859,27 +1030,43 @@ afs_NewCell(char *acellName, afs_int32 * acellHosts, int aflags,
  * afs_CellNumValid: check if a cell number is valid (also set the used flag)
  */
 
+/*!
+ * Perform whatever initialization is necessary.
+ */
 void
-afs_CellInit()
+afs_CellInit(void)
 {
-    RWLOCK_INIT(&afs_xcell, "afs_xcell");
-#ifdef AFS_AFSDB_ENV
-    RWLOCK_INIT(&afsdb_client_lock, "afsdb_client_lock");
-    RWLOCK_INIT(&afsdb_req_lock, "afsdb_req_lock");
-#endif
+    static char CellInit_done = 0;
+
+    if (CellInit_done)
+       return;
+
+    CellInit_done = 1;
+
+    AFS_RWLOCK_INIT(&afs_xcell, "afs_xcell");
+    AFS_RWLOCK_INIT(&afsdb_client_lock, "afsdb_client_lock");
+    AFS_RWLOCK_INIT(&afsdb_req_lock, "afsdb_req_lock");
     QInit(&CellLRU);
 
     afs_cellindex = 0;
     afs_cellalias_index = 0;
 }
 
+/*!
+ * Called on shutdown, should deallocate memory, etc.
+ */
 void
-shutdown_cell()
+shutdown_cell(void)
 {
     struct afs_q *cq, *tq;
     struct cell *tc;
 
-    RWLOCK_INIT(&afs_xcell, "afs_xcell");
+#ifdef AFS_CACHE_VNODE_PATH
+    if (cacheDiskType != AFS_FCACHE_TYPE_MEM) {
+       afs_osi_FreeStr(afs_cellname_inode.ufs);
+    }
+#endif
+    AFS_RWLOCK_INIT(&afs_xcell, "afs_xcell");
 
     for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
        tc = QTOC(cq);
@@ -903,6 +1090,11 @@ shutdown_cell()
 }
 }
 
+/*!
+ * Remove a server from a cell's server list.
+ * \param srvp Server to be removed.
+ * \return 
+ */
 void
 afs_RemoveCellEntry(struct server *srvp)
 {
@@ -915,7 +1107,7 @@ afs_RemoveCellEntry(struct server *srvp)
 
     /* Remove the server structure from the cell list - if there */
     ObtainWriteLock(&tc->lock, 200);
-    for (j = k = 0; j < MAXCELLHOSTS; j++) {
+    for (j = k = 0; j < AFS_MAXCELLHOSTS; j++) {
        if (!tc->cellHosts[j])
            break;
        if (tc->cellHosts[j] != srvp) {
@@ -925,12 +1117,17 @@ afs_RemoveCellEntry(struct server *srvp)
     if (k == 0) {
        /* What do we do if we remove the last one? */
     }
-    for (; k < MAXCELLHOSTS; k++) {
+    for (; k < AFS_MAXCELLHOSTS; k++) {
        tc->cellHosts[k] = 0;
     }
     ReleaseWriteLock(&tc->lock);
 }
 
+/*!
+ * Check if the given name exists as a cell or alias. Does not lock afs_xcell.
+ * \param aname 
+ * \return 
+ */
 static int
 afs_CellOrAliasExists_nl(char *aname)
 {
@@ -952,6 +1149,11 @@ afs_CellOrAliasExists_nl(char *aname)
     return 0;
 }
 
+/*!
+ * Check if the given name exists as a cell or alias. Locks afs_xcell.
+ * \param aname
+ * \return 
+ */
 int
 afs_CellOrAliasExists(char *aname)
 {
@@ -964,6 +1166,11 @@ afs_CellOrAliasExists(char *aname)
     return ret;
 }
 
+/*!
+ * Check if a cell number is valid (also set the used flag).
+ * \param cellnum 
+ * \return 1 - true, 0 - false
+ */
 int
 afs_CellNumValid(afs_int32 cellnum)
 {