Index: openafs/src/WINNT/afsclass/afsclassfn.cpp
diff -c openafs/src/WINNT/afsclass/afsclassfn.cpp:1.6 openafs/src/WINNT/afsclass/afsclassfn.cpp:1.6.4.1
*** openafs/src/WINNT/afsclass/afsclassfn.cpp:1.6	Sat Nov  5 01:47:44 2005
--- openafs/src/WINNT/afsclass/afsclassfn.cpp	Thu Jul 19 11:56:53 2007
***************
*** 51,59 ****
     AfsClass_Enter();
     NOTIFYCALLBACK::SendNotificationToAll (evtGetServerLogFileBegin, lpiServer, pszRemote, 0);
  
!    PVOID hCell;
!    PVOID hBOS;
!    LPSERVER lpServer;
     if ((lpServer = lpiServer->OpenServer (&status)) == NULL)
        rc = FALSE;
     else
--- 51,59 ----
     AfsClass_Enter();
     NOTIFYCALLBACK::SendNotificationToAll (evtGetServerLogFileBegin, lpiServer, pszRemote, 0);
  
!    PVOID hCell = NULL;
!    PVOID hBOS = NULL;
!    LPSERVER lpServer = NULL;
     if ((lpServer = lpiServer->OpenServer (&status)) == NULL)
        rc = FALSE;
     else
***************
*** 387,394 ****
     AfsClass_Enter();
     NOTIFYCALLBACK::SendNotificationToAll (evtRestartServiceBegin, lpiRestart);
  
!    PVOID hCell;
!    PVOID hBOS;
     LPSERVER lpServer;
     if ((lpServer = lpiRestart->OpenServer (&status)) == NULL)
        rc = FALSE;
--- 387,394 ----
     AfsClass_Enter();
     NOTIFYCALLBACK::SendNotificationToAll (evtRestartServiceBegin, lpiRestart);
  
!    PVOID hCell = NULL;
!    PVOID hBOS = NULL;
     LPSERVER lpServer;
     if ((lpServer = lpiRestart->OpenServer (&status)) == NULL)
        rc = FALSE;
***************
*** 489,497 ****
  
     // Obtain hCell and hVOS
     //
!    PVOID hCell;
     PVOID hVOS = NULL;
!    LPSERVER lpServer;
     if ((lpServer = lpiAggregate->OpenServer (&status)) == NULL)
        rc = FALSE;
     else
--- 489,497 ----
  
     // Obtain hCell and hVOS
     //
!    PVOID hCell = NULL;
     PVOID hVOS = NULL;
!    LPSERVER lpServer = NULL;
     if ((lpServer = lpiAggregate->OpenServer (&status)) == NULL)
        rc = FALSE;
     else
***************
*** 603,611 ****
  
     // Obtain hCell and hVOS
     //
!    PVOID hCell;
     PVOID hVOS = NULL;
!    LPSERVER lpServer;
     if ((lpServer = lpiFileset->OpenServer (&status)) == NULL)
        rc = FALSE;
     else
--- 603,611 ----
  
     // Obtain hCell and hVOS
     //
!    PVOID hCell = NULL;
     PVOID hVOS = NULL;
!    LPSERVER lpServer = NULL;
     if ((lpServer = lpiFileset->OpenServer (&status)) == NULL)
        rc = FALSE;
     else
***************
*** 1151,1157 ****
           lpServer->Close();
           }
  
-       LPCELL lpCell;
        if ((lpCell = lpiServer->OpenCell (&status)) == NULL)
           rc = FALSE;
        else
--- 1151,1156 ----
Index: openafs/src/WINNT/afsclass/c_svr.cpp
diff -c openafs/src/WINNT/afsclass/c_svr.cpp:1.5 openafs/src/WINNT/afsclass/c_svr.cpp:1.5.4.1
*** openafs/src/WINNT/afsclass/c_svr.cpp:1.5	Sat Nov  5 01:47:44 2005
--- openafs/src/WINNT/afsclass/c_svr.cpp	Thu Jul 19 11:56:53 2007
***************
*** 783,790 ****
     // the lpServer pointer won't have been freed.)
     // 
     PVOID hCell;
!    PVOID hBOS;
!    PVOID hVOS;
  
     TCHAR szServer[ cchNAME ];
  
--- 783,790 ----
     // the lpServer pointer won't have been freed.)
     // 
     PVOID hCell;
!    PVOID hBOS = NULL;
!    PVOID hVOS = NULL;
  
     TCHAR szServer[ cchNAME ];
  
Index: openafs/src/WINNT/afsd/cm_buf.c
diff -c openafs/src/WINNT/afsd/cm_buf.c:1.31.2.16 openafs/src/WINNT/afsd/cm_buf.c:1.31.2.18
*** openafs/src/WINNT/afsd/cm_buf.c:1.31.2.16	Sun Jun 10 13:00:07 2007
--- openafs/src/WINNT/afsd/cm_buf.c	Thu Aug  9 01:33:56 2007
***************
*** 593,598 ****
--- 593,599 ----
      long code = 0;
      long isdirty = 0;
      cm_scache_t * scp = NULL;
+     osi_hyper_t offset;
  
      osi_assert(bp->magic == CM_BUF_MAGIC);
  
***************
*** 603,611 ****
  	scp = cm_FindSCache(&bp->fid);
  	if (scp) {
  	    osi_Log2(buf_logp, "buf_CleanAsyncLocked starts I/O on scp 0x%p buf 0x%p", scp, bp);
! 	    code = (*cm_buf_opsp->Writep)(scp, &bp->offset,
! 					   cm_data.buf_blockSize, 0, bp->userp,
! 					   reqp);
  	    osi_Log3(buf_logp, "buf_CleanAsyncLocked I/O on scp 0x%p buf 0x%p, done=%d", scp, bp, code);
  
  	    cm_ReleaseSCache(scp);
--- 604,613 ----
  	scp = cm_FindSCache(&bp->fid);
  	if (scp) {
  	    osi_Log2(buf_logp, "buf_CleanAsyncLocked starts I/O on scp 0x%p buf 0x%p", scp, bp);
! 
!             offset = bp->offset;
!             LargeIntegerAdd(offset, ConvertLongToLargeInteger(bp->dirty_offset));
! 	    code = (*cm_buf_opsp->Writep)(scp, &offset, bp->dirty_length, 0, bp->userp, reqp);
  	    osi_Log3(buf_logp, "buf_CleanAsyncLocked I/O on scp 0x%p buf 0x%p, done=%d", scp, bp, code);
  
  	    cm_ReleaseSCache(scp);
***************
*** 623,628 ****
--- 625,632 ----
  	if (code == CM_ERROR_NOSUCHFILE){
  	    bp->flags &= ~CM_BUF_DIRTY;
  	    bp->flags |= CM_BUF_ERROR;
+             bp->dirty_offset = 0;
+             bp->dirty_length = 0;
  	    bp->error = CM_ERROR_NOSUCHFILE;
  	    bp->dataVersion = -1; /* bad */
  	    bp->dirtyCounter++;
***************
*** 1034,1045 ****
          /* load the page; freshly created pages should be idle */
          osi_assert(!(bp->flags & (CM_BUF_READING | CM_BUF_WRITING)));
  
-         /* setup offset, event */
- #ifndef DJGPP  /* doesn't seem to be used */
-         bp->over.Offset = bp->offset.LowPart;
-         bp->over.OffsetHigh = bp->offset.HighPart;
- #endif /* !DJGPP */
- 
          /* start the I/O; may drop lock */
          bp->flags |= CM_BUF_READING;
          code = (*cm_buf_opsp->Readp)(bp, cm_data.buf_blockSize, &tcount, NULL);
--- 1038,1043 ----
***************
*** 1174,1215 ****
   *
   * The buffer must be locked before calling this routine.
   */
! void buf_SetDirty(cm_buf_t *bp)
  {
      osi_assert(bp->magic == CM_BUF_MAGIC);
      osi_assert(bp->refCount > 0);
! 	
      if (bp->flags & CM_BUF_DIRTY) {
  	osi_Log1(buf_logp, "buf_SetDirty 0x%p already dirty", bp);
      } else {
  	osi_Log1(buf_logp, "buf_SetDirty 0x%p", bp);
-     }
-     /* set dirty bit */
-     bp->flags |= CM_BUF_DIRTY;
  
!     /* and turn off EOF flag, since it has associated data now */
!     bp->flags &= ~CM_BUF_EOF;
  
!     /* and add to the dirty list.  
!      * we obtain a hold on the buffer for as long as it remains 
!      * in the list.  buffers are only removed from the list by 
!      * the buf_IncrSyncer function regardless of when else the
!      * dirty flag might be cleared.
!      *
!      * This should never happen but just in case there is a bug
!      * elsewhere, never add to the dirty list if the buffer is 
!      * already there.
!      */
!     lock_ObtainWrite(&buf_globalLock);
!     if (bp->dirtyp == NULL && cm_data.buf_dirtyListEndp != bp) {
! 	buf_HoldLocked(bp);
! 	if (!cm_data.buf_dirtyListp) {
! 	    cm_data.buf_dirtyListp = cm_data.buf_dirtyListEndp = bp;
! 	} else {
! 	    cm_data.buf_dirtyListEndp->dirtyp = bp;
! 	    cm_data.buf_dirtyListEndp = bp;
! 	}
! 	bp->dirtyp = NULL;
      }
      lock_ReleaseWrite(&buf_globalLock);
  }
--- 1172,1233 ----
   *
   * The buffer must be locked before calling this routine.
   */
! void buf_SetDirty(cm_buf_t *bp, afs_uint32 offset, afs_uint32 length)
  {
      osi_assert(bp->magic == CM_BUF_MAGIC);
      osi_assert(bp->refCount > 0);
! 
!     lock_ObtainWrite(&buf_globalLock);
      if (bp->flags & CM_BUF_DIRTY) {
+ 
  	osi_Log1(buf_logp, "buf_SetDirty 0x%p already dirty", bp);
+ 
+         if (bp->dirty_offset <= offset) {
+             if (bp->dirty_offset + bp->dirty_length >= offset + length) {
+                 /* dirty_length remains the same */
+             } else {
+                 bp->dirty_length = offset + length - bp->dirty_offset;
+             }
+         } else /* bp->dirty_offset > offset */ {
+             if (bp->dirty_offset + bp->dirty_length >= offset + length) {
+                 bp->dirty_length = bp->dirty_offset + bp->dirty_length - offset;
+             } else {
+                 bp->dirty_length = length;
+             }
+             bp->dirty_offset = offset;
+         }
      } else {
  	osi_Log1(buf_logp, "buf_SetDirty 0x%p", bp);
  
!         /* set dirty bit */
!         bp->flags |= CM_BUF_DIRTY;
  
!         /* and turn off EOF flag, since it has associated data now */
!         bp->flags &= ~CM_BUF_EOF;
! 
!         bp->dirty_offset = offset;
!         bp->dirty_length = length;
! 
!         /* and add to the dirty list.  
!          * we obtain a hold on the buffer for as long as it remains 
!          * in the list.  buffers are only removed from the list by 
!          * the buf_IncrSyncer function regardless of when else the
!          * dirty flag might be cleared.
!          *
!          * This should never happen but just in case there is a bug
!          * elsewhere, never add to the dirty list if the buffer is 
!          * already there.
!          */
!         if (bp->dirtyp == NULL && cm_data.buf_dirtyListEndp != bp) {
!             buf_HoldLocked(bp);
!             if (!cm_data.buf_dirtyListp) {
!                 cm_data.buf_dirtyListp = cm_data.buf_dirtyListEndp = bp;
!             } else {
!                 cm_data.buf_dirtyListEndp->dirtyp = bp;
!                 cm_data.buf_dirtyListEndp = bp;
!             }
!             bp->dirtyp = NULL;
!         }
      }
      lock_ReleaseWrite(&buf_globalLock);
  }
***************
*** 1392,1397 ****
--- 1410,1417 ----
              if (LargeIntegerLessThanOrEqualTo(*sizep, bufp->offset)) {
                  /* truncating the entire page */
                  bufp->flags &= ~CM_BUF_DIRTY;
+                 bufp->dirty_offset = 0;
+                 bufp->dirty_length = 0;
                  bufp->dataVersion = -1;	/* known bad */
                  bufp->dirtyCounter++;
              }
***************
*** 1511,1516 ****
--- 1531,1564 ----
      return code;
  }       
  
+ /* Must be called with scp->mx held */
+ long buf_ForceDataVersion(cm_scache_t * scp, afs_uint32 fromVersion, afs_uint32 toVersion)
+ {
+     cm_buf_t * bp;
+     cm_buf_t * nbp;
+     unsigned int i;
+     int found = 0;
+ 
+     i = BUF_FILEHASH(&scp->fid);
+ 
+     lock_ObtainWrite(&buf_globalLock);
+ 
+     for (bp = cm_data.buf_fileHashTablepp[i]; bp; bp = bp->fileHashp) {
+         if (cm_FidCmp(&bp->fid, &scp->fid) == 0) {
+             if (bp->dataVersion == fromVersion) {
+                 bp->dataVersion = toVersion;
+                 found = 1;
+             }
+         }
+     }
+     lock_ReleaseWrite(&buf_globalLock);
+ 
+     if (found)
+         return 0;
+     else
+         return ENOENT;
+ }
+ 
  long buf_CleanVnode(struct cm_scache *scp, cm_user_t *userp, cm_req_t *reqp)
  {
      long code = 0;
***************
*** 1702,1709 ****
  {
      cm_buf_t *bp;
      afs_uint32 bcount = 0;
  
!     for (bp = cm_data.buf_allp; bp; bp=bp->allp, bcount++) {
  	if (!cm_FidCmp(fidp, &bp->fid) && (bp->flags & CM_BUF_DIRTY))
  	    return 1;
      }
--- 1750,1760 ----
  {
      cm_buf_t *bp;
      afs_uint32 bcount = 0;
+     afs_uint32 i;
  
!     i = BUF_FILEHASH(fidp);
! 
!     for (bp = cm_data.buf_fileHashTablepp[i]; bp; bp=bp->allp, bcount++) {
  	if (!cm_FidCmp(fidp, &bp->fid) && (bp->flags & CM_BUF_DIRTY))
  	    return 1;
      }
***************
*** 1723,1728 ****
--- 1774,1781 ----
  	    lock_ObtainMutex(&bp->mx);
  	    bp->cmFlags &= ~CM_BUF_CMSTORING;
  	    bp->flags &= ~CM_BUF_DIRTY;
+             bp->dirty_offset = 0;
+             bp->dirty_length = 0;
  	    bp->flags |= CM_BUF_ERROR;
  	    bp->error = VNOVNODE;
  	    bp->dataVersion = -1; /* bad */
Index: openafs/src/WINNT/afsd/cm_buf.h
diff -c openafs/src/WINNT/afsd/cm_buf.h:1.12.4.4 openafs/src/WINNT/afsd/cm_buf.h:1.12.4.6
*** openafs/src/WINNT/afsd/cm_buf.h:1.12.4.4	Sun Feb  4 22:41:41 2007
--- openafs/src/WINNT/afsd/cm_buf.h	Thu Aug  9 01:33:56 2007
***************
*** 72,106 ****
      long dirtyCounter;	        /* bumped at each dirty->clean transition */
      osi_hyper_t offset;	        /* offset */
      cm_fid_t fid;		/* file ID */
- #ifdef DEBUG
-     cm_scache_t *scp;		/* for debugging, the scache object belonging to */
-                                 /* the fid at the time of fid assignment. */
- #endif
      long flags;		        /* flags we're using */
      char *datap;		/* data in this buffer */
      unsigned long error;	/* last error code, if CM_BUF_ERROR is set */
      cm_user_t *userp;	        /* user who wrote to the buffer last */
- #ifndef DJGPP
-     OVERLAPPED over;	        /* overlapped structure for I/O */
- #endif
          
      /* fields added for the CM; locked by scp->mx */
      long dataVersion;	        /* data version of this page */
      long cmFlags;		/* flags for cm */
  #ifdef DISKCACHE95
      cm_diskcache_t *dcp;        /* diskcache structure */
  #endif /* DISKCACHE95 */
! 
!     /* syncop state */
!     afs_uint32 waitCount;           /* number of threads waiting */
!     afs_uint32 waitRequests;        /* num of thread wait requests */
  } cm_buf_t;
  
  /* values for cmFlags */
  #define CM_BUF_CMFETCHING	1	/* fetching this buffer */
  #define CM_BUF_CMSTORING	2	/* storing this buffer */
  #define CM_BUF_CMFULLYFETCHED	4	/* read-while-fetching optimization */
! /* waiting is done based on scp->flags */
  
  /* represents soft reference which is OK to lose on a recycle */
  typedef struct cm_softRef {
--- 72,111 ----
      long dirtyCounter;	        /* bumped at each dirty->clean transition */
      osi_hyper_t offset;	        /* offset */
      cm_fid_t fid;		/* file ID */
      long flags;		        /* flags we're using */
      char *datap;		/* data in this buffer */
      unsigned long error;	/* last error code, if CM_BUF_ERROR is set */
      cm_user_t *userp;	        /* user who wrote to the buffer last */
          
      /* fields added for the CM; locked by scp->mx */
      long dataVersion;	        /* data version of this page */
      long cmFlags;		/* flags for cm */
+ 
+     /* syncop state */
+     afs_uint32 waitCount;       /* number of threads waiting */
+     afs_uint32 waitRequests;    /* num of thread wait requests */
+ 
+     afs_uint32 dirty_offset;    /* offset from beginning of buffer containing dirty bytes */
+     afs_uint32 dirty_length;    /* number of dirty bytes within the buffer */
+ 
  #ifdef DISKCACHE95
      cm_diskcache_t *dcp;        /* diskcache structure */
  #endif /* DISKCACHE95 */
! #ifdef DEBUG
!     cm_scache_t *scp;		/* for debugging, the scache object belonging to */
!                                 /* the fid at the time of fid assignment. */
! #else
!     void * dummy;
! #endif
  } cm_buf_t;
  
  /* values for cmFlags */
  #define CM_BUF_CMFETCHING	1	/* fetching this buffer */
  #define CM_BUF_CMSTORING	2	/* storing this buffer */
  #define CM_BUF_CMFULLYFETCHED	4	/* read-while-fetching optimization */
! #define CM_BUF_CMWRITING        8       /* writing to this buffer */
! /* waiting is done based on scp->flags.  Removing bits from cmFlags
!    should be followed by waking the scp. */
  
  /* represents soft reference which is OK to lose on a recycle */
  typedef struct cm_softRef {
***************
*** 161,167 ****
  
  extern void buf_CleanWait(cm_scache_t *, cm_buf_t *);
  
! extern void buf_SetDirty(cm_buf_t *);
  
  extern long buf_CleanAndReset(void);
  
--- 166,172 ----
  
  extern void buf_CleanWait(cm_scache_t *, cm_buf_t *);
  
! extern void buf_SetDirty(cm_buf_t *, afs_uint32 offset, afs_uint32 length);
  
  extern long buf_CleanAndReset(void);
  
***************
*** 196,201 ****
--- 201,208 ----
  
  extern long buf_CleanDirtyBuffers(cm_scache_t *scp);
  
+ extern long buf_ForceDataVersion(cm_scache_t * scp, afs_uint32 fromVersion, afs_uint32 toVersion);
+ 
  /* error codes */
  #define CM_BUF_EXISTS	1	/* buffer exists, and shouldn't */
  #endif /*  _BUF_H__ENV_ */
Index: openafs/src/WINNT/afsd/cm_callback.c
diff -c openafs/src/WINNT/afsd/cm_callback.c:1.41.4.17 openafs/src/WINNT/afsd/cm_callback.c:1.41.4.18
*** openafs/src/WINNT/afsd/cm_callback.c:1.41.4.17	Sat Jul  7 09:38:33 2007
--- openafs/src/WINNT/afsd/cm_callback.c	Thu Aug  2 16:46:12 2007
***************
*** 1756,1767 ****
      return code;
  }
  
  /* called periodically by cm_daemon to shut down use of expired callbacks */
  void cm_CheckCBExpiration(void)
  {
      int i;
      cm_scache_t *scp;
!     time_t now;
          
      osi_Log0(afsd_logp, "CheckCBExpiration");
  
--- 1756,1807 ----
      return code;
  }
  
+ 
+ /* called with cm_scacheLock held */
+ long cm_CBServersUp(cm_scache_t *scp, time_t * downTime)
+ {
+     cm_vol_state_t *statep;
+     cm_volume_t * volp = scp->volp;
+     afs_uint32 volID = scp->fid.volume;
+     cm_serverRef_t *tsrp;
+     int found;
+ 
+     *downTime = 0;
+ 
+     if (scp->cbServerp == NULL)
+         return 1;
+ 
+     if (volp->rw.ID == volID) {
+         statep = &volp->rw;
+     } else if (volp->ro.ID == volID) {
+         statep = &volp->ro;
+     } else if (volp->bk.ID == volID) {
+         statep = &volp->bk;
+     }
+ 
+     if (statep->state == vl_online)
+         return 1;
+ 
+     for (found = 0,tsrp = statep->serversp; tsrp; tsrp=tsrp->next) {
+         if (tsrp->server == scp->cbServerp)
+             found = 1;
+         if (tsrp->server->downTime > *downTime)
+             *downTime = tsrp->server->downTime;
+     }
+ 
+     /* if the cbServerp does not match the current volume server list
+      * we report the callback server as up so the callback can be 
+      * expired.
+      */
+     return(found ? 0 : 1);
+ }
+ 
  /* called periodically by cm_daemon to shut down use of expired callbacks */
  void cm_CheckCBExpiration(void)
  {
      int i;
      cm_scache_t *scp;
!     time_t now, downTime = 0;
          
      osi_Log0(afsd_logp, "CheckCBExpiration");
  
***************
*** 1769,1786 ****
      lock_ObtainWrite(&cm_scacheLock);
      for (i=0; i<cm_data.scacheHashTableSize; i++) {
          for (scp = cm_data.scacheHashTablep[i]; scp; scp=scp->nextp) {
!             cm_HoldSCacheNoLock(scp);
!             if (scp->cbExpires > 0 && (scp->cbServerp == NULL || now > scp->cbExpires)) {
                  lock_ReleaseWrite(&cm_scacheLock);
!                 osi_Log4(afsd_logp, "Callback Expiration Discarding SCache scp 0x%p vol %u vn %u uniq %u", 
                            scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
                  lock_ObtainMutex(&scp->mx);
                  cm_DiscardSCache(scp);
                  lock_ReleaseMutex(&scp->mx);
                  cm_CallbackNotifyChange(scp);
                  lock_ObtainWrite(&cm_scacheLock);
              }
-             cm_ReleaseSCacheNoLock(scp);
          }
      }
      lock_ReleaseWrite(&cm_scacheLock);
--- 1809,1831 ----
      lock_ObtainWrite(&cm_scacheLock);
      for (i=0; i<cm_data.scacheHashTableSize; i++) {
          for (scp = cm_data.scacheHashTablep[i]; scp; scp=scp->nextp) {
! 
!             if (scp->cbServerp && scp->cbExpires > 0 && now > scp->cbExpires && 
!                  (cm_CBServersUp(scp, &downTime) || downTime == 0 || downTime >= scp->cbExpires)) 
!             {
!                 cm_HoldSCacheNoLock(scp);
                  lock_ReleaseWrite(&cm_scacheLock);
!                 
!                 osi_Log4(afsd_logp, "Callback Expiration Discarding SCache scp 0x%p vol %u vn %u uniq %u",
                            scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
                  lock_ObtainMutex(&scp->mx);
                  cm_DiscardSCache(scp);
                  lock_ReleaseMutex(&scp->mx);
                  cm_CallbackNotifyChange(scp);
+ 
+                 cm_ReleaseSCacheNoLock(scp);
                  lock_ObtainWrite(&cm_scacheLock);
              }
          }
      }
      lock_ReleaseWrite(&cm_scacheLock);
Index: openafs/src/WINNT/afsd/cm_config.h
diff -c openafs/src/WINNT/afsd/cm_config.h:1.8 openafs/src/WINNT/afsd/cm_config.h:1.8.6.1
*** openafs/src/WINNT/afsd/cm_config.h:1.8	Fri Mar 11 00:33:22 2005
--- openafs/src/WINNT/afsd/cm_config.h	Thu Aug  9 01:33:56 2007
***************
*** 13,19 ****
  #define CM_CONFIGDEFAULT_CACHESIZE	98304
  #define CM_CONFIGDEFAULT_BLOCKSIZE	4096
  #define CM_CONFIGDEFAULT_STATS		10000
! #define CM_CONFIGDEFAULT_CHUNKSIZE	17
  #define CM_CONFIGDEFAULT_DAEMONS	2
  #define CM_CONFIGDEFAULT_SVTHREADS	25
  #define CM_CONFIGDEFAULT_TRACEBUFSIZE	5000
--- 13,19 ----
  #define CM_CONFIGDEFAULT_CACHESIZE	98304
  #define CM_CONFIGDEFAULT_BLOCKSIZE	4096
  #define CM_CONFIGDEFAULT_STATS		10000
! #define CM_CONFIGDEFAULT_CHUNKSIZE	20
  #define CM_CONFIGDEFAULT_DAEMONS	2
  #define CM_CONFIGDEFAULT_SVTHREADS	25
  #define CM_CONFIGDEFAULT_TRACEBUFSIZE	5000
Index: openafs/src/WINNT/afsd/cm_conn.c
diff -c openafs/src/WINNT/afsd/cm_conn.c:1.49.2.19 openafs/src/WINNT/afsd/cm_conn.c:1.49.2.21
*** openafs/src/WINNT/afsd/cm_conn.c:1.49.2.19	Mon Jun 25 00:59:40 2007
--- openafs/src/WINNT/afsd/cm_conn.c	Tue Aug  7 00:00:49 2007
***************
*** 551,559 ****
      else if (errorCode >= -64 && errorCode < 0) {
          /* mark server as down */
          lock_ObtainMutex(&serverp->mx);
! 	if (reqp->flags & CM_REQ_NEW_CONN_FORCED)
  	    serverp->flags |= CM_SERVERFLAG_DOWN;
! 	else {
  	    reqp->flags |= CM_REQ_NEW_CONN_FORCED;
  	    forcing_new = 1;
  	}
--- 551,560 ----
      else if (errorCode >= -64 && errorCode < 0) {
          /* mark server as down */
          lock_ObtainMutex(&serverp->mx);
! 	if (reqp->flags & CM_REQ_NEW_CONN_FORCED) {
  	    serverp->flags |= CM_SERVERFLAG_DOWN;
!             serverp->downTime = osi_Time();
!         } else {
  	    reqp->flags |= CM_REQ_NEW_CONN_FORCED;
  	    forcing_new = 1;
  	}
***************
*** 708,720 ****
      struct timeval now;
  #endif /* DJGPP */        
  
      if (serversp == NULL) {
  	osi_Log1(afsd_logp, "cm_ConnByMServers returning 0x%x", CM_ERROR_ALLDOWN);
  	return CM_ERROR_ALLDOWN;
      }
  
-     *connpp = NULL;
- 
  #ifndef DJGPP
      timeUsed = (GetTickCount() - reqp->startTime) / 1000;
  #else
--- 709,721 ----
      struct timeval now;
  #endif /* DJGPP */        
  
+     *connpp = NULL;
+ 
      if (serversp == NULL) {
  	osi_Log1(afsd_logp, "cm_ConnByMServers returning 0x%x", CM_ERROR_ALLDOWN);
  	return CM_ERROR_ALLDOWN;
      }
  
  #ifndef DJGPP
      timeUsed = (GetTickCount() - reqp->startTime) / 1000;
  #else
***************
*** 867,872 ****
--- 868,875 ----
      cm_conn_t *tcp;
      cm_ucell_t *ucellp;
  
+     *connpp = NULL;
+ 
      lock_ObtainMutex(&userp->mx);
      lock_ObtainWrite(&cm_connLock);
      for (tcp = serverp->connsp; tcp; tcp=tcp->nextp) {
Index: openafs/src/WINNT/afsd/cm_dcache.c
diff -c openafs/src/WINNT/afsd/cm_dcache.c:1.30.2.15 openafs/src/WINNT/afsd/cm_dcache.c:1.30.2.16
*** openafs/src/WINNT/afsd/cm_dcache.c:1.30.2.15	Sun Jun 10 13:00:07 2007
--- openafs/src/WINNT/afsd/cm_dcache.c	Thu Aug  9 01:33:56 2007
***************
*** 1254,1261 ****
  		}
  		if (failed)
  		    bufp->flags &= ~CM_BUF_WRITING;
! 		else
  		    bufp->flags &= ~(CM_BUF_WRITING | CM_BUF_DIRTY);
  	    }
  
  	    lock_ReleaseMutex(&scp->mx);
--- 1254,1263 ----
  		}
  		if (failed)
  		    bufp->flags &= ~CM_BUF_WRITING;
! 		else {
  		    bufp->flags &= ~(CM_BUF_WRITING | CM_BUF_DIRTY);
+                     bufp->dirty_offset = bufp->dirty_length = 0;
+                 }
  	    }
  
  	    lock_ReleaseMutex(&scp->mx);
Index: openafs/src/WINNT/afsd/cm_dir.c
diff -c openafs/src/WINNT/afsd/cm_dir.c:1.4.4.1 openafs/src/WINNT/afsd/cm_dir.c:1.4.4.2
*** openafs/src/WINNT/afsd/cm_dir.c:1.4.4.1	Sat Jun 24 16:41:54 2006
--- openafs/src/WINNT/afsd/cm_dir.c	Thu Aug  2 16:53:51 2007
***************
*** 20,33 ****
  #include <rx/rx.h>
  
  
  /* compute how many 32 byte entries an AFS 3 dir requires for storing
   * the specified name.
   */
! long cm_NameEntries(char *namep, long *lenp)
  {
      long i;
          
!     i = (long)strlen(namep);
      if (lenp) *lenp = i;
!     return 1+((i+16)>>5);
  }	
--- 20,1437 ----
  #include <rx/rx.h>
  
  
+ afs_int32 DErrno;
+ 
+ /* Local static prototypes */
+ static long
+ cm_DirGetBlob(cm_dirOp_t * op,
+               unsigned int blobno, cm_buf_t ** bufferpp, cm_dirEntry_t ** blobpp);
+ 
+ static long
+ cm_DirFindItem(cm_dirOp_t * op,
+                char *ename,
+                cm_buf_t ** itembufpp, cm_dirEntry_t ** itempp,
+                cm_buf_t ** prevbufpp, unsigned short **previtempp);
+ 
+ static long
+ cm_DirOpAddBuffer(cm_dirOp_t * op, cm_buf_t * buffer);
+ 
+ /* flags for cm_DirOpDelBuffer */
+ #define DIROP_MODIFIED  1
+ #define DIROP_SCPLOCKED 2
+ 
+ static int
+ cm_DirOpDelBuffer(cm_dirOp_t * op, cm_buf_t * buffer, int flags);
+ 
+ static long
+ cm_DirCheckStatus(cm_dirOp_t * op);
+ 
+ static long
+ cm_DirReleasePage(cm_dirOp_t * op, cm_buf_t ** bufferpp, int modified);
+ 
+ static long
+ cm_DirGetPage(cm_dirOp_t * op,
+               long index, cm_buf_t ** bufferpp, void ** datapp);
+ 
+ static long
+ cm_DirFindBlobs(cm_dirOp_t * op, int nblobs);
+ 
+ static long
+ cm_DirAddPage(cm_dirOp_t * op, int pageno);
+ 
+ static long
+ cm_DirFreeBlobs(cm_dirOp_t * op, int firstblob, int nblobs);
+ 
+ 
  /* compute how many 32 byte entries an AFS 3 dir requires for storing
   * the specified name.
   */
! long 
! cm_NameEntries(char *namep, long *lenp)
  {
      long i;
          
!     i = (long)strlen(namep) + 1;
      if (lenp) *lenp = i;
!     return 1 + ((i+15) >> 5);
! }
! 
! /* Create an entry in a file.  Dir is a file representation, while
!    entry is a string name.
! 
!    On entry:
!        op->scp->mx is locked
! 
!    On exit:
!        op->scp->mx is locked
! 
!    None of the directory buffers for op->scp should be locked by the
!    calling thread.
! */
! long
! cm_DirCreateEntry(cm_dirOp_t * op, char *entry, cm_fid_t * cfid)
! {
!     int blobs, firstelt;
!     int i;
! 
!     cm_dirEntry_t *ep = NULL;
!     cm_buf_t *entrybuf = NULL;
! 
!     unsigned short *pp = NULL;
!     cm_buf_t *prevptrbuf = NULL;
! 
!     cm_dirHeader_t *dhp = NULL;
!     cm_buf_t *dhpbuf = NULL;
! 
!     long code = 0;
! 
!     /* check name quality */
!     if (*entry == 0)
! 	return EINVAL;
! 
!     osi_Log4(afsd_logp, "cm_DirCreateEntry for op 0x%p, name [%s] and fid[%d,%d]",
!              op, osi_LogSaveString(afsd_logp, entry), cfid->vnode, cfid->unique);
! 
!     /* First check if file already exists. */
!     code = cm_DirFindItem(op,
!                           entry,
!                           &entrybuf, &ep,
!                           &prevptrbuf, &pp);
!     if (code == 0) {
!         cm_DirReleasePage(op, &entrybuf, FALSE);
!         cm_DirReleasePage(op, &prevptrbuf, FALSE);
! 	return EEXIST;
!     }
! 
!     blobs = cm_NameEntries(entry, NULL);	/* number of entries required */
!     firstelt = cm_DirFindBlobs(op, blobs);
!     if (firstelt < 0) {
!         osi_Log0(afsd_logp, "cm_DirCreateEntry returning EFBIG");
! 	return EFBIG;		/* directory is full */
!     }
! 
!     /* First, we fill in the directory entry. */
!     code = cm_DirGetBlob(op, firstelt, &entrybuf, &ep);
!     if (code != 0)
! 	return EIO;
! 
!     ep->flag = CM_DIR_FFIRST;
!     ep->fid.vnode = htonl(cfid->vnode);
!     ep->fid.unique = htonl(cfid->unique);
!     strcpy(ep->name, entry);
! 
!     /* Now we just have to thread it on the hash table list. */
!     code = cm_DirGetPage(op, 0, &dhpbuf, &dhp);
!     if (code != 0) {
! 	cm_DirReleasePage(op, &entrybuf, TRUE);
! 	return EIO;
!     }
! 
!     i = cm_DirHash(entry);
! 
!     ep->next = dhp->hashTable[i];
!     dhp->hashTable[i] = htons(firstelt);
! 
!     cm_DirReleasePage(op, &dhpbuf, TRUE);
!     cm_DirReleasePage(op, &entrybuf, TRUE);
! 
!     osi_Log0(afsd_logp, "cm_DirCreateEntry returning success");
! 
!     return 0;
! }
! 
! /* Return the length of a directory in pages
! 
!    On entry:
!        op->scp->mx is locked
! 
!    On exit:
!        op->scp->mx is locked
! 
!    The first directory page for op->scp should not be locked by the
!    calling thread.
! */
! int
! cm_DirLength(cm_dirOp_t * op)
! {
!     int i, ctr;
!     cm_dirHeader_t *dhp = NULL;
!     cm_buf_t       *dhpbuf = NULL;
! 
!     long code;
! 
!     code = cm_DirGetPage(op, 0, &dhpbuf, &dhp);
!     if (code != 0)
! 	return 0;
! 
!     if (dhp->header.pgcount != 0)
! 	ctr = ntohs(dhp->header.pgcount);
!     else {
! 	/* old style, count the pages */
! 	ctr = 0;
! 	for (i = 0; i < CM_DIR_MAXPAGES; i++)
! 	    if (dhp->alloMap[i] != CM_DIR_EPP)
! 		ctr++;
!     }
!     cm_DirReleasePage(op, &dhpbuf, FALSE);
!     return ctr * CM_DIR_PAGESIZE;
! }
! 
! /* Delete a directory entry.
! 
!    On entry:
!        op->scp->mx is locked
! 
!    On exit:
!        op->scp->mx is locked
! 
!    None of the directory buffers for op->scp should be locked by the
!    calling thread.
!  */
! int
! cm_DirDeleteEntry(cm_dirOp_t * op, char *entry)
! {
!     /* Delete an entry from a directory, including update of all free
!        entry descriptors. */
! 
!     int nitems, index;
!     cm_dirEntry_t *firstitem = NULL;
!     cm_buf_t      *itembuf = NULL;
!     unsigned short *previtem = NULL;
!     cm_buf_t      *pibuf = NULL;
!     osi_hyper_t    thyper;
!     unsigned long  junk;
! 
!     long code;
! 
!     osi_Log2(afsd_logp, "cm_DirDeleteEntry for op 0x%p, entry [%s]",
!              op, osi_LogSaveString(afsd_logp, entry));
! 
!     code = cm_DirFindItem(op, entry,
!                           &itembuf, &firstitem,
!                           &pibuf, &previtem);
!     if (code != 0) {
!         osi_Log0(afsd_logp, "cm_DirDeleteEntry returning ENOENT");
! 	return ENOENT;
!     }
! 
!     *previtem = firstitem->next;
!     cm_DirReleasePage(op, &pibuf, TRUE);
! 
!     thyper = itembuf->offset;
!     thyper = LargeIntegerAdd(thyper,
!                              ConvertLongToLargeInteger(((char *) firstitem) - itembuf->datap));
!     thyper = ExtendedLargeIntegerDivide(thyper, 32, &junk);
! 
!     index = thyper.LowPart;
!     osi_assert(thyper.HighPart == 0);
! 
!     nitems = cm_NameEntries(firstitem->name, NULL);
!     cm_DirReleasePage(op, &itembuf, FALSE);
! 
!     cm_DirFreeBlobs(op, index, nitems);
! 
!     osi_Log0(afsd_logp, "cm_DirDeleteEntry returning success");
! 
!     return 0;
! }
! 
! /* Find a bunch of contiguous entries; at least nblobs in a row.
! 
!    Called with op->scp->mx */
! static long
! cm_DirFindBlobs(cm_dirOp_t * op, int nblobs)
! {
!     int i, j, k;
!     int failed = 0;
! 
!     cm_dirHeader_t *dhp = NULL;
!     cm_buf_t *dhpbuf = NULL;
!     int dhpModified = FALSE;
! 
!     cm_pageHeader_t *pp = NULL;
!     cm_buf_t *pagebuf = NULL;
!     int pageModified = FALSE;
! 
!     int pgcount;
! 
!     long code;
! 
!     osi_Log2(afsd_logp, "cm_DirFindBlobs for op 0x%p, nblobs = %d",
!              op, nblobs);
! 
!     code = cm_DirGetPage(op, 0, &dhpbuf, (void **) &dhp);
!     if (code)
! 	return -1;
! 
!     for (i = 0; i < CM_DIR_BIGMAXPAGES; i++) {
! 	if (i >= CM_DIR_MAXPAGES || dhp->alloMap[i] >= nblobs) {
! 	    /* if page could contain enough entries */
! 	    /* If there are CM_DIR_EPP free entries, then the page is
!                not even allocated. */
! 	    if (i >= CM_DIR_MAXPAGES) {
! 
! 		/* this pages exists past the end of the old-style dir */
! 		pgcount = ntohs(dhp->header.pgcount);
! 		if (pgcount == 0) {
! 		    pgcount = CM_DIR_MAXPAGES;
! 		    dhp->header.pgcount = htons(pgcount);
!                     dhpModified = TRUE;
! 		}
! 
! 		if (i > pgcount - 1) {
! 		    /* this page is bigger than last allocated page */
!                     cm_DirAddPage(op, i);
! 		    dhp->header.pgcount = htons(i + 1);
!                     dhpModified = TRUE;
! 		}
! 	    } else if (dhp->alloMap[i] == CM_DIR_EPP) {
! 		/* Add the page to the directory. */
! 		cm_DirAddPage(op, i);
! 		dhp->alloMap[i] = CM_DIR_EPP - 1;
! 		dhp->header.pgcount = htons(i + 1);
!                 dhpModified = TRUE;
! 	    }
! 
!             code = cm_DirGetPage(op, i, &pagebuf, &pp);
!             if (code) {
!                 cm_DirReleasePage(op, &dhpbuf, dhpModified);
!                 break;
!             }
! 
! 	    for (j = 0; j <= CM_DIR_EPP - nblobs; j++) {
! 		failed = 0;
! 		for (k = 0; k < nblobs; k++)
! 		    if ((pp->freeBitmap[(j + k) >> 3] >> ((j + k) & 7)) & 1) {
! 			failed = 1;
! 			break;
! 		    }
! 		if (!failed)
! 		    break;
! 		failed = 1;
! 	    }
! 
! 	    if (!failed) {
! 		/* Here we have the first index in j.  We update the allocation maps
! 		 * and free up any resources we've got allocated. */
! 		if (i < CM_DIR_MAXPAGES) {
! 		    dhp->alloMap[i] -= nblobs;
!                     dhpModified = TRUE;
!                 }
! 
!                 cm_DirReleasePage(op, &dhpbuf, dhpModified);
! 
! 		for (k = 0; k < nblobs; k++)
! 		    pp->freeBitmap[(j + k) >> 3] |= 1 << ((j + k) & 7);
! 
!                 cm_DirReleasePage(op, &pagebuf, TRUE);
! 
!                 osi_Log0(afsd_logp, "cm_DirFindBlobs returning success");
! 
! 		return j + i * CM_DIR_EPP;
! 	    }
!             cm_DirReleasePage(op, &pagebuf, pageModified);
! 	}
!     }
! 
!     /* If we make it here, the directory is full. */
!     osi_Log0(afsd_logp, "cm_DirFindBlobs directory is full");
!     cm_DirReleasePage(op, &dhpbuf, dhpModified);
!     return -1;
! }
! 
! /* Add a page to a directory. 
! 
!    Called with op->scp->mx
! */
! static long
! cm_DirAddPage(cm_dirOp_t * op, int pageno)
! {
!     int i;
!     cm_pageHeader_t *pp = NULL;
!     cm_buf_t *pagebuf = NULL;
!     long code = 0;
! 
!     osi_Log2(afsd_logp, "cm_DirAddPage for op 0x%p, pageno=%d", op, pageno);
! 
!     code = cm_DirGetPage(op, pageno, &pagebuf, (void **) &pp);
!     if (code != 0)
!         return code;
! 
!     pp->tag = htons(1234);
!     if (pageno > 0)
! 	pp->pgcount = 0;
!     pp->freeCount = CM_DIR_EPP - 1; /* The first dude is already allocated */
!     pp->freeBitmap[0] = 0x01;
!     for (i = 1; i < CM_DIR_EPP / 8; i++) /* It's a constant */
! 	pp->freeBitmap[i] = 0;
! 
!     cm_DirReleasePage(op, &pagebuf, TRUE);
! 
!     osi_Log0(afsd_logp, "cm_DirAddPage returning success");
! 
!     return code;
! }
! 
! /* Free a whole bunch of directory entries.
! 
!    Called with op->scp->mx
! */
! static long
! cm_DirFreeBlobs(cm_dirOp_t * op, int firstblob, int nblobs)
! {
!     int i;
!     int page;
! 
!     cm_dirHeader_t *dhp = NULL;
!     cm_buf_t       *dhpbuf = NULL;
!     int             dhpmodified = FALSE;
! 
!     cm_pageHeader_t *pp = NULL;
!     cm_buf_t        *pagebuf = NULL;
!     long code = 0;
! 
!     osi_Log3(afsd_logp, "cm_DirFreeBlobs for op 0x%p, firstblob=%d, nblobs=%d",
!              op, firstblob, nblobs);
! 
!     page = firstblob / CM_DIR_EPP;
!     firstblob -= CM_DIR_EPP * page;	/* convert to page-relative entry */
! 
!     code = cm_DirGetPage(op, 0, &dhpbuf, &dhp);
!     if (code)
!         return code;
! 
!     if (page < CM_DIR_MAXPAGES) {
! 	dhp->alloMap[page] += nblobs;
!         dhpmodified = TRUE;
!     }
! 
!     cm_DirReleasePage(op, &dhpbuf, dhpmodified);
! 
!     code = cm_DirGetPage(op, page, &pagebuf, &pp);
!     if (code == 0) {
! 	for (i = 0; i < nblobs; i++)
! 	    pp->freeBitmap[(firstblob + i) >> 3] &=
! 		~(1 << ((firstblob + i) & 7));
!         cm_DirReleasePage(op, &pagebuf, TRUE);
!     }
! 
!     osi_Log1(afsd_logp, "cm_DirFreeBlobs returning code 0x%x", code);
! 
!     return code;
! }
! 
! /*
!  * Format an empty directory properly.  Note that the first 13 entries in a
!  * directory header page are allocated, 1 to the page header, 4 to the
!  * allocation map and 8 to the hash table.
!  *
!  * Called with op->scp->mx
!  */
! int
! cm_DirMakeDir(cm_dirOp_t * op, cm_fid_t * me, cm_fid_t * parent)
! {
!     int i;
!     cm_dirHeader_t *dhp = NULL;
!     cm_buf_t *dhpbuf = NULL;
! 
!     long code;
! 
!     osi_Log3(afsd_logp, "cm_DirMakeDir for op 0x%p, directory fid[%d, %d]",
!              op, me->vnode, me->unique);
!     osi_Log2(afsd_logp, "              parent[%d, %d]",
!              parent->vnode, parent->unique);
! 
!     code = cm_DirGetPage(op, 0, &dhpbuf, &dhp);
!     if (code)
!         return 1;
! 
!     dhp->header.pgcount = htons(1);
!     dhp->header.tag = htons(1234);
!     dhp->header.freeCount = (CM_DIR_EPP - CM_DIR_DHE - 1);
!     dhp->header.freeBitmap[0] = 0xff;
!     dhp->header.freeBitmap[1] = 0x1f;
!     for (i = 2; i < CM_DIR_EPP / 8; i++)
! 	dhp->header.freeBitmap[i] = 0;
!     dhp->alloMap[0] = (CM_DIR_EPP - CM_DIR_DHE - 1);
!     for (i = 1; i < CM_DIR_MAXPAGES; i++)
! 	dhp->alloMap[i] = CM_DIR_EPP;
!     for (i = 0; i < CM_DIR_NHASHENT; i++)
! 	dhp->hashTable[i] = 0;
! 
!     cm_DirReleasePage(op, &dhpbuf, TRUE);
! 
!     cm_DirCreateEntry(op, ".", me);
!     cm_DirCreateEntry(op, "..", parent);	/* Virtue is its own .. */
! 
!     osi_Log0(afsd_logp, "cm_DirMakeDir returning success");
! 
!     return 0;
! }
! 
! /* Look up a file name in directory.
! 
!    On entry:
!        op->scp->mx is locked
! 
!    On exit:
!        op->scp->mx is locked
! 
!    None of the directory buffers for op->scp should be locked by the
!    calling thread.
! */
! int
! cm_DirLookup(cm_dirOp_t * op, char *entry, cm_fid_t * cfid)
! {
!     cm_dirEntry_t *firstitem = NULL;
!     cm_buf_t      *itembuf = NULL;
!     unsigned short *previtem = NULL;
!     cm_buf_t      *pibuf = NULL;
! 
!     long code;
! 
!     osi_Log2(afsd_logp, "cm_DirLookup for op 0x%p, entry[%s]",
!              op, osi_LogSaveString(afsd_logp, entry));
! 
!     code = cm_DirFindItem(op, entry,
!                           &itembuf, &firstitem,
!                           &pibuf, &previtem);
!     if (code != 0) {
!         return ENOENT;
!     }
! 
!     cm_DirReleasePage(op, &pibuf, FALSE);
! 
!     cfid->cell = op->scp->fid.cell;
!     cfid->volume = op->scp->fid.volume;
!     cfid->vnode = ntohl(firstitem->fid.vnode);
!     cfid->unique = ntohl(firstitem->fid.unique);
! 
!     cm_DirReleasePage(op, &itembuf, FALSE);
! 
!     osi_Log2(afsd_logp, "cm_DirLookup returning fid[%d,%d]",
!              cfid->vnode, cfid->unique);
! 
!     return 0;
! }
! 
! /* Look up a file name in directory.
! 
!    On entry:
!        op->scp->mx is locked
! 
!    On exit:
!        op->scp->mx is locked
! 
!    None of the directory buffers for op->scp should be locked by the
!    calling thread.
! */
! int
! cm_DirLookupOffset(cm_dirOp_t * op, char *entry, cm_fid_t *cfid, osi_hyper_t *offsetp)
! {
!     cm_dirEntry_t *firstitem = NULL;
!     cm_buf_t      *itembuf = NULL;
!     unsigned short *previtem = NULL;
!     cm_buf_t      *pibuf = NULL;
! 
!     long code;
! 
!     osi_Log2(afsd_logp, "cm_DirLookupOffset for op 0x%p, entry[%s]",
!              op, osi_LogSaveString(afsd_logp, entry));
! 
!     code = cm_DirFindItem(op, entry,
!                           &itembuf, &firstitem,
!                           &pibuf, &previtem);
!     if (code != 0)
!         return ENOENT;
! 
!     cm_DirReleasePage(op, &pibuf, FALSE);
! 
!     cfid->cell = op->scp->fid.cell;
!     cfid->volume = op->scp->fid.volume;
!     cfid->vnode = ntohl(firstitem->fid.vnode);
!     cfid->unique = ntohl(firstitem->fid.unique);
!     if (offsetp) {
!         osi_hyper_t thyper;
! 
!         thyper = itembuf->offset;
!         thyper = LargeIntegerAdd(thyper,
!                                  ConvertLongToLargeInteger(((char *) firstitem) - itembuf->datap));
! 
! 	*offsetp = thyper;
!     }
! 
!     cm_DirReleasePage(op, &itembuf, FALSE);
! 
!     osi_Log2(afsd_logp, "cm_DirLookupOffset returning fid[%d,%d]",
!              cfid->vnode, cfid->unique);
!     if (offsetp) {
!         osi_Log2(afsd_logp, "               offset [%x:%x]",
!                  offsetp->HighPart, offsetp->LowPart);
!     }
! 
!     return 0;
! }
! 
! /* Apply a function to every directory entry in a directory.
! 
!    On entry:
!        op->scp->mx is locked
! 
!    On exit:
!        op->scp->mx is locked
! 
!    None of the directory buffers for op->scp should be locked by the
!    calling thread.
! 
!    The hook function cannot modify or lock any directory buffers.
!  */
! int
! cm_DirApply(cm_dirOp_t * op, int (*hookproc) (void *, char *, long, long), void *hook)
! {
!     /* Enumerate the contents of a directory. */
!     int i;
!     int num;
! 
!     cm_dirHeader_t *dhp = NULL;
!     cm_buf_t       *dhpbuf = NULL;
! 
!     cm_dirEntry_t  *ep = NULL;
!     cm_buf_t       *epbuf = NULL;
! 
!     long code = 0;
! 
!     code = cm_DirGetPage(op, 0, &dhpbuf, &dhp);
!     if (code != 0)
!         return EIO;
! 
!     for (i = 0; i < CM_DIR_NHASHENT; i++) {
! 	/* For each hash chain, enumerate everyone on the list. */
! 	num = ntohs(dhp->hashTable[i]);
! 	while (num != 0) {
! 	    /* Walk down the hash table list. */
! 	    code = cm_DirGetBlob(op, num, &epbuf, &ep);
! 	    if (code != 0) {
!                 cm_DirReleasePage(op, &dhpbuf, FALSE);
!                 return code;
! 	    }
! 
! 	    num = ntohs(ep->next);
! 	    (*hookproc) (hook, ep->name, ntohl(ep->fid.vnode),
! 			 ntohl(ep->fid.unique));
! 
!             cm_DirReleasePage(op, &epbuf, FALSE);
! 	}
!     }
!     cm_DirReleasePage(op, &dhpbuf, FALSE);
! 
!     return 0;
! }
! 
! /* Check if a directory is empty
! 
!    On entry:
!        op->scp->mx is locked
! 
!    On exit:
!        op->scp->mx is locked
! 
!    None of the directory buffers for op->scp should be locked by the
!    calling thread.
!  */
! int
! cm_DirIsEmpty(cm_dirOp_t * op)
! {
!     /* Enumerate the contents of a directory. */
!     int i;
!     int num;
! 
!     cm_dirHeader_t *dhp = NULL;
!     cm_buf_t       *dhpbuf = NULL;
! 
!     cm_dirEntry_t  *ep = NULL;
!     cm_buf_t       *epbuf = NULL;
! 
!     long code = 0;
! 
!     code = cm_DirGetPage(op, 0, &dhpbuf, &dhp);
!     if (code != 0)
!         return 0;
! 
!     for (i = 0; i < CM_DIR_NHASHENT; i++) {
! 	/* For each hash chain, enumerate everyone on the list. */
! 	num = ntohs(dhp->hashTable[i]);
! 
! 	while (num != 0) {
! 	    /* Walk down the hash table list. */
! 	    code = cm_DirGetBlob(op, num, &epbuf, &ep);
! 	    if (code != 0)
! 		break;
! 
! 	    if (strcmp(ep->name, "..") && strcmp(ep->name, ".")) {
!                 cm_DirReleasePage(op, &epbuf, FALSE);
!                 cm_DirReleasePage(op, &dhpbuf, FALSE);
! 		return 1;
! 	    }
! 	    num = ntohs(ep->next);
! 	    cm_DirReleasePage(op, &epbuf, FALSE);
! 	}
!     }
!     cm_DirReleasePage(op, &dhpbuf, FALSE);
!     return 0;
! }
! 
! /* Return a pointer to an entry, given its number.
! 
!    On entry:
!      scp->mx locked
!      if *bufferpp != NULL, then *bufferpp->mx is locked
! 
!    During:
!      scp->mx may be unlocked
!      *bufferpp may be released
! 
!    On exit:
!      scp->mx locked
!      if *bufferpp != NULL, then *bufferpp->mx is locked
! 
!      *bufferpp should be released via cm_DirReleasePage() or any other
!      *call that releases a directory buffer.
! */
! static long
! cm_DirGetBlob(cm_dirOp_t * op,
!               unsigned int blobno, cm_buf_t ** bufferpp, cm_dirEntry_t ** blobpp)
! {
!     unsigned char * ep;
!     long code = 0;
! 
!     osi_Log2(afsd_logp, "cm_DirGetBlob for op 0x%p, blobno=%d",
!              op, blobno);
! 
!     code = cm_DirGetPage(op, blobno >> CM_DIR_LEPP,
!                          bufferpp, (void **) &ep);
!     if (code != 0)
!         return code;
! 
!     *blobpp = (cm_dirEntry_t *) (ep + 32 * (blobno & (CM_DIR_EPP - 1)));
! 
!     return code;
  }	
+ 
+ int
+ cm_DirHash(char *string)
+ {
+     /* Hash a string to a number between 0 and NHASHENT. */
+     register unsigned char tc;
+     register int hval;
+     register int tval;
+     hval = 0;
+     while ((tc = (*string++))) {
+ 	hval *= 173;
+ 	hval += tc;
+     }
+     tval = hval & (CM_DIR_NHASHENT - 1);
+     if (tval == 0)
+ 	return tval;
+     else if (hval < 0)
+ 	tval = CM_DIR_NHASHENT - tval;
+     return tval;
+ }
+ 
+ /* Find a directory entry, given its name.  This entry returns a
+  * pointer to a locked buffer, and a pointer to a locked buffer (in
+  * previtem) referencing the found item (to aid the delete code).  If
+  * no entry is found, however, no items are left locked, and a null
+  * pointer is returned instead.
+  *
+  * On entry:
+  *  scp->mx locked
+  *
+  * On exit:
+  *  scp->mx locked
+  */
+ static long
+ cm_DirFindItem(cm_dirOp_t * op,
+                char *ename,
+                cm_buf_t ** itembufpp, cm_dirEntry_t ** itempp,
+                cm_buf_t ** prevbufpp, unsigned short **previtempp)
+ {
+     int                  i;
+     cm_dirHeader_t      *dhp = NULL;
+     unsigned short      *lp = NULL;
+     cm_dirEntry_t       *tp = NULL;
+     cm_buf_t            *hashbufp = NULL;
+     cm_buf_t            *itembufp = NULL;
+     long code = 0;
+ 
+     osi_Log2(afsd_logp, "cm_DirFindItem for op 0x%p, entry[%s]",
+              op, osi_LogSaveString(afsd_logp, ename));
+ 
+     i = cm_DirHash(ename);
+ 
+     if (op->scp->fileType != CM_SCACHETYPE_DIRECTORY) {
+         osi_Log0(afsd_logp, "cm_DirFindItem: The scp is not a directory");
+         return CM_ERROR_INVAL;
+     }
+ 
+     code = cm_DirGetPage(op, 0, &hashbufp, (void **) &dhp);
+     if (code != 0) {
+ 	return code;
+     }
+ 
+     if (dhp->hashTable[i] == 0) {
+ 	/* no such entry */
+         osi_Log1(afsd_logp, "cm_DirFindItem: Hash bucket %d is empty", i);
+ 	cm_DirReleasePage(op, &hashbufp, FALSE);
+ 	return ENOENT;
+     }
+ 
+     code = cm_DirGetBlob(op,
+                          (u_short) ntohs(dhp->hashTable[i]),
+                          &itembufp, &tp);
+     if (code != 0) {
+         cm_DirReleasePage(op, &hashbufp, FALSE);
+ 	return code;
+     }
+ 
+     lp = &(dhp->hashTable[i]);
+ 
+     /* loop invariant:
+ 
+        lp       : pointer to blob number of entry we are looking at
+        hashbufp : buffer containing lp
+        tp       : pointer to entry we are looking at
+        itembufp : buffer containing tp
+      */
+     while (1) {
+ 	/* Look at each hash conflict entry. */
+ 	if (!strcmp(ename, tp->name)) {
+             osi_Log0(afsd_logp, "cm_DirFindItem: returning success");
+ 	    /* Found our entry. */
+ 	    *previtempp = lp;
+             *prevbufpp = hashbufp;
+             *itempp = tp;
+             *itembufpp = itembufp;
+ 	    return 0;
+ 	}
+ 
+ 	lp = &(tp->next);
+         cm_DirReleasePage(op, &hashbufp, FALSE);
+         hashbufp = itembufp;
+ 
+         itembufp = NULL;
+         tp = NULL;
+ 
+ 	if (*lp == 0) {
+ 	    /* The end of the line */
+             osi_Log0(afsd_logp, "cm_DirFindItem: returning ENOENT");
+ 	    cm_DirReleasePage(op, &hashbufp, FALSE);
+ 	    return ENOENT;
+ 	}
+ 
+ 	code = cm_DirGetBlob(op,
+                              (u_short) ntohs(*lp),
+                              &itembufp, &tp);
+ 
+ 	if (code != 0) {
+ 	    cm_DirReleasePage(op, &hashbufp, FALSE);
+ 	    return code;
+ 	}
+     }
+ }
+ 
+ /* Begin a sequence of directory operations.  scp->mx should be
+    locked.
+ */
+ long
+ cm_BeginDirOp(cm_scache_t * scp, cm_user_t * userp, cm_req_t * reqp,
+               cm_dirOp_t * op)
+ {
+     long code;
+     int i;
+ 
+     osi_Log3(afsd_logp, "Beginning dirOp[0x%p] for scp[0x%p], userp[0x%p]",
+              op, scp, userp);
+ 
+     memset(op, 0, sizeof(*op));
+ 
+     cm_HoldSCache(scp);
+     op->scp = scp;
+     cm_HoldUser(userp);
+     op->userp = userp;
+     cm_InitReq(&op->req);
+ 
+     op->dirtyBufCount = 0;
+     op->nBuffers = 0;
+ 
+     for (i=0; i < CM_DIROP_MAXBUFFERS; i++) {
+         op->buffers[i].flags = 0;
+     }
+ 
+     code = cm_DirCheckStatus(op);
+ 
+     if (code == 0) {
+         op->length = scp->length;
+         op->newLength = op->length;
+         op->dataVersion = scp->dataVersion;
+         op->newDataVersion = op->dataVersion;
+     } else {
+         cm_EndDirOp(op);
+     }
+ 
+     return code;
+ }
+ 
+ /* Check if it is safe for us to perform local directory updates.
+    Called with scp->mx held. */
+ int
+ cm_CheckDirOpForSingleChange(cm_dirOp_t * op)
+ {
+     long code;
+ 
+     if (op->scp == NULL)
+         return 0;
+ 
+     code = cm_DirCheckStatus(op);
+ 
+     if (code == 0 &&
+         op->dataVersion == op->scp->dataVersion - 1) {
+         /* only one set of changes happened between cm_BeginDirOp()
+            and this function.  It is safe for us to perform local
+            changes. */
+         op->newDataVersion = op->scp->dataVersion;
+         op->newLength = op->scp->serverLength;
+ 
+         osi_Log0(afsd_logp, "cm_CheckDirOpForSingleChange succeeded");
+ 
+         return 1;
+     }
+ 
+     osi_Log3(afsd_logp,
+              "cm_CheckDirOpForSingleChange failed.  code=0x%x, old dv=%d, new dv=%d",
+              code, op->dataVersion, op->scp->dataVersion);
+     return 0;
+ }
+ 
+ /* End a sequence of directory operations.  Called with op->scp->mx
+    locked.*/
+ long
+ cm_EndDirOp(cm_dirOp_t * op)
+ {
+     long code = 0;
+ 
+     if (op->scp == NULL)
+         return 0;
+ 
+     osi_Log2(afsd_logp, "Ending dirOp 0x%p with %d dirty buffer releases",
+              op, op->dirtyBufCount);
+ 
+     if (op->dirtyBufCount > 0) {
+         /* we made changes.  We should go through the list of buffers
+            and update the dataVersion for each. */
+ 
+         lock_ReleaseMutex(&op->scp->mx);
+         code = buf_ForceDataVersion(op->scp, op->dataVersion, op->newDataVersion);
+         lock_ObtainMutex(&op->scp->mx);
+     }
+ 
+     if (op->scp)
+         cm_ReleaseSCache(op->scp);
+     op->scp = NULL;
+ 
+     if (op->userp)
+         cm_ReleaseUser(op->userp);
+     op->userp = 0;
+ 
+     osi_assertx(op->nBuffers == 0, "Buffer leak after dirOp termination");
+ 
+     return code;
+ }
+ 
+ /* NOTE: Called without scp->mx and without bufferp->mx */
+ static long
+ cm_DirOpAddBuffer(cm_dirOp_t * op, cm_buf_t * bufferp)
+ {
+     int i;
+     long code = 0;
+ 
+     osi_Log2(afsd_logp, "cm_DirOpAddBuffer for op 0x%p, buffer %p", op, bufferp);
+ 
+     if (bufferp == NULL)
+         return -1;
+ 
+     for (i=0; i < CM_DIROP_MAXBUFFERS; i++) {
+         if ((op->buffers[i].flags & CM_DIROPBUFF_INUSE) &&
+             op->buffers[i].bufferp == bufferp) {
+             break;
+         }
+     }
+ 
+     if (i < CM_DIROP_MAXBUFFERS) {
+         /* we already have this buffer on our list */
+ 
+         op->buffers[i].refcount++;
+         osi_Log0(afsd_logp,
+                  "cm_DirOpAddBuffer: the buffer is already listed for the dirOp");
+         return 0;
+     } else {
+         /* we have to add a new buffer */
+         osi_assertx(op->nBuffers < CM_DIROP_MAXBUFFERS - 1,
+                     "DirOp has exceeded CM_DIROP_MAXBUFFERS buffers");
+ 
+         for (i=0; i < CM_DIROP_MAXBUFFERS; i++) {
+             if (!(op->buffers[i].flags & CM_DIROPBUFF_INUSE))
+                 break;
+         }
+ 
+         osi_assert(i < CM_DIROP_MAXBUFFERS);
+ 
+         lock_ObtainMutex(&bufferp->mx);
+         lock_ObtainMutex(&op->scp->mx);
+ 
+         /* Make sure we are synchronized. */
+         code = cm_SyncOp(op->scp, bufferp, op->userp, &op->req, PRSFS_LOOKUP,
+                          CM_SCACHESYNC_NEEDCALLBACK |
+                          CM_SCACHESYNC_WRITE |
+                          CM_SCACHESYNC_BUFLOCKED);
+ 
+         if (code == 0 &&
+             bufferp->dataVersion != op->dataVersion) {
+ 
+             osi_Log2(afsd_logp, "cm_DirOpAddBuffer: buffer version mismatch. buf ver = %d. want %d", bufferp->dataVersion, op->dataVersion);
+ 
+             cm_SyncOpDone(op->scp, bufferp,
+                           CM_SCACHESYNC_NEEDCALLBACK |
+                           CM_SCACHESYNC_WRITE |
+                           CM_SCACHESYNC_BUFLOCKED);
+ 
+             code = CM_ERROR_INVAL;
+         }
+ 
+         lock_ReleaseMutex(&op->scp->mx);
+         lock_ReleaseMutex(&bufferp->mx);
+ 
+         if (code) {
+             osi_Log1(afsd_logp, "cm_DirOpAddBuffer: failed to sync buffer.  code=0x%x",
+                      code);
+             return code;
+         }
+ 
+         buf_Hold(bufferp);
+         op->buffers[i].bufferp = bufferp;
+         op->buffers[i].refcount = 1; /* start with one ref */
+         op->buffers[i].flags = CM_DIROPBUFF_INUSE;
+ 
+         op->nBuffers++;
+ 
+         osi_Log0(afsd_logp, "cm_DirOpAddBuffer: returning success");
+ 
+         return 0;
+     }
+ }
+ 
+ /* Note: Called without op->scp->mx */
+ static int
+ cm_DirOpFindBuffer(cm_dirOp_t * op, osi_hyper_t offset, cm_buf_t ** bufferpp)
+ {
+     int i;
+ 
+     for (i=0; i < CM_DIROP_MAXBUFFERS; i++) {
+         if ((op->buffers[i].flags & CM_DIROPBUFF_INUSE) &&
+             LargeIntegerEqualTo(op->buffers[i].bufferp->offset, offset))
+             break;
+     }
+ 
+     if (i < CM_DIROP_MAXBUFFERS) {
+         /* found it */
+         op->buffers[i].refcount++;
+         buf_Hold(op->buffers[i].bufferp);
+         *bufferpp = op->buffers[i].bufferp;
+ 
+         osi_Log2(afsd_logp, "cm_DirOpFindBuffer: found buffer for offset [%x:%x]",
+                  offset.HighPart, offset.LowPart);
+         return 1;
+     }
+ 
+     osi_Log2(afsd_logp, "cm_DirOpFindBuffer: buffer not found for offset [%x:%x]",
+              offset.HighPart, offset.LowPart);
+     return 0;
+ }
+ 
+ 
+ /* NOTE: called with scp->mx NOT held */
+ static int
+ cm_DirOpDelBuffer(cm_dirOp_t * op, cm_buf_t * bufferp, int flags)
+ {
+     int i;
+ 
+     osi_Log3(afsd_logp, "cm_DirOpDelBuffer for op 0x%p, buffer 0x%p, flags=%d",
+              op, bufferp, flags);
+ 
+     for (i=0; i < CM_DIROP_MAXBUFFERS; i++) {
+         if ((op->buffers[i].flags & CM_DIROPBUFF_INUSE) &&
+             op->buffers[i].bufferp == bufferp)
+             break;
+     }
+ 
+     if (i < CM_DIROP_MAXBUFFERS) {
+ 
+         if (flags & DIROP_MODIFIED)
+             op->dirtyBufCount++;
+ 
+         osi_assert(op->buffers[i].refcount > 0);
+         op->buffers[i].refcount --;
+ 
+         if (op->buffers[i].refcount == 0) {
+             /* this was the last reference we had */
+ 
+             osi_Log0(afsd_logp, "cm_DirOpDelBuffer: releasing buffer");
+ 
+             /* if this buffer was modified, then we update the data
+                version of the buffer with the data version of the
+                scp. */
+             if (!(flags & DIROP_SCPLOCKED)) {
+                 lock_ObtainMutex(&op->scp->mx);
+             }
+ 
+             /* first make sure that the buffer is idle.  It should
+                have been idle all along. */
+             osi_assertx((bufferp->cmFlags & (CM_BUF_CMFETCHING |
+                                             CM_BUF_CMSTORING)) == 0,
+                         "Buffer is not idle while performing dirOp");
+ 
+             cm_SyncOpDone(op->scp, bufferp,
+                           CM_SCACHESYNC_NEEDCALLBACK |
+                           CM_SCACHESYNC_WRITE);
+ 
+ #ifdef DEBUG
+             osi_assert(bufferp->dataVersion == op->dataVersion);
+ #endif
+ 
+             lock_ReleaseMutex(&op->scp->mx);
+ 
+             lock_ObtainMutex(&bufferp->mx);
+ 
+             if (flags & DIROP_SCPLOCKED) {
+                 lock_ObtainMutex(&op->scp->mx);
+             }
+ 
+             if (flags & DIROP_MODIFIED) {
+                 /* We don't update the dataversion here.  Instead we
+                    wait until the dirOp is completed and then flip the
+                    dataversion on all the buffers in one go.
+                    Otherwise we won't know if the dataversion is
+                    current because it was fetched from the server or
+                    because we touched it during the dirOp. */
+ 
+                 if (bufferp->userp != op->userp) {
+                     if (bufferp->userp != NULL)
+                         cm_ReleaseUser(bufferp->userp);
+                     cm_HoldUser(op->userp);
+                     bufferp->userp = op->userp;
+                 }
+             }
+ 
+             lock_ReleaseMutex(&bufferp->mx);
+ 
+             op->buffers[i].bufferp = NULL;
+             buf_Release(bufferp);
+             op->buffers[i].flags = 0;
+ 
+             op->nBuffers--;
+ 
+             return 1;
+         } else {
+             /* we have other references to this buffer. so we have to
+                let it be */
+             return 0;
+         }
+ 
+     } else {
+         osi_Log0(afsd_logp, "cm_DirOpDelBuffer: buffer not found");
+         osi_assertx(FALSE, "Attempt to delete a non-existent buffer from a dirOp");
+         return -1;
+     }
+ }
+ 
+ /* Check if we have current status and a callback for the given scp.
+    This should be called before cm_DirGetPage() is called per scp.
+ 
+    On entry:
+      scp->mx locked
+ 
+    On exit:
+      scp->mx locked
+ 
+    During:
+      scp->mx may be released
+  */
+ static long
+ cm_DirCheckStatus(cm_dirOp_t * op)
+ {
+     long code;
+ 
+     code = cm_SyncOp(op->scp, NULL, op->userp, &op->req, PRSFS_LOOKUP,
+                      CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ 
+     osi_Log2(afsd_logp, "cm_DirCheckStatus for op 0x%p returning code 0x%x",
+              op, code);
+ 
+     return code;
+ }
+ 
+ /* Release a directory buffer that was obtained via a call to
+    cm_DirGetPage() or any other function that returns a locked, held,
+    directory page buffer.
+ 
+    Called with scp->mx held
+  */
+ static long
+ cm_DirReleasePage(cm_dirOp_t * op, cm_buf_t ** bufferpp, int modified)
+ {
+     long code = 0;
+ 
+     if (!*bufferpp)
+         return EINVAL;
+ 
+     cm_DirOpDelBuffer(op, *bufferpp,
+                       ((modified ? DIROP_MODIFIED : 0) | DIROP_SCPLOCKED));
+     buf_Release(*bufferpp);
+     *bufferpp = NULL;
+ 
+     return code;
+ }
+ 
+ /*
+    Returns the index'th directory page from scp.  The userp and reqp
+    will be used to fetch the buffer from the fileserver if necessary.
+    If the call is successful, a locked and held cm_buf_t is returned
+    via buferpp and a pointer to the directory page is returned via
+    datapp.
+ 
+    The returned buffer should be released via a call to
+    cm_DirReleasePage() or by passing it into a subsequent call to
+    cm_DirGetPage() for the *same* scp.
+ 
+    If a *locked* buffer for the *same* scp is passed in via bufferpp
+    to the function, it will check if the requested directory page is
+    located in the specified buffer.  If not, the buffer will be
+    released and a new buffer returned that contains the requested
+    page.
+ 
+    Note: If a buffer is specified on entry via bufferpp, it is assumed
+    that the buffer is unmodified.  If the buffer is modified, it
+    should be released via cm_DirReleasePage().
+ 
+    On entry:
+      scp->mx locked.
+      If *bufferpp is non-NULL, then *bufferpp->mx is locked.
+ 
+    On exit:
+      scp->mxlocked
+      If *bufferpp is non-NULL, then *bufferpp->mx is locked.
+ 
+    During:
+      scp->mx will be released
+ 
+  */
+ static long
+ cm_DirGetPage(cm_dirOp_t * op,
+               long index, cm_buf_t ** bufferpp, void ** datapp)
+ {
+     osi_hyper_t pageOffset;     /* offset of the dir page from the
+                                    start of the directory */
+     osi_hyper_t bufferOffset;   /* offset of the buffer from the start
+                                    of the directory */
+     osi_hyper_t thyper;
+ 
+     cm_buf_t * bufferp = NULL;
+ 
+     void * datap = NULL;
+ 
+     long code = 0;
+ 
+     osi_Log2(afsd_logp, "cm_DirGetPage for op 0x%p, index %d", op, index);
+ 
+     pageOffset = ConvertLongToLargeInteger(index * CM_DIR_PAGESIZE);
+     bufferOffset.HighPart = pageOffset.HighPart;
+     bufferOffset.LowPart = pageOffset.LowPart & ~(cm_data.buf_blockSize - 1);
+ 
+     bufferp = *bufferpp;
+     if (bufferp != NULL) {
+         osi_assert(cm_FidCmp(&bufferp->fid, &op->scp->fid) == 0);
+ 
+         thyper = bufferp->offset;
+     }
+ 
+     lock_ReleaseMutex(&op->scp->mx);
+ 
+     if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) {
+         /* wrong buffer */
+ 
+         if (bufferp) {
+             buf_Release(bufferp);
+             cm_DirOpDelBuffer(op, bufferp, 0);
+             bufferp = NULL;
+         }
+ 
+         /* first check if we are already working with the buffer */
+         if (cm_DirOpFindBuffer(op, bufferOffset, &bufferp)) {
+             code = 0;
+             goto _has_buffer;
+         }
+ 
+         lock_ObtainRead(&op->scp->bufCreateLock);
+         code = buf_Get(op->scp, &bufferOffset, &bufferp);
+         lock_ReleaseRead(&op->scp->bufCreateLock);
+ 
+         if (code) {
+             osi_Log1(afsd_logp, "    buf_Get returned code 0x%x", code);
+             bufferp = NULL;
+             goto _exit;
+         }
+ 
+         osi_assert(bufferp != NULL);
+ 
+         /* DirOpAddBuffer will obtain bufferp->mx if necessary */
+         code = cm_DirOpAddBuffer(op, bufferp);
+ 
+         if (code != 0) {
+             /* for some reason, the buffer was rejected.  We can't use
+                this buffer, and since this is the only buffer we can
+                potentially use, there's no recourse.*/
+             buf_Release(bufferp);
+             bufferp = NULL;
+             goto _exit;
+         }
+ 
+ #if 0
+         /* The code below is for making sure the buffer contains
+            current data.  This is a bad idea, since the whole point of
+            doing directory updates locally is to avoid fetching all
+            the data from the server. */
+         while (1) {
+             lock_ObtainMutex(&op->scp->mx);
+             code = cm_SyncOp(op->scp, bufferp, op->userp, &op->req, PRSFS_LOOKUP,
+                              CM_SCACHESYNC_NEEDCALLBACK |
+                              CM_SCACHESYNC_READ |
+                              CM_SCACHESYNC_BUFLOCKED);
+ 
+             if (code) {
+                 lock_ReleaseMutex(&op->scp->mx);
+                 break;
+             }
+ 
+             cm_SyncOpDone(op->scp, bufferp,
+                           CM_SCACHESYNC_NEEDCALLBACK |
+                           CM_SCACHESYNC_READ |
+                           CM_SCACHESYNC_BUFLOCKED);
+ 
+             if (cm_HaveBuffer(op->scp, bufferp, 1)) {
+                 lock_ReleaseMutex(&op->scp->mx);
+                 break;
+             }
+ 
+             lock_ReleaseMutex(&bufferp->mx);
+             code = cm_GetBuffer(op->scp, bufferp, NULL, op->userp, &op->req);
+             lock_ReleaseMutex(&op->scp->mx);
+             lock_ObtainMutex(&bufferp->mx);
+ 
+             if (code)
+                 break;
+         }
+ 
+         if (code) {
+             cm_DirOpDelBuffer(op, bufferp, 0);
+             buf_Release(bufferp);
+             bufferp = NULL;
+             goto _exit;
+         }
+ #endif
+     }
+ 
+  _has_buffer:
+ 
+     /* now to figure out where the data is */
+     thyper = LargeIntegerSubtract(pageOffset, bufferOffset);
+ 
+     osi_assert(thyper.HighPart == 0);
+     osi_assert(cm_data.buf_blockSize > thyper.LowPart &&
+                cm_data.buf_blockSize - thyper.LowPart >= CM_DIR_PAGESIZE);
+ 
+     datap = (void *) (((char *)bufferp->datap) + thyper.LowPart);
+ 
+     if (datapp)
+         *datapp = datap;
+ 
+     /* also, if we are writing past EOF, we should make a note of the
+        new length */
+     thyper = LargeIntegerAdd(pageOffset,
+                              ConvertLongToLargeInteger(CM_DIR_PAGESIZE));
+     if (LargeIntegerLessThan(op->newLength, thyper)) {
+         op->newLength = thyper;
+     }
+ 
+  _exit:
+ 
+     *bufferpp = bufferp;
+     if (op->scp)
+         lock_ObtainMutex(&op->scp->mx);
+ 
+     osi_Log1(afsd_logp, "cm_DirGetPage returning code 0x%x", code);
+ 
+     return code;
+ }
+ 
+ 
+ void
+ cm_DirEntryListAdd(char * namep, cm_dirEntryList_t ** list)
+ {
+     size_t len;
+     cm_dirEntryList_t * entry;
+ 
+     len = strlen(namep);
+     len += sizeof(cm_dirEntryList_t);
+ 
+     entry = malloc(len);
+     if (entry) {
+         entry->nextp = *list;
+         strcpy(entry->name, namep);
+         *list = entry;
+     }
+ }
+ 
+ void
+ cm_DirEntryListFree(cm_dirEntryList_t ** list)
+ {
+     cm_dirEntryList_t * entry;
+     cm_dirEntryList_t * next;
+ 
+     for (entry = *list; entry; entry = next) {
+         next = entry->nextp;
+         free(entry);
+     }
+ 
+     *list = NULL;
+ }
+ 
Index: openafs/src/WINNT/afsd/cm_dir.h
diff -c openafs/src/WINNT/afsd/cm_dir.h:1.4.4.1 openafs/src/WINNT/afsd/cm_dir.h:1.4.4.2
*** openafs/src/WINNT/afsd/cm_dir.h:1.4.4.1	Mon Feb 19 22:14:45 2007
--- openafs/src/WINNT/afsd/cm_dir.h	Thu Aug  2 16:53:52 2007
***************
*** 31,36 ****
--- 31,39 ----
  						 * header alone.
  						 */
  
+ #define CM_DIR_FFIRST           1
+ #define CM_DIR_FNEXT            2
+ 
  typedef struct cm_dirFid {
  	/* A file identifier. */
  	afs_int32 vnode;	/* file's vnode slot */
***************
*** 56,63 ****
  	unsigned short hashTable[CM_DIR_NHASHENT];
  } cm_dirHeader_t;
  
! /* this represents a directory entry.  We use strlen to find out how many bytes are
!  * really in the dir entry; it is always a multiple of 32.
   */
  typedef struct cm_dirEntry {
  	/* A directory entry */
--- 59,67 ----
  	unsigned short hashTable[CM_DIR_NHASHENT];
  } cm_dirHeader_t;
  
! /* this represents a directory entry.  We use strlen to find out how
!  * many bytes are really in the dir entry; it is always a multiple of
!  * 32.
   */
  typedef struct cm_dirEntry {
  	/* A directory entry */
***************
*** 87,92 ****
  } cm_dirPage1_t;
  #endif /* UNUSED */
  
! extern long cm_NameEntries(char *namep, long *lenp);
  
  #endif /*  __CM_DIR_ENV__ */
--- 91,178 ----
  } cm_dirPage1_t;
  #endif /* UNUSED */
  
! #define CM_DIROP_MAXBUFFERS 8
! 
! typedef struct cm_dirOpBuffer {
!     int        flags;
!     cm_buf_t * bufferp;
!     int        refcount;
! } cm_dirOpBuffer_t;
! 
! #define CM_DIROPBUFF_INUSE      0x1
! 
! /* Used for managing transactional directory operations.  Each
!    instance should only be used by one thread. */
! typedef struct cm_dirOp {
!     cm_scache_t * scp;
!     cm_user_t *   userp;
!     cm_req_t      req;
! 
!     osi_hyper_t   length;       /* scp->length at the time
!                                    cm_BeginDirOp() was called.*/
!     osi_hyper_t   newLength;    /* adjusted scp->length */
!     afs_uint32    dataVersion;  /* scp->dataVersion when
!                                    cm_BeginDirOp() was called.*/
!     afs_uint32    newDataVersion; /* scp->dataVersion when
!                                      cm_CheckDirOpForSingleChange()
!                                      was called. */
! 
!     afs_uint32    dirtyBufCount;
! 
!     int           nBuffers;     /* number of buffers below */
!     cm_dirOpBuffer_t buffers[CM_DIROP_MAXBUFFERS];
! } cm_dirOp_t;
! 
! extern long
! cm_BeginDirOp(cm_scache_t * scp, cm_user_t * userp, cm_req_t * reqp,
!               cm_dirOp_t * op);
! 
! extern int
! cm_CheckDirOpForSingleChange(cm_dirOp_t * op);
! 
! extern long
! cm_EndDirOp(cm_dirOp_t * op);
! 
! extern long
! cm_NameEntries(char *namep, long *lenp);
! 
! extern long
! cm_DirCreateEntry(cm_dirOp_t * op, char *entry, cm_fid_t * cfid);
! 
! extern int
! cm_DirLength(cm_dirOp_t * op);
! 
! extern int
! cm_DirDeleteEntry(cm_dirOp_t * op, char *entry);
! 
! extern int
! cm_DirMakeDir(cm_dirOp_t * op, cm_fid_t * me, cm_fid_t * parent);
! 
! extern int
! cm_DirLookup(cm_dirOp_t * op, char *entry, cm_fid_t * cfid);
! 
! extern int
! cm_DirLookupOffset(cm_dirOp_t * op, char *entry, cm_fid_t *cfid, osi_hyper_t *offsetp);
! 
! extern int
! cm_DirApply(cm_dirOp_t * op, int (*hookproc) (void *, char *, long, long), void *hook);
! 
! extern int
! cm_DirIsEmpty(cm_dirOp_t * op);
! 
! extern int
! cm_DirHash(char *string);
! 
! /* Directory entry lists */
! typedef struct cm_dirEntryList {
!     struct cm_dirEntryList * nextp;
!     char   name[1];
! } cm_dirEntryList_t;
! 
! extern void
! cm_DirEntryListAdd(char * namep, cm_dirEntryList_t ** list);
! 
! extern void
! cm_DirEntryListFree(cm_dirEntryList_t ** list);
  
  #endif /*  __CM_DIR_ENV__ */
Index: openafs/src/WINNT/afsd/cm_ioctl.c
diff -c openafs/src/WINNT/afsd/cm_ioctl.c:1.73.2.18 openafs/src/WINNT/afsd/cm_ioctl.c:1.73.2.19
*** openafs/src/WINNT/afsd/cm_ioctl.c:1.73.2.18	Sat Jun 30 00:44:23 2007
--- openafs/src/WINNT/afsd/cm_ioctl.c	Sun Jul 22 19:10:17 2007
***************
*** 1995,2001 ****
      if (r && !stricmp(r+1,ucellp->cellp->name))
  	*r = '\0';
  
!     code = ubik_Call(PR_NameToID, pruclient, 0, &lnames, &lids);
      if (lids.idlist_val) {
  	*uid = *lids.idlist_val;
  	free(lids.idlist_val);
--- 1995,2001 ----
      if (r && !stricmp(r+1,ucellp->cellp->name))
  	*r = '\0';
  
!     code = ubik_PR_NameToID(pruclient, 0, &lnames, &lids);
      if (lids.idlist_val) {
  	*uid = *lids.idlist_val;
  	free(lids.idlist_val);
Index: openafs/src/WINNT/afsd/cm_scache.c
diff -c openafs/src/WINNT/afsd/cm_scache.c:1.35.2.39 openafs/src/WINNT/afsd/cm_scache.c:1.35.2.41
*** openafs/src/WINNT/afsd/cm_scache.c:1.35.2.39	Fri Jul  6 19:22:03 2007
--- openafs/src/WINNT/afsd/cm_scache.c	Thu Aug  9 01:33:56 2007
***************
*** 107,112 ****
--- 107,114 ----
  		lock_ObtainMutex(&bufp->mx);
  		bufp->cmFlags &= ~CM_BUF_CMSTORING;
  		bufp->flags &= ~CM_BUF_DIRTY;
+                 bufp->dirty_offset = 0;
+                 bufp->dirty_length = 0;
  		bufp->flags |= CM_BUF_ERROR;
  		bufp->error = VNOVNODE;
  		bufp->dataVersion = -1; /* bad */
***************
*** 127,132 ****
--- 129,136 ----
  		lock_ObtainMutex(&bufp->mx);
  		bufp->cmFlags &= ~CM_BUF_CMFETCHING;
  		bufp->flags &= ~CM_BUF_DIRTY;
+                 bufp->dirty_offset = 0;
+                 bufp->dirty_length = 0;
  		bufp->flags |= CM_BUF_ERROR;
  		bufp->error = VNOVNODE;
  		bufp->dataVersion = -1; /* bad */
***************
*** 966,973 ****
                  osi_Log1(afsd_logp, "CM SyncOp scp 0x%p is FETCHING|STORING|SIZESTORING|GETCALLBACK want FETCHDATA", scp);
                  goto sleep;
              }
!             if (bufp && (bufp->cmFlags & (CM_BUF_CMFETCHING | CM_BUF_CMSTORING))) {
!                 osi_Log2(afsd_logp, "CM SyncOp scp 0x%p bufp 0x%p is BUF_CMFETCHING|BUF_CMSTORING want FETCHDATA", scp, bufp);
                  goto sleep;
              }
          }
--- 970,977 ----
                  osi_Log1(afsd_logp, "CM SyncOp scp 0x%p is FETCHING|STORING|SIZESTORING|GETCALLBACK want FETCHDATA", scp);
                  goto sleep;
              }
!             if (bufp && (bufp->cmFlags & (CM_BUF_CMFETCHING | CM_BUF_CMSTORING | CM_BUF_CMWRITING))) {
!                 osi_Log2(afsd_logp, "CM SyncOp scp 0x%p bufp 0x%p is BUF_CMFETCHING|BUF_CMSTORING|BUF_CMWRITING want FETCHDATA", scp, bufp);
                  goto sleep;
              }
          }
***************
*** 978,985 ****
                  osi_Log1(afsd_logp, "CM SyncOp scp 0x%p is FETCHING|STORING|SIZESTORING|GETCALLBACK want STOREDATA", scp);
                  goto sleep;
              }
!             if (bufp && (bufp->cmFlags & (CM_BUF_CMFETCHING | CM_BUF_CMSTORING))) {
!                 osi_Log2(afsd_logp, "CM SyncOp scp 0x%p bufp 0x%p is BUF_CMFETCHING|BUF_CMSTORING want STOREDATA", scp, bufp);
                  goto sleep;
              }
          }
--- 982,989 ----
                  osi_Log1(afsd_logp, "CM SyncOp scp 0x%p is FETCHING|STORING|SIZESTORING|GETCALLBACK want STOREDATA", scp);
                  goto sleep;
              }
!             if (bufp && (bufp->cmFlags & (CM_BUF_CMFETCHING | CM_BUF_CMSTORING | CM_BUF_CMWRITING))) {
!                 osi_Log2(afsd_logp, "CM SyncOp scp 0x%p bufp 0x%p is BUF_CMFETCHING|BUF_CMSTORING|BUF_CMWRITING want STOREDATA", scp, bufp);
                  goto sleep;
              }
          }
***************
*** 1045,1050 ****
--- 1049,1058 ----
                  osi_Log2(afsd_logp, "CM SyncOp scp 0x%p bufp 0x%p is BUF_CMFETCHING want READ", scp, bufp);
                  goto sleep;
              }
+             if (bufp && (bufp->cmFlags & CM_BUF_CMWRITING)) {
+                 osi_Log2(afsd_logp, "CM SyncOp scp 0x%p bufp 0x%p is BUF_CMWRITING want READ", scp, bufp);
+                 goto sleep;
+             }
          }
          if (flags & CM_SCACHESYNC_WRITE) {
              /* don't write unless the status is stable and the chunk
***************
*** 1055,1062 ****
                  osi_Log1(afsd_logp, "CM SyncOp scp 0x%p is FETCHING|STORING|SIZESTORING want WRITE", scp);
                  goto sleep;
              }
!             if (bufp && (bufp->cmFlags & (CM_BUF_CMFETCHING | CM_BUF_CMSTORING))) {
!                 osi_Log2(afsd_logp, "CM SyncOp scp 0x%p bufp 0x%p is BUF_CMFETCHING|BUF_CMSTORING want WRITE", scp, bufp);
                  goto sleep;
              }
          }
--- 1063,1077 ----
                  osi_Log1(afsd_logp, "CM SyncOp scp 0x%p is FETCHING|STORING|SIZESTORING want WRITE", scp);
                  goto sleep;
              }
!             if (bufp && (bufp->cmFlags & (CM_BUF_CMFETCHING |
!                                           CM_BUF_CMSTORING |
!                                           CM_BUF_CMWRITING))) {
!                 osi_Log3(afsd_logp, "CM SyncOp scp 0x%p bufp 0x%p is %s want WRITE",
!                          scp, bufp,
!                          ((bufp->cmFlags & CM_BUF_CMFETCHING) ? "CM_BUF_CMFETCHING":
!                           ((bufp->cmFlags & CM_BUF_CMSTORING) ? "CM_BUF_CMSTORING" :
!                            ((bufp->cmFlags & CM_BUF_CMWRITING) ? "CM_BUF_CMWRITING" :
!                             "UNKNOWN!!!"))));
                  goto sleep;
              }
          }
***************
*** 1217,1222 ****
--- 1232,1244 ----
          osi_QAdd((osi_queue_t **) &scp->bufWritesp, &qdp->q);
      }
  
+     if (flags & CM_SCACHESYNC_WRITE) {
+         /* mark the buffer as being written to. */
+         if (bufp) {
+             bufp->cmFlags |= CM_BUF_CMWRITING;
+         }
+     }
+ 
      return 0;
  }
  
***************
*** 1297,1302 ****
--- 1319,1332 ----
          }
      }
  
+     if (flags & CM_SCACHESYNC_WRITE) {
+         if (bufp) {
+             osi_assert(bufp->cmFlags & CM_BUF_CMWRITING);
+ 
+             bufp->cmFlags &= ~CM_BUF_CMWRITING;
+         }
+     }
+ 
      /* and wakeup anyone who is waiting */
      if (scp->flags & CM_SCACHEFLAG_WAITING) {
          osi_Log1(afsd_logp, "CM SyncOpDone Waking scp 0x%p", scp);
Index: openafs/src/WINNT/afsd/cm_server.c
diff -c openafs/src/WINNT/afsd/cm_server.c:1.25.2.11 openafs/src/WINNT/afsd/cm_server.c:1.25.2.12
*** openafs/src/WINNT/afsd/cm_server.c:1.25.2.11	Sat Jul  7 09:38:33 2007
--- openafs/src/WINNT/afsd/cm_server.c	Thu Aug  2 16:46:12 2007
***************
*** 110,115 ****
--- 110,116 ----
      if (code >= 0) {
  	/* mark server as up */
  	tsp->flags &= ~CM_SERVERFLAG_DOWN;
+         tsp->downTime = 0;
  
  	/* we currently handle 32-bits of capabilities */
  	if (caps.Capabilities_len > 0) {
***************
*** 152,157 ****
--- 153,159 ----
      } else {
  	/* mark server as down */
  	tsp->flags |= CM_SERVERFLAG_DOWN;
+         tsp->downTime = osi_Time();
  	if (code != VRESTARTING)
  	    cm_ForceNewConnections(tsp);
  
Index: openafs/src/WINNT/afsd/cm_server.h
diff -c openafs/src/WINNT/afsd/cm_server.h:1.13.2.8 openafs/src/WINNT/afsd/cm_server.h:1.13.2.9
*** openafs/src/WINNT/afsd/cm_server.h:1.13.2.8	Thu Jun 28 00:50:15 2007
--- openafs/src/WINNT/afsd/cm_server.h	Thu Aug  2 16:46:12 2007
***************
*** 40,45 ****
--- 40,46 ----
      osi_mutex_t mx;
      unsigned short ipRank;		/* server priority */
      cm_server_vols_t *  vols;           /* by mx */
+     time_t downTime;                    /* by mx */
  } cm_server_t;
  
  enum repstate {srv_not_busy, srv_busy, srv_offline, srv_deleted};
Index: openafs/src/WINNT/afsd/cm_vnodeops.c
diff -c openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.32 openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.34
*** openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.32	Wed Jun 13 18:28:25 2007
--- openafs/src/WINNT/afsd/cm_vnodeops.c	Thu Aug  2 16:58:42 2007
***************
*** 604,618 ****
      {
          cm_lookupSearch_t*	sp = parmp;
  
  #ifdef AFS_FREELANCE_CLIENT
  	/* Freelance entries never end up in the DNLC because they
  	 * do not have an associated cm_server_t
  	 */
!     if ( !(cm_freelanceEnabled &&
              sp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
!             sp->fid.volume==AFS_FAKE_ROOT_VOL_ID ) )
! #endif /* AFS_FREELANCE_CLIENT */
!     {
          int casefold = sp->caseFold;
          sp->caseFold = 0; /* we have a strong preference for exact matches */
          if ( *retscp = cm_dnlcLookup(scp, sp))	/* dnlc hit */
--- 604,621 ----
      {
          cm_lookupSearch_t*	sp = parmp;
  
+         if (
  #ifdef AFS_FREELANCE_CLIENT
  	/* Freelance entries never end up in the DNLC because they
  	 * do not have an associated cm_server_t
  	 */
!             !(cm_freelanceEnabled &&
              sp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
!               sp->fid.volume==AFS_FAKE_ROOT_VOL_ID )
! #else /* !AFS_FREELANCE_CLIENT */
!             TRUE
! #endif
!             ) {
          int casefold = sp->caseFold;
          sp->caseFold = 0; /* we have a strong preference for exact matches */
          if ( *retscp = cm_dnlcLookup(scp, sp))	/* dnlc hit */
***************
*** 622,627 ****
--- 625,656 ----
              return 0;
          }
          sp->caseFold = casefold;
+ 
+             /* see if we can find it using the directory hash tables.
+                we can only do exact matches, since the hash is case
+                sensitive. */
+             {
+                 cm_dirOp_t dirop;
+ 
+                 code = ENOENT;
+ 
+                 code = cm_BeginDirOp(scp, userp, reqp, &dirop);
+                 if (code == 0) {
+                     code = cm_DirLookup(&dirop, sp->searchNamep, &sp->fid);
+                     cm_EndDirOp(&dirop);
+                 }
+ 
+                 if (code == 0) {
+                     /* found it */
+                     sp->found = TRUE;
+                     sp->ExactFound = TRUE;
+                     lock_ReleaseMutex(&scp->mx);
+ 
+                     *retscp = NULL; /* force caller to call cm_GetSCache() */
+ 
+                     return 0;
+                 }
+             }
      }
      }	
  
***************
*** 1128,1133 ****
--- 1157,1164 ----
      cm_lookupSearch_t rock;
      int getroot;
  
+     memset(&rock, 0, sizeof(rock));
+ 
      if (dscp->fid.vnode == 1 && dscp->fid.unique == 1
           && strcmp(namep, "..") == 0) {
          if (dscp->dotdotFid.volume == 0)
***************
*** 1139,1145 ****
  	goto haveFid;
      }
  
!     memset(&rock, 0, sizeof(rock));
      rock.fid.cell = dscp->fid.cell;
      rock.fid.volume = dscp->fid.volume;
      rock.searchNamep = namep;
--- 1170,1199 ----
  	goto haveFid;
      }
  
!     if (flags & CM_FLAG_NOMOUNTCHASE) {
!         /* In this case, we should go and call cm_Dir* functions
!            directly since the following cm_ApplyDir() function will
!            not. */
! 
!         cm_dirOp_t dirop;
! 
!         lock_ObtainMutex(&dscp->mx);
! 
!         code = cm_BeginDirOp(dscp, userp, reqp, &dirop);
!         if (code == 0) {
!             code = cm_DirLookup(&dirop, namep, &rock.fid);
!             cm_EndDirOp(&dirop);
!         }
! 
!         lock_ReleaseMutex(&dscp->mx);
! 
!         if (code == 0) {
!             /* found it */
!             rock.found = TRUE;
!             goto haveFid;
!         }
!     }
! 
      rock.fid.cell = dscp->fid.cell;
      rock.fid.volume = dscp->fid.volume;
      rock.searchNamep = namep;
***************
*** 1486,1491 ****
--- 1540,1546 ----
      AFSFetchStatus newDirStatus;
      AFSVolSync volSync;
      struct rx_connection * callp;
+     cm_dirOp_t dirop;
  
  #ifdef AFS_FREELANCE_CLIENT
      if (cm_freelanceEnabled && dscp == cm_data.rootSCachep) {
***************
*** 1497,1507 ****
  
      /* make sure we don't screw up the dir status during the merge */
      lock_ObtainMutex(&dscp->mx);
      sflags = CM_SCACHESYNC_STOREDATA;
      code = cm_SyncOp(dscp, NULL, userp, reqp, 0, sflags);
      lock_ReleaseMutex(&dscp->mx);
!     if (code) 
          return code;
  
      /* make the RPC */
      afsFid.Volume = dscp->fid.volume;
--- 1552,1567 ----
  
      /* make sure we don't screw up the dir status during the merge */
      lock_ObtainMutex(&dscp->mx);
+ 
+     code = cm_BeginDirOp(dscp, userp, reqp, &dirop);
+ 
      sflags = CM_SCACHESYNC_STOREDATA;
      code = cm_SyncOp(dscp, NULL, userp, reqp, 0, sflags);
      lock_ReleaseMutex(&dscp->mx);
!     if (code) {
!         cm_EndDirOp(&dirop);
          return code;
+     }
  
      /* make the RPC */
      afsFid.Volume = dscp->fid.volume;
***************
*** 1530,1544 ****
      lock_ObtainMutex(&dscp->mx);
      cm_dnlcRemove(dscp, namep);
      cm_SyncOpDone(dscp, NULL, sflags);
!     if (code == 0) 
          cm_MergeStatus(NULL, dscp, &newDirStatus, &volSync, userp, 0);
!     else if (code == CM_ERROR_NOSUCHFILE) {
  	/* windows would not have allowed the request to delete the file 
  	 * if it did not believe the file existed.  therefore, we must 
  	 * have an inconsistent view of the world.
  	 */
  	dscp->cbServerp = NULL;
      }
      lock_ReleaseMutex(&dscp->mx);
  
      return code;
--- 1590,1608 ----
      lock_ObtainMutex(&dscp->mx);
      cm_dnlcRemove(dscp, namep);
      cm_SyncOpDone(dscp, NULL, sflags);
!     if (code == 0) {
          cm_MergeStatus(NULL, dscp, &newDirStatus, &volSync, userp, 0);
!         if (cm_CheckDirOpForSingleChange(&dirop)) {
!             cm_DirDeleteEntry(&dirop, namep);
!         }
!     } else if (code == CM_ERROR_NOSUCHFILE) {
  	/* windows would not have allowed the request to delete the file 
  	 * if it did not believe the file existed.  therefore, we must 
  	 * have an inconsistent view of the world.
  	 */
  	dscp->cbServerp = NULL;
      }
+     cm_EndDirOp(&dirop);
      lock_ReleaseMutex(&dscp->mx);
  
      return code;
***************
*** 1724,1729 ****
--- 1788,1797 ----
      int symlinkCount;		/* count of # of symlinks traversed */
      int extraFlag;		/* avoid chasing mt pts for dir cmd */
      int phase = 1;		/* 1 = tidPathp, 2 = pathp */
+ #define MAX_FID_COUNT 512
+     cm_fid_t fids[MAX_FID_COUNT]; /* array of fids processed in this path walk */
+     int fid_count = 0;          /* number of fids processed in this path walk */
+     int i;
  
  #ifdef DEBUG_REFCOUNT
      afsi_log("%s:%d cm_NameI rootscp 0x%p ref %d", file, line, rootSCachep, rootSCachep->refCount);
***************
*** 1787,1793 ****
  		code = cm_Lookup(tscp, component,
  				  flags | extraFlag,
  				  userp, reqp, &nscp);
! 		if (code) {
  		    cm_ReleaseSCache(tscp);
  		    if (dirScp)
  			cm_ReleaseSCache(dirScp);
--- 1855,1876 ----
  		code = cm_Lookup(tscp, component,
  				  flags | extraFlag,
  				  userp, reqp, &nscp);
! 
!                 if (code == 0) {
!                     for ( i=0; i<fid_count; i++) {
!                         if ( !cm_FidCmp(&nscp->fid, &fids[i]) ) {
!                             code = CM_ERROR_TOO_MANY_SYMLINKS;
!                             cm_ReleaseSCache(nscp);
!                             nscp = NULL;
!                             break;
!                         }
!                     }
!                     if (i == fid_count && fid_count < MAX_FID_COUNT) {
!                         fids[fid_count++] = nscp->fid;
!                     }
!                 }
!                 
!                 if (code) {
  		    cm_ReleaseSCache(tscp);
  		    if (dirScp)
  			cm_ReleaseSCache(dirScp);
***************
*** 1855,1860 ****
--- 1938,1958 ----
                      else 
                          restp = tp;
                      code = cm_AssembleLink(tscp, restp, &linkScp, &tempsp, userp, reqp);
+ 
+                     if (code == 0 && linkScp != NULL) {
+                         for ( i=0; i<fid_count; i++) {
+                             if ( !cm_FidCmp(&linkScp->fid, &fids[i]) ) {
+                                 code = CM_ERROR_TOO_MANY_SYMLINKS;
+                                 cm_ReleaseSCache(linkScp);
+                                 nscp = NULL;
+                                 break;
+                             }
+                         }
+                         if (i == fid_count && fid_count < MAX_FID_COUNT) {
+                             fids[fid_count++] = linkScp->fid;
+                         }
+                     }
+ 
                      if (code) {
                          /* something went wrong */
                          cm_ReleaseSCache(tscp);
***************
*** 1987,1992 ****
--- 2085,2096 ----
      cm_FreeSpace(spacep);
      cm_ReleaseSCache(newRootScp);
  
+     if (linkScp == *outScpp) {
+         cm_ReleaseSCache(*outScpp);
+         *outScpp = NULL;
+         code = CM_ERROR_NOSUCHPATH;
+     }
+ 
      return code;
  }
  
***************
*** 2461,2467 ****
      cm_callbackRequest_t cbReq;
      AFSFid newAFSFid;
      cm_fid_t newFid;
!     cm_scache_t *scp;
      int didEnd;
      AFSStoreStatus inStatus;
      AFSFetchStatus updatedDirStatus;
--- 2565,2571 ----
      cm_callbackRequest_t cbReq;
      AFSFid newAFSFid;
      cm_fid_t newFid;
!     cm_scache_t *scp = NULL;
      int didEnd;
      AFSStoreStatus inStatus;
      AFSFetchStatus updatedDirStatus;
***************
*** 2469,2474 ****
--- 2573,2579 ----
      AFSCallBack newFileCallback;
      AFSVolSync volSync;
      struct rx_connection * callp;
+     cm_dirOp_t dirop;
  
      /* can't create names with @sys in them; must expand it manually first.
       * return "invalid request" if they try.
***************
*** 2482,2490 ****
--- 2587,2598 ----
       * completes.
       */
      lock_ObtainMutex(&dscp->mx);
+     cm_BeginDirOp(dscp, userp, reqp, &dirop);
      code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA);
      if (code == 0) {
          cm_StartCallbackGrantingCall(NULL, &cbReq);
+     } else {
+         cm_EndDirOp(&dirop);
      }
      lock_ReleaseMutex(&dscp->mx);
      if (code) {
***************
*** 2558,2563 ****
--- 2666,2678 ----
      if (!didEnd)
          cm_EndCallbackGrantingCall(NULL, &cbReq, NULL, 0);
  
+     lock_ObtainMutex(&dscp->mx);
+     if (scp && cm_CheckDirOpForSingleChange(&dirop)) {
+         cm_DirCreateEntry(&dirop, namep, &newFid);
+     }
+     cm_EndDirOp(&dirop);
+     lock_ReleaseMutex(&dscp->mx);
+ 
      return code;
  }       
  
***************
*** 2603,2608 ****
--- 2718,2724 ----
      AFSCallBack newDirCallback;
      AFSVolSync volSync;
      struct rx_connection * callp;
+     cm_dirOp_t dirop;
  
      /* can't create names with @sys in them; must expand it manually first.
       * return "invalid request" if they try.
***************
*** 2616,2624 ****
--- 2732,2743 ----
       * our call completes.
       */
      lock_ObtainMutex(&dscp->mx);
+     cm_BeginDirOp(dscp, userp, reqp, &dirop);
      code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA);
      if (code == 0) {
          cm_StartCallbackGrantingCall(NULL, &cbReq);
+     } else {
+         cm_EndDirOp(&dirop);
      }
      lock_ReleaseMutex(&dscp->mx);
      if (code) {
***************
*** 2691,2696 ****
--- 2810,2822 ----
      if (!didEnd)
          cm_EndCallbackGrantingCall(NULL, &cbReq, NULL, 0);
  
+     lock_ObtainMutex(&dscp->mx);
+     if (scp && cm_CheckDirOpForSingleChange(&dirop)) {
+         cm_DirCreateEntry(&dirop, namep, &newFid);
+     }
+     cm_EndDirOp(&dirop);
+     lock_ReleaseMutex(&dscp->mx);
+ 
      /* and return error code */
      return code;
  }       
***************
*** 2706,2711 ****
--- 2832,2838 ----
      AFSFetchStatus newLinkStatus;
      AFSVolSync volSync;
      struct rx_connection * callp;
+     cm_dirOp_t dirop;
  
      if (dscp->fid.cell != sscp->fid.cell ||
          dscp->fid.volume != sscp->fid.volume) {
***************
*** 2713,2719 ****
--- 2840,2849 ----
      }
  
      lock_ObtainMutex(&dscp->mx);
+     cm_BeginDirOp(dscp, userp, reqp, &dirop);
      code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA);
+     if (code != 0)
+         cm_EndDirOp(&dirop);
      lock_ReleaseMutex(&dscp->mx);
  
      if (code)
***************
*** 2753,2759 ****
--- 2883,2893 ----
      cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
      if (code == 0) {
          cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, 0);
+         if (cm_CheckDirOpForSingleChange(&dirop)) {
+             cm_DirCreateEntry(&dirop, namep, &sscp->fid);
+         }
      }
+     cm_EndDirOp(&dirop);
      lock_ReleaseMutex(&dscp->mx);
  
      return code;
***************
*** 2773,2785 ****
--- 2907,2923 ----
      AFSFetchStatus newLinkStatus;
      AFSVolSync volSync;
      struct rx_connection * callp;
+     cm_dirOp_t dirop;
  
      /* before starting the RPC, mark that we're changing the directory data,
       * so that someone who does a chmod on the dir will wait until our
       * call completes.
       */
      lock_ObtainMutex(&dscp->mx);
+     cm_BeginDirOp(dscp, userp, reqp, &dirop);
      code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA);
+     if (code != 0)
+         cm_EndDirOp(&dirop);
      lock_ReleaseMutex(&dscp->mx);
      if (code) {
          return code;
***************
*** 2817,2823 ****
--- 2955,2970 ----
      cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
      if (code == 0) {
          cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, 0);
+         if (cm_CheckDirOpForSingleChange(&dirop)) {
+             newFid.cell = dscp->fid.cell;
+             newFid.volume = dscp->fid.volume;
+             newFid.vnode = newAFSFid.Vnode;
+             newFid.unique = newAFSFid.Unique;
+ 
+             cm_DirCreateEntry(&dirop, namep, &newFid);
+         }
      }
+     cm_EndDirOp(&dirop);
      lock_ReleaseMutex(&dscp->mx);
  
      /* now try to create the new dir's entry, too, but be careful to 
***************
*** 2856,2872 ****
      AFSFetchStatus updatedDirStatus;
      AFSVolSync volSync;
      struct rx_connection * callp;
  
      /* before starting the RPC, mark that we're changing the directory data,
       * so that someone who does a chmod on the dir will wait until our
       * call completes.
       */
      lock_ObtainMutex(&dscp->mx);
      code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA);
-     lock_ReleaseMutex(&dscp->mx);
      if (code) {
          return code;
      }
      didEnd = 0;
  
      /* try the RPC now */
--- 3003,3023 ----
      AFSFetchStatus updatedDirStatus;
      AFSVolSync volSync;
      struct rx_connection * callp;
+     cm_dirOp_t dirOp;
  
      /* before starting the RPC, mark that we're changing the directory data,
       * so that someone who does a chmod on the dir will wait until our
       * call completes.
       */
      lock_ObtainMutex(&dscp->mx);
+     cm_BeginDirOp(dscp, userp, reqp, &dirOp);
      code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA);
      if (code) {
+         cm_EndDirOp(&dirOp);
+         lock_ReleaseMutex(&dscp->mx);
          return code;
      }
+     lock_ReleaseMutex(&dscp->mx);
      didEnd = 0;
  
      /* try the RPC now */
***************
*** 2899,2905 ****
--- 3050,3060 ----
      if (code == 0) {
          cm_dnlcRemove(dscp, namep); 
          cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, 0);
+         if (cm_CheckDirOpForSingleChange(&dirOp)) {
+             cm_DirDeleteEntry(&dirOp, namep);
      }
+     }
+     cm_EndDirOp(&dirOp);
      lock_ReleaseMutex(&dscp->mx);
  
      /* and return error code */
***************
*** 2937,2942 ****
--- 3092,3101 ----
      AFSVolSync volSync;
      int oneDir;
      struct rx_connection * callp;
+     cm_dirOp_t oldDirOp;
+     cm_fid_t   fileFid;
+     int        diropCode = -1;
+     cm_dirOp_t newDirOp;
  
      /* before starting the RPC, mark that we're changing the directory data,
       * so that someone who does a chmod on the dir will wait until our call
***************
*** 2952,2959 ****
--- 3111,3122 ----
          lock_ObtainMutex(&oldDscp->mx);
          cm_dnlcRemove(oldDscp, oldNamep);
          cm_dnlcRemove(oldDscp, newNamep);
+         cm_BeginDirOp(oldDscp, userp, reqp, &oldDirOp);
          code = cm_SyncOp(oldDscp, NULL, userp, reqp, 0,
                            CM_SCACHESYNC_STOREDATA);
+         if (code != 0) {
+             cm_EndDirOp(&oldDirOp);
+         }
          lock_ReleaseMutex(&oldDscp->mx);
      }
      else {
***************
*** 2972,2992 ****
--- 3135,3162 ----
  
          if (oldDscp->fid.vnode < newDscp->fid.vnode) {
              lock_ObtainMutex(&oldDscp->mx);
+             cm_BeginDirOp(oldDscp, userp, reqp, &oldDirOp);
              cm_dnlcRemove(oldDscp, oldNamep);
              code = cm_SyncOp(oldDscp, NULL, userp, reqp, 0,
                                CM_SCACHESYNC_STOREDATA);
+             if (code != 0)
+                 cm_EndDirOp(&oldDirOp);
              lock_ReleaseMutex(&oldDscp->mx);
              if (code == 0) {
                  lock_ObtainMutex(&newDscp->mx);
+                 cm_BeginDirOp(newDscp, userp, reqp, &newDirOp);
                  cm_dnlcRemove(newDscp, newNamep);
                  code = cm_SyncOp(newDscp, NULL, userp, reqp, 0,
                                    CM_SCACHESYNC_STOREDATA);
+                 if (code != 0)
+                     cm_EndDirOp(&newDirOp);
                  lock_ReleaseMutex(&newDscp->mx);
                  if (code) {
                      /* cleanup first one */
                      lock_ObtainMutex(&oldDscp->mx);
                      cm_SyncOpDone(oldDscp, NULL,
                                     CM_SCACHESYNC_STOREDATA);
+                     cm_EndDirOp(&oldDirOp);
                      lock_ReleaseMutex(&oldDscp->mx);
                  }       
              }
***************
*** 2994,3014 ****
--- 3164,3191 ----
          else {
              /* lock the new vnode entry first */
              lock_ObtainMutex(&newDscp->mx);
+             cm_BeginDirOp(newDscp, userp, reqp, &newDirOp);
              cm_dnlcRemove(newDscp, newNamep);
              code = cm_SyncOp(newDscp, NULL, userp, reqp, 0,
                                CM_SCACHESYNC_STOREDATA);
+             if (code != 0)
+                 cm_EndDirOp(&newDirOp);
              lock_ReleaseMutex(&newDscp->mx);
              if (code == 0) {
                  lock_ObtainMutex(&oldDscp->mx);
+                 cm_BeginDirOp(oldDscp, userp, reqp, &oldDirOp);
                  cm_dnlcRemove(oldDscp, oldNamep);
                  code = cm_SyncOp(oldDscp, NULL, userp, reqp, 0,
                                    CM_SCACHESYNC_STOREDATA);
+                 if (code != 0)
+                     cm_EndDirOp(&oldDirOp);
                  lock_ReleaseMutex(&oldDscp->mx);
                  if (code) {
                      /* cleanup first one */
                      lock_ObtainMutex(&newDscp->mx);
                      cm_SyncOpDone(newDscp, NULL,
                                     CM_SCACHESYNC_STOREDATA);
+                     cm_EndDirOp(&newDirOp);
                      lock_ReleaseMutex(&newDscp->mx);
                  }       
              }
***************
*** 3054,3063 ****
--- 3231,3257 ----
      /* update the individual stat cache entries for the directories */
      lock_ObtainMutex(&oldDscp->mx);
      cm_SyncOpDone(oldDscp, NULL, CM_SCACHESYNC_STOREDATA);
+ 
      if (code == 0) {
          cm_MergeStatus(NULL, oldDscp, &updatedOldDirStatus, &volSync,
                          userp, 0);
+ 
+         if (cm_CheckDirOpForSingleChange(&oldDirOp)) {
+ 
+             diropCode = cm_DirLookup(&oldDirOp, oldNamep, &fileFid);
+ 
+             if (diropCode == 0) {
+                 if (oneDir) {
+                     diropCode = cm_DirCreateEntry(&oldDirOp, newNamep, &fileFid);
+                 }
+ 
+                 if (diropCode == 0) {
+                     diropCode = cm_DirDeleteEntry(&oldDirOp, oldNamep);
      }
+             }
+         }
+     }
+     cm_EndDirOp(&oldDirOp);
      lock_ReleaseMutex(&oldDscp->mx);
  
      /* and update it for the new one, too, if necessary */
***************
*** 3067,3073 ****
--- 3261,3275 ----
          if (code == 0) {
              cm_MergeStatus(NULL, newDscp, &updatedNewDirStatus, &volSync,
                              userp, 0);
+ 
+             /* we only make the local change if we successfully made
+                the change in the old directory AND there was only one
+                change in the new directory */
+             if (diropCode == 0 && cm_CheckDirOpForSingleChange(&newDirOp)) {
+                 cm_DirCreateEntry(&newDirOp, newNamep, &fileFid);
+             }
          }
+         cm_EndDirOp(&newDirOp);
          lock_ReleaseMutex(&newDscp->mx);
      }
  
Index: openafs/src/WINNT/afsd/fs.c
diff -c openafs/src/WINNT/afsd/fs.c:1.32.4.11 openafs/src/WINNT/afsd/fs.c:1.32.4.12
*** openafs/src/WINNT/afsd/fs.c:1.32.4.11	Mon Jul  2 20:35:13 2007
--- openafs/src/WINNT/afsd/fs.c	Fri Jul 27 23:04:37 2007
***************
*** 1099,1105 ****
      blob.out = cellname;
  
      code = pioctl(fname, VIOC_FILE_CELL_NAME, &blob, 1);
!     return code ? errno : 0;
  }
  
  /* Check if a username is valid: If it contains only digits (or a
--- 1099,1105 ----
      blob.out = cellname;
  
      code = pioctl(fname, VIOC_FILE_CELL_NAME, &blob, 1);
!     return code;
  }
  
  /* Check if a username is valid: If it contains only digits (or a
***************
*** 1930,1937 ****
  		cellName = localCellName;
  	}
      } else {
! 	if (!cellName)
! 	    GetCell(parent,space);
      }
  
      code = GetCellName(cellName?cellName:space, &info);
--- 1930,1940 ----
  		cellName = localCellName;
  	}
      } else {
! 	if (!cellName) {
! 	    code = GetCell(parent,space);
!             if (code)
!                 return 1;
!         }
      }
  
      code = GetCellName(cellName?cellName:space, &info);
Index: openafs/src/WINNT/afsd/rawops.c
diff -c openafs/src/WINNT/afsd/rawops.c:1.2.4.2 openafs/src/WINNT/afsd/rawops.c:1.2.4.3
*** openafs/src/WINNT/afsd/rawops.c:1.2.4.2	Mon Dec 11 23:01:26 2006
--- openafs/src/WINNT/afsd/rawops.c	Thu Aug  9 01:33:56 2007
***************
*** 155,165 ****
      long written = 0;
      osi_hyper_t fileLength;	/* file's length at start of write */
      osi_hyper_t minLength;	/* don't read past this */
!     long nbytes;		/* # of bytes to transfer this iteration */
      cm_buf_t *bufferp;
      osi_hyper_t thyper;		/* hyper tmp variable */
      osi_hyper_t bufferOffset;
!     long bufIndex;			/* index in buffer where our data is */
      int doWriteBack;
      osi_hyper_t writeBackOffset;	/* offset of region to write back when
      * I/O is done */
--- 155,165 ----
      long written = 0;
      osi_hyper_t fileLength;	/* file's length at start of write */
      osi_hyper_t minLength;	/* don't read past this */
!     afs_uint32 nbytes;		/* # of bytes to transfer this iteration */
      cm_buf_t *bufferp;
      osi_hyper_t thyper;		/* hyper tmp variable */
      osi_hyper_t bufferOffset;
!     afs_uint32 bufIndex;	/* index in buffer where our data is */
      int doWriteBack;
      osi_hyper_t writeBackOffset;	/* offset of region to write back when
      * I/O is done */
***************
*** 333,339 ****
          else
  #endif /* DJGPP */
              memcpy(bufferp->datap + bufIndex, op, nbytes);
!         buf_SetDirty(bufferp);
  
          /* and record the last writer */
          if (bufferp->userp != userp) {
--- 333,339 ----
          else
  #endif /* DJGPP */
              memcpy(bufferp->datap + bufIndex, op, nbytes);
!         buf_SetDirty(bufferp, bufIndex, nbytes);
  
          /* and record the last writer */
          if (bufferp->userp != userp) {
Index: openafs/src/WINNT/afsd/smb.c
diff -c openafs/src/WINNT/afsd/smb.c:1.118.2.37 openafs/src/WINNT/afsd/smb.c:1.118.2.40
*** openafs/src/WINNT/afsd/smb.c:1.118.2.37	Thu Jul  5 15:22:16 2007
--- openafs/src/WINNT/afsd/smb.c	Thu Aug  9 01:33:56 2007
***************
*** 4389,4395 ****
                                                        scp->bulkStatProgress)) {
                      /* Don't bulk stat if risking timeout */
                      int now = GetTickCount();
!                     if (now - req.startTime > RDRtimeout) {
                          scp->bulkStatProgress = thyper;
                          scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING;
                          dsp->flags &= ~SMB_DIRSEARCH_BULKST;
--- 4389,4395 ----
                                                        scp->bulkStatProgress)) {
                      /* Don't bulk stat if risking timeout */
                      int now = GetTickCount();
!                     if (now - req.startTime > RDRtimeout * 1000) {
                          scp->bulkStatProgress = thyper;
                          scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING;
                          dsp->flags &= ~SMB_DIRSEARCH_BULKST;
***************
*** 5182,5187 ****
--- 5182,5188 ----
      char *maskp;		/* pointer to the star pattern */
      int flags;
      int any;
+     cm_dirEntryList_t * matches;
  } smb_unlinkRock_t;
  
  int smb_UnlinkProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp)
***************
*** 5210,5229 ****
          match = smb_V3MatchMask(matchName, rockp->maskp, caseFold | CM_FLAG_CASEFOLD);
      }
      if (match) {
!         osi_Log1(smb_logp, "Unlinking %s",
                   osi_LogSaveString(smb_logp, matchName));
!         code = cm_Unlink(dscp, dep->name, rockp->userp, rockp->reqp);
!         if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
!             smb_NotifyChange(FILE_ACTION_REMOVED,
! 			     FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_CREATION,
!                              dscp, dep->name, NULL, TRUE);
!         if (code == 0) {
              rockp->any = 1;
  
              /* If we made a case sensitive exact match, we might as well quit now. */
              if (!(rockp->flags & SMB_MASKFLAG_CASEFOLD) && !strcmp(matchName, rockp->maskp))
                  code = CM_ERROR_STOPNOW;
!         }
      }
      else code = 0;
  
--- 5211,5228 ----
          match = smb_V3MatchMask(matchName, rockp->maskp, caseFold | CM_FLAG_CASEFOLD);
      }
      if (match) {
!         osi_Log1(smb_logp, "Found match %s",
                   osi_LogSaveString(smb_logp, matchName));
! 
!         cm_DirEntryListAdd(dep->name, &rockp->matches);
! 
              rockp->any = 1;
  
              /* If we made a case sensitive exact match, we might as well quit now. */
              if (!(rockp->flags & SMB_MASKFLAG_CASEFOLD) && !strcmp(matchName, rockp->maskp))
                  code = CM_ERROR_STOPNOW;
!         else
!             code = 0;
      }
      else code = 0;
  
***************
*** 5304,5309 ****
--- 5303,5309 ----
      rock.reqp = &req;
      rock.dscp = dscp;
      rock.vcp = vcp;
+     rock.matches = NULL;
  
      /* Now, if we aren't dealing with a wildcard match, we first try an exact 
       * match.  If that fails, we do a case insensitve match. 
***************
*** 5324,5329 ****
--- 5324,5347 ----
      if (code == CM_ERROR_STOPNOW) 
          code = 0;
  
+     if (code == 0 && rock.matches) {
+         cm_dirEntryList_t * entry;
+ 
+         for (entry = rock.matches; code == 0 && entry; entry = entry->nextp) {
+ 
+             osi_Log1(smb_logp, "Unlinking %s",
+                      osi_LogSaveString(smb_logp, entry->name));
+             code = cm_Unlink(dscp, entry->name, userp, &req);
+ 
+             if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
+                 smb_NotifyChange(FILE_ACTION_REMOVED,
+                                  FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_CREATION,
+                                  dscp, entry->name, NULL, TRUE);
+         }
+     }
+ 
+     cm_DirEntryListFree(&rock.matches);
+ 
      cm_ReleaseUser(userp);
          
      cm_ReleaseSCache(dscp);
***************
*** 5342,5347 ****
--- 5360,5366 ----
      char *maskp;		/* pointer to star pattern of old file name */
      int flags;		    /* tilde, casefold, etc */
      char *newNamep;		/* ptr to the new file's name */
+     char oldName[MAX_PATH];
      int any;
  } smb_renameRock_t;
  
***************
*** 5366,5386 ****
          cm_Gen8Dot3Name(dep, shortName, NULL);
          match = smb_V3MatchMask(shortName, rockp->maskp, caseFold);
      }
      if (match) {
  	rockp->any = 1;
! 
! 	code = cm_Rename(rockp->odscp, dep->name,
!                          rockp->ndscp, rockp->newNamep, rockp->userp,
!                          rockp->reqp);	
!         /* if the call worked, stop doing the search now, since we
!          * really only want to rename one file.
!          */
! 	osi_Log1(smb_logp, "cm_Rename returns %ld", code);
!         if (code == 0) 
              code = CM_ERROR_STOPNOW;
!     }       
!     else 
  	code = 0;
  
      return code;
  }
--- 5385,5399 ----
          cm_Gen8Dot3Name(dep, shortName, NULL);
          match = smb_V3MatchMask(shortName, rockp->maskp, caseFold);
      }
+ 
      if (match) {
  	rockp->any = 1;
!         strncpy(rockp->oldName, dep->name, sizeof(rockp->oldName)/sizeof(char) - 1);
!         rockp->oldName[sizeof(rockp->oldName)/sizeof(char) - 1] = '\0';
              code = CM_ERROR_STOPNOW;
!     } else {
  	code = 0;
+     }
  
      return code;
  }
***************
*** 5485,5490 ****
--- 5498,5504 ----
      rock.maskp = oldLastNamep;
      rock.flags = ((strchr(oldLastNamep, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0);
      rock.newNamep = newLastNamep;
+     rock.oldName[0] = '\0';
      rock.any = 0;
  
      /* Check if the file already exists; if so return error */
***************
*** 5537,5552 ****
      }
      osi_Log1(smb_logp, "smb_RenameProc returns %ld", code);
  
!     if (code == CM_ERROR_STOPNOW)
!         code = 0;
!     else if (code == 0)
          code = CM_ERROR_NOSUCHFILE;
  
      /* Handle Change Notification */
      /*
      * Being lazy, not distinguishing between files and dirs in this
      * filter, since we'd have to do a lookup.
      */
      filter = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME;
      if (oldDscp == newDscp) {
          if (oldDscp->flags & CM_SCACHEFLAG_ANYWATCH)
--- 5551,5574 ----
      }
      osi_Log1(smb_logp, "smb_RenameProc returns %ld", code);
  
!     if (code == CM_ERROR_STOPNOW && rock.oldName[0] != '\0') {
! 	code = cm_Rename(rock.odscp, rock.oldName,
!                          rock.ndscp, rock.newNamep, rock.userp,
!                          rock.reqp);	
!         /* if the call worked, stop doing the search now, since we
!          * really only want to rename one file.
!          */
! 	osi_Log1(smb_logp, "cm_Rename returns %ld", code);
!     } else if (code == 0) {
          code = CM_ERROR_NOSUCHFILE;
+     }
  
      /* Handle Change Notification */
      /*
      * Being lazy, not distinguishing between files and dirs in this
      * filter, since we'd have to do a lookup.
      */
+     if (code == 0) {
      filter = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME;
      if (oldDscp == newDscp) {
          if (oldDscp->flags & CM_SCACHEFLAG_ANYWATCH)
***************
*** 5563,5568 ****
--- 5585,5591 ----
                               filter, newDscp, newLastNamep,
                               NULL, TRUE);
      }
+     }
  
      if (tmpscp != NULL) 
          cm_ReleaseSCache(tmpscp);
***************
*** 5759,5764 ****
--- 5782,5788 ----
      char *maskp;		/* pointer to the star pattern */
      int flags;
      int any;
+     cm_dirEntryList_t * matches;
  } smb_rmdirRock_t;
  
  int smb_RmdirProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp)
***************
*** 5783,5802 ****
          matchName = shortName;
          match = (cm_stricmp(matchName, rockp->maskp) == 0);
      }       
      if (match) {
-         osi_Log1(smb_logp, "Removing directory %s",
-                  osi_LogSaveString(smb_logp, matchName));
-         code = cm_RemoveDir(dscp, dep->name, rockp->userp, rockp->reqp);
-         if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
-             smb_NotifyChange(FILE_ACTION_REMOVED,
-                              FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_CREATION,
-                              dscp, dep->name, NULL, TRUE);
-         if (code == 0)
              rockp->any = 1;
      }
-     else code = 0;
  
!     return code;
  }
  
  long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
--- 5807,5819 ----
          matchName = shortName;
          match = (cm_stricmp(matchName, rockp->maskp) == 0);
      }       
+ 
      if (match) {
              rockp->any = 1;
+         cm_DirEntryListAdd(dep->name, &rockp->matches);
      }
  
!     return 0;
  }
  
  long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
***************
*** 5867,5872 ****
--- 5884,5890 ----
      rock.userp = userp;
      rock.reqp = &req;
      rock.dscp = dscp;
+     rock.matches = NULL;
  
      /* First do a case sensitive match, and if that fails, do a case insensitive match */
      code = cm_ApplyDir(dscp, smb_RmdirProc, &rock, &thyper, userp, &req, NULL);
***************
*** 5877,5882 ****
--- 5895,5918 ----
          code = cm_ApplyDir(dscp, smb_RmdirProc, &rock, &thyper, userp, &req, NULL);
      }
  
+     if (code == 0 && rock.matches) {
+         cm_dirEntryList_t * entry;
+ 
+         for (entry = rock.matches; code == 0 && entry; entry = entry->nextp) {
+             osi_Log1(smb_logp, "Removing directory %s",
+                      osi_LogSaveString(smb_logp, entry->name));
+ 
+             code = cm_RemoveDir(dscp, entry->name, userp, &req);
+ 
+             if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
+                 smb_NotifyChange(FILE_ACTION_REMOVED,
+                                  FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_CREATION,
+                                  dscp, entry->name, NULL, TRUE);
+         }
+     }
+ 
+     cm_DirEntryListFree(&rock.matches);
+ 
      cm_ReleaseUser(userp);
          
      cm_ReleaseSCache(dscp);
***************
*** 6381,6391 ****
      cm_scache_t *scp;
      osi_hyper_t fileLength;	/* file's length at start of write */
      osi_hyper_t minLength;	/* don't read past this */
!     long nbytes;		/* # of bytes to transfer this iteration */
      cm_buf_t *bufferp;
      osi_hyper_t thyper;		/* hyper tmp variable */
      osi_hyper_t bufferOffset;
!     long bufIndex;		/* index in buffer where our data is */
      int doWriteBack;
      osi_hyper_t writeBackOffset;/* offset of region to write back when
                                   * I/O is done */
--- 6417,6427 ----
      cm_scache_t *scp;
      osi_hyper_t fileLength;	/* file's length at start of write */
      osi_hyper_t minLength;	/* don't read past this */
!     afs_uint32 nbytes;		/* # of bytes to transfer this iteration */
      cm_buf_t *bufferp;
      osi_hyper_t thyper;		/* hyper tmp variable */
      osi_hyper_t bufferOffset;
!     afs_uint32 bufIndex;		/* index in buffer where our data is */
      int doWriteBack;
      osi_hyper_t writeBackOffset;/* offset of region to write back when
                                   * I/O is done */
***************
*** 6572,6578 ****
          else
  #endif /* DJGPP */
              memcpy(bufferp->datap + bufIndex, op, nbytes);
!         buf_SetDirty(bufferp);
  
          /* and record the last writer */
          if (bufferp->userp != userp) {
--- 6608,6614 ----
          else
  #endif /* DJGPP */
              memcpy(bufferp->datap + bufIndex, op, nbytes);
!         buf_SetDirty(bufferp, bufIndex, nbytes);
  
          /* and record the last writer */
          if (bufferp->userp != userp) {
Index: openafs/src/WINNT/afsd/smb3.c
diff -c openafs/src/WINNT/afsd/smb3.c:1.95.2.38 openafs/src/WINNT/afsd/smb3.c:1.95.2.40
*** openafs/src/WINNT/afsd/smb3.c:1.95.2.38	Sat Jun 30 00:38:52 2007
--- openafs/src/WINNT/afsd/smb3.c	Fri Jul 27 22:51:16 2007
***************
*** 4337,4343 ****
          
      userp = smb_GetTran2User(vcp, p);
      if (!userp) {
!     	osi_Log1(smb_logp, "T2 search dir unable to resolve user [%d]", p->uid);
      	smb_FreeTran2Packet(outp);
      	return CM_ERROR_BADSMB;
      }
--- 4337,4343 ----
          
      userp = smb_GetTran2User(vcp, p);
      if (!userp) {
!     	osi_Log1(smb_logp, "T2SDSingle search dir unable to resolve user [%d]", p->uid);
      	smb_FreeTran2Packet(outp);
      	return CM_ERROR_BADSMB;
      }
***************
*** 4378,4390 ****
  	return 0;
      }
  #endif /* DFS_SUPPORT */
!     osi_Log1(smb_logp,"smb_ReceiveTran2SearchDir scp 0x%p", scp);
!     lock_ObtainMutex(&scp->mx);
!     if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 &&
! 	 LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) {
! 	scp->flags |= CM_SCACHEFLAG_BULKSTATTING;
!     }
!     lock_ReleaseMutex(&scp->mx);
  
      /* now do a single case sensitive lookup for the file in question */
      code = cm_Lookup(scp, maskp, CM_FLAG_NOMOUNTCHASE, userp, &req, &targetscp);
--- 4378,4384 ----
  	return 0;
      }
  #endif /* DFS_SUPPORT */
!     osi_Log1(smb_logp,"T2SDSingle scp 0x%p", scp);
  
      /* now do a single case sensitive lookup for the file in question */
      code = cm_Lookup(scp, maskp, CM_FLAG_NOMOUNTCHASE, userp, &req, &targetscp);
***************
*** 4984,4990 ****
                      LargeIntegerGreaterThanOrEqualTo(thyper, scp->bulkStatProgress)) {
                      /* Don't bulk stat if risking timeout */
                      DWORD now = GetTickCount();
!                     if (now - req.startTime > RDRtimeout) {
                          scp->bulkStatProgress = thyper;
                          scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING;
                          dsp->flags &= ~SMB_DIRSEARCH_BULKST;
--- 4978,4984 ----
                      LargeIntegerGreaterThanOrEqualTo(thyper, scp->bulkStatProgress)) {
                      /* Don't bulk stat if risking timeout */
                      DWORD now = GetTickCount();
!                     if (now - req.startTime > RDRtimeout * 1000) {
                          scp->bulkStatProgress = thyper;
                          scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING;
                          dsp->flags &= ~SMB_DIRSEARCH_BULKST;
Index: openafs/src/WINNT/aklog/aklog.c
diff -c openafs/src/WINNT/aklog/aklog.c:1.14.4.4 openafs/src/WINNT/aklog/aklog.c:1.14.4.5
*** openafs/src/WINNT/aklog/aklog.c:1.14.4.4	Tue May 15 23:34:58 2007
--- openafs/src/WINNT/aklog/aklog.c	Thu Aug  9 18:54:07 2007
***************
*** 220,235 ****
      }       
  
      /*
-      * This is a crock, but it is Transarc's crock, so
-      * we have to play along in order to get the
-      * functionality.  The way the afs id is stored is
-      * as a string in the username field of the token.
-      * Contrary to what you may think by looking at
-      * the code for tokens, this hack (AFS ID %d) will
-      * not work if you change %d to something else.
-      */
- 
-     /*
       * This code is taken from cklog -- it lets people
       * automatically register with the ptserver in foreign cells
       */
--- 220,225 ----
***************
*** 266,272 ****
              }
  
              if ((*status = ktc_SetToken(aserver, atoken, aclient, 0))) {
!                 printf("%s: unable to obtain tokens for cell %s "
                          "(status: %d).\n", progname, cell_to_use, status);
                  *status = AKLOG_TOKEN;
                  return ;
--- 256,262 ----
              }
  
              if ((*status = ktc_SetToken(aserver, atoken, aclient, 0))) {
!                 printf("%s: unable to set tokens for cell %s "
                          "(status: %d).\n", progname, cell_to_use, status);
                  *status = AKLOG_TOKEN;
                  return ;
Index: openafs/src/WINNT/client_config/lang/en_US/afs_config.rc
diff -c openafs/src/WINNT/client_config/lang/en_US/afs_config.rc:1.7.6.3 openafs/src/WINNT/client_config/lang/en_US/afs_config.rc:1.7.6.4
*** openafs/src/WINNT/client_config/lang/en_US/afs_config.rc:1.7.6.3	Fri Feb  2 23:53:04 2007
--- openafs/src/WINNT/client_config/lang/en_US/afs_config.rc	Fri Jul 27 11:41:53 2007
***************
*** 700,706 ****
      IDS_SERVICE_FAIL_START  "The AFS Client Service could not be started successfully. You might not have authorization to perform this operation.\n\nError 0x%1."
      IDS_SERVICE_FAIL_STOP   "The AFS Client Service could not be stopped successfully. You might not have authorization to perform this operation.\n\nError 0x%1."
      IDS_WARN_STOPPED        "The disabled controls cannot be changed because the AFS Client service is not running."
!     IDS_WARN_ADMIN          "The disabled controls cannot be changed because you are not logged in to Windows as an administrator."
      IDS_CELL_UNKNOWN        "(unknown)"
      IDS_GATEWAY_UNKNOWN     "(unknown)"
  END
--- 700,706 ----
      IDS_SERVICE_FAIL_START  "The AFS Client Service could not be started successfully. You might not have authorization to perform this operation.\n\nError 0x%1."
      IDS_SERVICE_FAIL_STOP   "The AFS Client Service could not be stopped successfully. You might not have authorization to perform this operation.\n\nError 0x%1."
      IDS_WARN_STOPPED        "The disabled controls cannot be changed because the AFS Client service is not running."
!     IDS_WARN_ADMIN          "The disabled controls cannot be changed because you are not a member of the AFS Administrators Group."
      IDS_CELL_UNKNOWN        "(unknown)"
      IDS_GATEWAY_UNKNOWN     "(unknown)"
  END
Index: openafs/src/WINNT/doc/install/Documentation/en_US/html/index.htm
diff -c openafs/src/WINNT/doc/install/Documentation/en_US/html/index.htm:1.5.4.16 openafs/src/WINNT/doc/install/Documentation/en_US/html/index.htm:1.5.4.17
*** openafs/src/WINNT/doc/install/Documentation/en_US/html/index.htm:1.5.4.16	Fri Jun 22 10:40:12 2007
--- openafs/src/WINNT/doc/install/Documentation/en_US/html/index.htm	Thu Aug  9 11:46:17 2007
***************
*** 57,63 ****
  
  <h1>OpenAFS for Windows</h1>
  
! <h2>Version 1.5.21</h2>
  
  <p class=MsoNormal>&nbsp; </p>
  
--- 57,63 ----
  
  <h1>OpenAFS for Windows</h1>
  
! <h2>Version 1.5.22</h2>
  
  <p class=MsoNormal>&nbsp; </p>
  
***************
*** 80,86 ****
  <span
  style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  </span></span><a
! href="ReleaseNotes/relnotes-frames.htm">OpenAFS for Windows 1.5.21
  Release Notes</a></p>
  
  <p style='margin-left:36.0pt;text-indent:-18.0pt;'>
--- 80,86 ----
  <span
  style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  </span></span><a
! href="ReleaseNotes/relnotes-frames.htm">OpenAFS for Windows 1.5.22
  Release Notes</a></p>
  
  <p style='margin-left:36.0pt;text-indent:-18.0pt;'>
Index: openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/logo.htm
diff -c openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/logo.htm:1.1.6.16 openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/logo.htm:1.1.6.17
*** openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/logo.htm:1.1.6.16	Fri Jun 22 10:18:39 2007
--- openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/logo.htm	Thu Aug  9 11:46:21 2007
***************
*** 18,24 ****
  .shape {behavior:url(#default#VML);}
  </style>
  <![endif]-->
! <title>OpenAFS for Windows 1.5.21 Release Notes</title>
  <!--[if gte mso 9]><xml>
   <o:DocumentProperties>
    <o:Revision>1</o:Revision>
--- 18,24 ----
  .shape {behavior:url(#default#VML);}
  </style>
  <![endif]-->
! <title>OpenAFS for Windows 1.5.22 Release Notes</title>
  <!--[if gte mso 9]><xml>
   <o:DocumentProperties>
    <o:Revision>1</o:Revision>
Index: openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/relnotes-frames.htm
diff -c openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/relnotes-frames.htm:1.1.4.18 openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/relnotes-frames.htm:1.1.4.19
*** openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/relnotes-frames.htm:1.1.4.18	Fri Jun 22 10:18:39 2007
--- openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/relnotes-frames.htm	Thu Aug  9 11:46:21 2007
***************
*** 8,14 ****
  <meta name=Generator content="Microsoft Word 11">
  <meta name=Originator content="Microsoft Word 11">
  <link rel=File-List href="relnotes-frames_files/filelist.xml">
! <title>OpenAFS for Windows 1.5.21 Release Notes</title>
  <!--[if gte mso 9]><xml>
   <w:WordDocument>
    <w:Zoom>0</w:Zoom>
--- 8,14 ----
  <meta name=Generator content="Microsoft Word 11">
  <meta name=Originator content="Microsoft Word 11">
  <link rel=File-List href="relnotes-frames_files/filelist.xml">
! <title>OpenAFS for Windows 1.5.22 Release Notes</title>
  <!--[if gte mso 9]><xml>
   <w:WordDocument>
    <w:Zoom>0</w:Zoom>
Index: openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/relnotes.htm
diff -c openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/relnotes.htm:1.6.4.20 openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/relnotes.htm:1.6.4.21
*** openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/relnotes.htm:1.6.4.20	Fri Jun 22 10:18:39 2007
--- openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/relnotes.htm	Thu Aug  9 11:46:21 2007
***************
*** 19,25 ****
  .shape {behavior:url(#default#VML);}
  </style>
  <![endif]-->
! <title>OpenAFS for Windows 1.5.21 Release Notes</title>
  <o:SmartTagType namespaceuri="urn:schemas-microsoft-com:office:smarttags"
   name="PostalCode"/>
  <o:SmartTagType namespaceuri="urn:schemas-microsoft-com:office:smarttags"
--- 19,25 ----
  .shape {behavior:url(#default#VML);}
  </style>
  <![endif]-->
! <title>OpenAFS for Windows 1.5.22 Release Notes</title>
  <o:SmartTagType namespaceuri="urn:schemas-microsoft-com:office:smarttags"
   name="PostalCode"/>
  <o:SmartTagType namespaceuri="urn:schemas-microsoft-com:office:smarttags"
***************
*** 586,592 ****
  
  <div class=Section1>
  
! <p class=MsoTitle>OpenAFS for Windows 1.5.21<br>
  Release Notes</p>
  
  <p class=MsoBodyText>The Andrew File System (AFS) is a location-independent
--- 586,592 ----
  
  <div class=Section1>
  
! <p class=MsoTitle>OpenAFS for Windows 1.5.22<br>
  Release Notes</p>
  
  <p class=MsoBodyText>The Andrew File System (AFS) is a location-independent
***************
*** 646,652 ****
  Operational Notes<span style='color:windowtext;display:none;mso-hide:all;
  text-decoration:none;text-underline:none'>. 2</span></a></span></p>
  
! <p class=MsoToc1><span class=MsoHyperlink><a href="#_Toc115417112">4. How to
  Debug Problems with OpenAFS for Windows:<span style='color:windowtext;
  display:none;mso-hide:all;text-decoration:none;text-underline:none'> 11</span></a></span></p>
  
--- 646,652 ----
  Operational Notes<span style='color:windowtext;display:none;mso-hide:all;
  text-decoration:none;text-underline:none'>. 2</span></a></span></p>
  
! <p class=MsoToc1><span class=MsoHyperlink><a href="#_Toc170268869">4. How to
  Debug Problems with OpenAFS for Windows:<span style='color:windowtext;
  display:none;mso-hide:all;text-decoration:none;text-underline:none'> 11</span></a></span></p>
  
***************
*** 1160,1166 ****
  
  <p class=MsoNormal>Integrated Login supports the ability to obtain tokens for
  multiple cells.&nbsp; For further information on how to configure this feature
! read about the <a href="../relnotes.htm#_Value:_TheseCells"><span class=SpellE>TheseCells</span></a>
  value.</p>
  
  <h2><a name="_Toc170268828"></a><a name="_Toc152605047"></a><a
--- 1160,1166 ----
  
  <p class=MsoNormal>Integrated Login supports the ability to obtain tokens for
  multiple cells.&nbsp; For further information on how to configure this feature
! read about the <a href="#_Value:_TheseCells"><span class=SpellE>TheseCells</span></a>
  value.</p>
  
  <h2><a name="_Toc170268828"></a><a name="_Toc152605047"></a><a
***************
*** 1398,1403 ****
--- 1398,1406 ----
  It has not been thoroughly tested.&nbsp; Any data which would cause pain if
  lost should not be stored in an OpenAFS Server on Windows.</p>
  
+ <p class=MsoNormal>Known issues include lack of support for power management
+ and dynamic network configuration.</p>
+ 
  <h3><a name="_Toc170268833">3.10.1. OpenAFS Server Installation</a></h3>
  
  <p class=MsoNormal>When the OpenAFS Server is installed, the <span
***************
*** 1490,1496 ****
  name="_Toc115416118"></a><a name="_Toc139993102"></a><a name="_Toc126872183"></a><a
  name="_Toc115417054"></a><span style='mso-bookmark:_Toc170268836'><span
  style='mso-bookmark:_Toc152605053'><span style='mso-bookmark:_Toc115416118'>3.12.
! </span>Large Files (64-bit) Supported</span></span></h2>
  
  <p class=MsoNormal>As of release 1.5.3, OpenAFS for Windows supports files
  larger than 2GB.&nbsp; The maximum file size is now 16777216 terabytes when the
--- 1493,1499 ----
  name="_Toc115416118"></a><a name="_Toc139993102"></a><a name="_Toc126872183"></a><a
  name="_Toc115417054"></a><span style='mso-bookmark:_Toc170268836'><span
  style='mso-bookmark:_Toc152605053'><span style='mso-bookmark:_Toc115416118'>3.12.
! </span>Large File (64-bit) Support</span></span></h2>
  
  <p class=MsoNormal>As of release 1.5.3, OpenAFS for Windows supports files
  larger than 2GB.&nbsp; The maximum file size is now 16777216 terabytes when the
***************
*** 2100,2116 ****
  name="_Toc115416144"></a><a name="_Toc139993128"></a><a name="_Toc126872209"></a><a
  name="_Toc115417080"></a><span style='mso-bookmark:_Toc170268862'><span
  style='mso-bookmark:_Toc152605079'><span style='mso-bookmark:_Toc115416144'>3.38.
! AFS Client Universally Unique Identifiers</span></span></span></h2>
  
  <p class=MsoNormal>The OpenAFS Client implements Universally Unique Identifiers
! (<span class=SpellE>UUIDs</span>).&nbsp; They are used to provide the server
  with a method of identifying the client that is independent of IP
! address.&nbsp; The UUID is generated when the <span class=SpellE>AFSCache</span>
! file is created and is maintained as long as the contents of the <span
! class=SpellE>AFSCache</span> file are kept intact.&nbsp; The UUID is stored in
! the <span class=SpellE>AFSCache</span> file.&nbsp;&nbsp; When cloning machines
! that have Windows AFS client installed, the <span class=SpellE>AFSCache</span>
! files should be deleted as part of the cloning process.</p>
  
  <h2><a name="_Toc170268863"></a><a name="_Toc152605080"></a><a
  name="_Toc139993129"><span style='mso-bookmark:_Toc152605080'><span
--- 2103,2133 ----
  name="_Toc115416144"></a><a name="_Toc139993128"></a><a name="_Toc126872209"></a><a
  name="_Toc115417080"></a><span style='mso-bookmark:_Toc170268862'><span
  style='mso-bookmark:_Toc152605079'><span style='mso-bookmark:_Toc115416144'>3.38.
! AFS Client Universally Unique Identifiers (UUIDs) vs. System Cloning</span></span></span></h2>
  
  <p class=MsoNormal>The OpenAFS Client implements Universally Unique Identifiers
! (<span class=SpellE>UUIDs</span>).&nbsp; They are used to provide the AFS file server
  with a method of identifying the client that is independent of IP
! address.&nbsp; This permits the AFS file server to track mobile clients or those 
! behind Network Address Translators when they move from address to address or port
! to port.  Tracking the client improves client performance by permitting callback 
! state to be maintained across location changes.  The UUID is generated when the 
! <span class=SpellE>AFSCache</span> file is created and is maintained as long as
! the contents of the <span class=SpellE>AFSCache</span> file are valid.&nbsp; 
! The UUID is stored in the <span class=SpellE>AFSCache</span> file.&nbsp;</p> 
! <p class=MsoNormal>
! When cloning machines that have Windows AFS client installed it is necessary
! to generate a new UUID for each client.  This will be done automatically if 
! the Windows Machine SID is re-generated using Microsoft SysPrep.  If the SID is
! not being re-generated either the <span class=SpellE>AFSCache</span> file should 
! be deleted or the command <i>fs uuid -generate</i> must be executed after the 
! the clone is created.  <b>Multiple AFS clients reporting the same UUID will not
! only result in horrible AFS client performance and cache inconsistencies, but 
! they will also put a tremendous strain on the AFS file servers.</b></p>
! <p class=MsoNormal>For lab environments that wish to erase all cached data
! on each restart, the <a href="#_Toc170268938">NonPersistentCaching</a> option 
! will disable the use of the persistent cache file.  As a side effect, a new
! UUID will be generated for the AFS client service on each restart.</p>
  
  <h2><a name="_Toc170268863"></a><a name="_Toc152605080"></a><a
  name="_Toc139993129"><span style='mso-bookmark:_Toc152605080'><span
***************
*** 2132,2138 ****
  with the explorer shell does not use asynchronous i/o. </p>
  
  <p class=MsoBodyText>The CIFS session timeout defaults to 45 seconds and can be
! increased by modifying the <a href="../relnotes.htm#_Value:_ConnDeadTimeout">registry</a>.</p>
  
  <h2><a name="_Toc170268864"></a><a name="_Toc152605081"></a><a
  name="_Toc139993130"><span style='mso-bookmark:_Toc152605081'><span
--- 2149,2155 ----
  with the explorer shell does not use asynchronous i/o. </p>
  
  <p class=MsoBodyText>The CIFS session timeout defaults to 45 seconds and can be
! increased by modifying the <a href="#_Value:_ConnDeadTimeout">registry</a>.</p>
  
  <h2><a name="_Toc170268864"></a><a name="_Toc152605081"></a><a
  name="_Toc139993130"><span style='mso-bookmark:_Toc152605081'><span
***************
*** 2438,2444 ****
  options in both tools to make it easier to synchronize the application requests
  and the resulting OpenAFS Client Service operations.&nbsp;&nbsp; The captured
  data can be stored to files for inclusion in <a
! href="../relnotes.htm#_5._Reporting_Bugs:">bug reports</a>.</p>
  
  <h2><a name="_Toc170268874">4.5. Microsoft </a><span class=SpellE><span
  style='mso-bookmark:_Toc170268874'>MiniDumps</span></span><span
--- 2455,2461 ----
  options in both tools to make it easier to synchronize the application requests
  and the resulting OpenAFS Client Service operations.&nbsp;&nbsp; The captured
  data can be stored to files for inclusion in <a
! href="#_5._Reporting_Bugs:">bug reports</a>.</p>
  
  <h2><a name="_Toc170268874">4.5. Microsoft </a><span class=SpellE><span
  style='mso-bookmark:_Toc170268874'>MiniDumps</span></span><span
***************
*** 4361,4371 ****
    style='mso-bookmark:_Toc170268930'><span style='mso-bookmark:_Toc152605145'><span
    style='mso-bookmark:_Toc115416203'>Value: <span class=SpellE>ChunkSize</span></span></span></span></h5>
    <p class=MsoBodyText>Type: DWORD<br>
!   Default: 17 (CM_CONFIGDEFAULT_CHUNKSIZE)<br>
    Variable: <span class=SpellE>cm_logChunkSize</span> (<span class=SpellE>cm_chunkSize</span>
    = 1 &lt;&lt; <span class=SpellE>cm_logChunkSize</span>)</p>
    <p class=MsoBodyText>Size of chunk for reading and writing. Actual chunk size
!   is 2^cm_logChunkSize.</p>
    </td>
   </tr>
   <tr style='mso-yfti-irow:3;height:92.0pt'>
--- 4378,4388 ----
    style='mso-bookmark:_Toc170268930'><span style='mso-bookmark:_Toc152605145'><span
    style='mso-bookmark:_Toc115416203'>Value: <span class=SpellE>ChunkSize</span></span></span></span></h5>
    <p class=MsoBodyText>Type: DWORD<br>
!   Default: 20 (CM_CONFIGDEFAULT_CHUNKSIZE)<br>
    Variable: <span class=SpellE>cm_logChunkSize</span> (<span class=SpellE>cm_chunkSize</span>
    = 1 &lt;&lt; <span class=SpellE>cm_logChunkSize</span>)</p>
    <p class=MsoBodyText>Size of chunk for reading and writing. Actual chunk size
!   is 2^cm_logChunkSize.  The default chunk size is therefore 1 MB.</p>
    </td>
   </tr>
   <tr style='mso-yfti-irow:3;height:92.0pt'>
***************
*** 4491,4500 ****
    Variable: <span class=SpellE>buf_CacheType</span></p>
    <p class=MsoBodyText>When this registry value is set to a non-zero value, the
    <span class=SpellE>CachePath</span> value is ignored and the cache data is
!   stored in the windows paging file.&nbsp; This prevents the use of persistent
!   caching (when available) as well as the ability to alter the size of the
!   cache at runtime using the &quot;<span class=SpellE>fs</span> <span
!   class=SpellE>setcachesize</span>&quot; command.</p>
    </td>
   </tr>
   <tr style='mso-yfti-irow:11;height:125.5pt'>
--- 4508,4516 ----
    Variable: <span class=SpellE>buf_CacheType</span></p>
    <p class=MsoBodyText>When this registry value is set to a non-zero value, the
    <span class=SpellE>CachePath</span> value is ignored and the cache data is
!   stored in the windows paging file.&nbsp; This disables the use of persistent
!   caching and the ability to maintain a single UUID for the AFS client service 
!   across restarts.</p>
    </td>
   </tr>
   <tr style='mso-yfti-irow:11;height:125.5pt'>
Index: openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/toc.htm
diff -c openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/toc.htm:1.2.6.15 openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/toc.htm:1.2.6.16
*** openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/toc.htm:1.2.6.15	Fri Jun 22 10:18:40 2007
--- openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/toc.htm	Thu Aug  9 11:46:24 2007
***************
*** 10,16 ****
  <meta name=Originator content="Microsoft Word 11">
  <base target=body>
  <link rel=File-List href="toc_files/filelist.xml">
! <title>OpenAFS for Windows 1.5.21 Table of Contents</title>
  <!--[if gte mso 9]><xml>
   <o:DocumentProperties>
    <o:Author>Jeffrey Altman</o:Author>
--- 10,16 ----
  <meta name=Originator content="Microsoft Word 11">
  <base target=body>
  <link rel=File-List href="toc_files/filelist.xml">
! <title>OpenAFS for Windows 1.5.22 Table of Contents</title>
  <!--[if gte mso 9]><xml>
   <o:DocumentProperties>
    <o:Author>Jeffrey Altman</o:Author>
***************
*** 373,379 ****
  
  <p class=MsoToc2 style='tab-stops:right dotted 431.5pt'><span
  class=MsoHyperlink><span style='mso-no-proof:yes'><a
! href="relnotes.htm#_Toc170268836">3.12. Large Files (64-bit) Supported</a></span></span><span
  style='mso-fareast-font-family:"Times New Roman";mso-no-proof:yes'><o:p></o:p></span></p>
  
  <p class=MsoToc2 style='tab-stops:right dotted 431.5pt'><span
--- 373,379 ----
  
  <p class=MsoToc2 style='tab-stops:right dotted 431.5pt'><span
  class=MsoHyperlink><span style='mso-no-proof:yes'><a
! href="relnotes.htm#_Toc170268836">3.12. Large File (64-bit) Support</a></span></span><span
  style='mso-fareast-font-family:"Times New Roman";mso-no-proof:yes'><o:p></o:p></span></p>
  
  <p class=MsoToc2 style='tab-stops:right dotted 431.5pt'><span
***************
*** 512,519 ****
  
  <p class=MsoToc2 style='tab-stops:right dotted 431.5pt'><span
  class=MsoHyperlink><span style='mso-no-proof:yes'><a
! href="relnotes.htm#_Toc170268862">3.38. AFS Client Universally Unique
! Identifiers</a></span></span><span style='mso-fareast-font-family:"Times New Roman";
  mso-no-proof:yes'><o:p></o:p></span></p>
  
  <p class=MsoToc2 style='tab-stops:right dotted 431.5pt'><span
--- 512,518 ----
  
  <p class=MsoToc2 style='tab-stops:right dotted 431.5pt'><span
  class=MsoHyperlink><span style='mso-no-proof:yes'><a
! href="relnotes.htm#_Toc170268862">3.38. AFS Client Universally Unique Identifiers (UUIDs) vs. System Cloning</a></span></span><span style='mso-fareast-font-family:"Times New Roman";
  mso-no-proof:yes'><o:p></o:p></span></p>
  
  <p class=MsoToc2 style='tab-stops:right dotted 431.5pt'><span
Index: openafs/src/afs/afs_call.c
diff -c openafs/src/afs/afs_call.c:1.86.4.11 openafs/src/afs/afs_call.c:1.86.4.12
*** openafs/src/afs/afs_call.c:1.86.4.11	Mon Jun 18 14:18:48 2007
--- openafs/src/afs/afs_call.c	Thu Jul 12 14:12:54 2007
***************
*** 11,17 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_call.c,v 1.86.4.11 2007/06/18 18:18:48 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 11,17 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_call.c,v 1.86.4.12 2007/07/12 18:12:54 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 457,469 ****
  #endif /* AFS_SGI61_ENV */
  
      AFS_STATCNT(afs_syscall_call);
!     if (!afs_suser(
  #ifdef	AFS_SUN5_ENV
! 		   CRED()
  #else
! 		   NULL
  #endif
! 		   ) && (parm != AFSOP_GETMTU) && (parm != AFSOP_GETMASK)) {
  	/* only root can run this code */
  #if defined(AFS_OSF_ENV) || defined(AFS_SUN5_ENV) || defined(KERNEL_HAVE_UERROR)
  #if defined(KERNEL_HAVE_UERROR)
--- 457,469 ----
  #endif /* AFS_SGI61_ENV */
  
      AFS_STATCNT(afs_syscall_call);
!     if (
  #ifdef	AFS_SUN5_ENV
! 	!afs_suser(CRED())
  #else
! 	!afs_suser(NULL)
  #endif
! 		    && (parm != AFSOP_GETMTU) && (parm != AFSOP_GETMASK)) {
  	/* only root can run this code */
  #if defined(AFS_OSF_ENV) || defined(AFS_SUN5_ENV) || defined(KERNEL_HAVE_UERROR)
  #if defined(KERNEL_HAVE_UERROR)
Index: openafs/src/afs/afs_util.c
diff -c openafs/src/afs/afs_util.c:1.28.2.5 openafs/src/afs/afs_util.c:1.28.2.6
*** openafs/src/afs/afs_util.c:1.28.2.5	Thu Feb 22 19:44:08 2007
--- openafs/src/afs/afs_util.c	Thu Jul 26 13:05:40 2007
***************
*** 16,22 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_util.c,v 1.28.2.5 2007/02/23 00:44:08 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
--- 16,22 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_util.c,v 1.28.2.6 2007/07/26 17:05:40 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 649,655 ****
  
  afs_int32 afs_calc_inum (afs_int32 volume, afs_int32 vnode)
  { 
!     afs_int32 ino;
      char digest[16];
      struct afs_md5 ct;
      
--- 649,655 ----
  
  afs_int32 afs_calc_inum (afs_int32 volume, afs_int32 vnode)
  { 
!     afs_int32 ino, vno = vnode;
      char digest[16];
      struct afs_md5 ct;
      
***************
*** 659,665 ****
  	AFS_MD5_Update(&ct, &vnode, 4);
  	AFS_MD5_Final(digest, &ct);
  	memcpy(&ino, digest, sizeof(ino_t));
! 	ino ^= (ino ^ vnode) & 1;
      } else {
  	ino = (volume << 16) + vnode;
      }
--- 659,665 ----
  	AFS_MD5_Update(&ct, &vnode, 4);
  	AFS_MD5_Final(digest, &ct);
  	memcpy(&ino, digest, sizeof(ino_t));
! 	ino ^= (ino ^ vno) & 1;
      } else {
  	ino = (volume << 16) + vnode;
      }
Index: openafs/src/afs/DARWIN/osi_vnodeops.c
diff -c openafs/src/afs/DARWIN/osi_vnodeops.c:1.41.2.2 openafs/src/afs/DARWIN/osi_vnodeops.c:1.41.2.3
*** openafs/src/afs/DARWIN/osi_vnodeops.c:1.41.2.2	Tue Mar 20 15:31:06 2007
--- openafs/src/afs/DARWIN/osi_vnodeops.c	Sat Jul 28 10:33:26 2007
***************
*** 5,11 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/DARWIN/osi_vnodeops.c,v 1.41.2.2 2007/03/20 19:31:06 shadow Exp $");
  
  #include <afs/sysincludes.h>	/* Standard vendor system headers */
  #include <afsincludes.h>	/* Afs-based standard headers */
--- 5,11 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/DARWIN/osi_vnodeops.c,v 1.41.2.3 2007/07/28 14:33:26 shadow Exp $");
  
  #include <afs/sysincludes.h>	/* Standard vendor system headers */
  #include <afsincludes.h>	/* Afs-based standard headers */
***************
*** 2096,2106 ****
         par.vnfs_markroot = 1;
     error = vnode_create(VNCREATE_FLAVOR, VCREATESIZE, &par, &nvp);
     if (!error) {
!      vnode_addfsref(nvp);
!      avc->v = nvp;
!      avc->states &=~ CDeadVnode;
!      vnode_clearfsnode(ovp);
!      vnode_removefsref(ovp);
     }
     AFS_GLOCK();
     ReleaseWriteLock(&avc->lock);
--- 2096,2108 ----
         par.vnfs_markroot = 1;
     error = vnode_create(VNCREATE_FLAVOR, VCREATESIZE, &par, &nvp);
     if (!error) {
!        vnode_addfsref(nvp);
!        avc->v = nvp;
!        avc->states &=~ CDeadVnode;
!        if (!(avc->states & CVInit)) {
! 	   vnode_clearfsnode(ovp);
! 	   vnode_removefsref(ovp);
!        }
     }
     AFS_GLOCK();
     ReleaseWriteLock(&avc->lock);
Index: openafs/src/afs/LINUX/osi_probe.c
diff -c openafs/src/afs/LINUX/osi_probe.c:1.11.2.11 openafs/src/afs/LINUX/osi_probe.c:1.11.2.12
*** openafs/src/afs/LINUX/osi_probe.c:1.11.2.11	Wed Jun 27 17:23:07 2007
--- openafs/src/afs/LINUX/osi_probe.c	Tue Jul 17 08:16:45 2007
***************
*** 59,64 ****
--- 59,65 ----
  #include "afsincludes.h"
  #endif
  #include <linux/version.h>
+ #include <linux/sched.h>
  #ifdef CONFIG_H_EXISTS
  #include <linux/config.h>
  #endif
***************
*** 153,158 ****
--- 154,160 ----
   * 0x0010 - detail - check_harder
   * 0x0020 - detail - check_harder/zapped
   * 0x0040 - automatically ignore setgroups and afs_syscall
+  * 0x0080 - detail - check_table_readable
   */
  static int probe_debug = 0x41;
  #ifdef module_param
***************
*** 298,303 ****
--- 300,309 ----
      int debug_ignore_NR[4];         /* syscalls to ignore for debugging */
  } probectl;
  
+ #if defined(AFS_I386_LINUX26_ENV) || defined(AFS_AMD64_LINUX26_ENV)
+ static int check_access(unsigned long, int);
+ static int check_table_readable(probectl *, PROBETYPE *);
+ #endif
  
  
  /********** Probing Configuration: sys_call_table **********/
***************
*** 947,952 ****
--- 953,963 ----
      PROBETYPE *x;
      int i, j;
  
+ #if defined(AFS_I386_LINUX26_ENV) || defined(AFS_AMD64_LINUX26_ENV)
+     i = check_table_readable(P, ptr);
+     if (i >= 0) return i;
+ #endif
+ 
      for (x = ptr, i = 0; i < _SS(NR_syscalls); i++, x++) {
  #ifdef OSI_PROBE_DEBUG
  	if (probe_debug & 0x0040) {
***************
*** 1069,1074 ****
--- 1080,1090 ----
      unsigned long ip1;
      int i, s;
  
+ #if defined(AFS_I386_LINUX26_ENV) || defined(AFS_AMD64_LINUX26_ENV)
+     i = check_table_readable(P, p);
+     if (i >= 0) return 0;
+ #endif
+ 
      /* Check zapped syscalls */
      for (i = 1; i < P->n_zapped_syscalls; i++) {
  	if (p[_SS(P->zapped_syscalls[i])] != p[_SS(P->zapped_syscalls[0])]) {
***************
*** 1356,1362 ****
  }
  
  #if defined(AFS_I386_LINUX26_ENV) || defined(AFS_AMD64_LINUX26_ENV)
! static int check_writable(unsigned long address) 
  { 
      pgd_t *pgd = pgd_offset_k(address);
  #ifdef PUD_SIZE
--- 1372,1378 ----
  }
  
  #if defined(AFS_I386_LINUX26_ENV) || defined(AFS_AMD64_LINUX26_ENV)
! static int check_access(unsigned long address, int mode) 
  { 
      pgd_t *pgd = pgd_offset_k(address);
  #ifdef PUD_SIZE
***************
*** 1381,1390 ****
  	pte = (pte_t *)pmd;
      else
  	pte = pte_offset_kernel(pmd, address);
!     if (pte_none(*pte) || !pte_present(*pte) || !pte_write(*pte))
  	return 0;
      return 1;
  }
  #endif
  
  void *osi_find_syscall_table(int which)
--- 1397,1430 ----
  	pte = (pte_t *)pmd;
      else
  	pte = pte_offset_kernel(pmd, address);
!     if (pte_none(*pte) || !pte_present(*pte))
! 	return 0;
!     if (mode && !pte_write(*pte))
  	return 0;
      return 1;
  }
+ 
+ static int check_table_readable(probectl *P, PROBETYPE *ptr)
+ {
+     PROBETYPE *next_page;
+     int i = 0, delta;
+ 
+     while (i < _SS(NR_syscalls)) {
+ 	next_page = (PROBETYPE *)PAGE_ALIGN((unsigned long)(ptr+1));
+ 	delta = next_page - ptr;
+ 	if (!check_access((unsigned long)ptr, 0)) {
+ #ifdef OSI_PROBE_DEBUG
+ 	    if (probe_debug & 0x0080)
+ 		printk("<7>osi_probe: %s                      0x%016lx not readable; delta=0x%lx\n",
+ 		       P->symbol, (unsigned long)ptr, delta);
+ #endif
+ 	    return delta - 1;
+ 	}
+ 	ptr += delta;
+ 	i += delta;
+     }
+     return -1;
+ }
  #endif
  
  void *osi_find_syscall_table(int which)
***************
*** 1412,1418 ****
      }
      printk("Found %s at 0x%lx (%s)\n", P->desc, (unsigned long)answer, method);
  #if defined(AFS_I386_LINUX26_ENV) || defined(AFS_AMD64_LINUX26_ENV)
!     if (!check_writable((unsigned long)answer)) {
  	printk("Address 0x%lx is not writable.\n", (unsigned long)answer);
  	printk("System call hooks will not be installed; proceeding anyway\n");
  	return 0;
--- 1452,1458 ----
      }
      printk("Found %s at 0x%lx (%s)\n", P->desc, (unsigned long)answer, method);
  #if defined(AFS_I386_LINUX26_ENV) || defined(AFS_AMD64_LINUX26_ENV)
!     if (!check_access((unsigned long)answer, 1)) {
  	printk("Address 0x%lx is not writable.\n", (unsigned long)answer);
  	printk("System call hooks will not be installed; proceeding anyway\n");
  	return 0;
Index: openafs/src/afs/LINUX/osi_vfsops.c
diff -c openafs/src/afs/LINUX/osi_vfsops.c:1.42.4.17 openafs/src/afs/LINUX/osi_vfsops.c:1.42.4.18
*** openafs/src/afs/LINUX/osi_vfsops.c:1.42.4.17	Tue Jun 26 01:42:05 2007
--- openafs/src/afs/LINUX/osi_vfsops.c	Fri Jul 13 18:17:25 2007
***************
*** 16,22 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_vfsops.c,v 1.42.4.17 2007/06/26 05:42:05 jaltman Exp $");
  
  #define __NO_VERSION__		/* don't define kernel_version in module.h */
  #include <linux/module.h> /* early to avoid printf->printk mapping */
--- 16,22 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_vfsops.c,v 1.42.4.18 2007/07/13 22:17:25 shadow Exp $");
  
  #define __NO_VERSION__		/* don't define kernel_version in module.h */
  #include <linux/module.h> /* early to avoid printf->printk mapping */
***************
*** 108,114 ****
  struct backing_dev_info afs_backing_dev_info = {
      .ra_pages		= 0, /* disable readahead, afs does prefetch */
  };
- #endif
  
  int
  afs_fill_super(struct super_block *sb, void *data, int silent)
--- 108,113 ----
***************
*** 457,463 ****
    .notify_change =	afs_notify_change,
  #endif
  };
! #endif
  
  /************** Support routines ************************/
  
--- 456,462 ----
    .notify_change =	afs_notify_change,
  #endif
  };
! 
  
  /************** Support routines ************************/
  
Index: openafs/src/auth/ktc.c
diff -c openafs/src/auth/ktc.c:1.16.8.4 openafs/src/auth/ktc.c:1.16.8.5
*** openafs/src/auth/ktc.c:1.16.8.4	Thu Feb  8 20:17:45 2007
--- openafs/src/auth/ktc.c	Thu Aug  9 10:58:23 2007
***************
*** 17,23 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/auth/ktc.c,v 1.16.8.4 2007/02/09 01:17:45 shadow Exp $");
  
  #if defined(UKERNEL)
  #include "afs/sysincludes.h"
--- 17,23 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/auth/ktc.c,v 1.16.8.5 2007/08/09 14:58:23 shadow Exp $");
  
  #if defined(UKERNEL)
  #include "afs/sysincludes.h"
***************
*** 1163,1168 ****
--- 1163,1169 ----
  {
      int k_errno;
      int kvno, lifetime;
+     long mit_compat;		/* MIT Kerberos 5 with Krb4 uses a "long" for issue_date */
  
      if (fd < 0) {
  	return TKT_FIL_INI;
***************
*** 1199,1208 ****
  	/* don't try to read a silly amount into ticket->dat */
  	token->ticketLen > MAXKTCTICKETLEN
  	|| tf_read((char *)(token->ticket), token->ticketLen) < 1
! 	|| tf_read((char *)&(token->startTime),
! 		   sizeof(token->startTime)) < 1) {
  	return TKT_FIL_FMT;
      }
      token->endTime = life_to_time(token->startTime, lifetime);
      token->kvno = kvno;
      return 0;
--- 1200,1209 ----
  	/* don't try to read a silly amount into ticket->dat */
  	token->ticketLen > MAXKTCTICKETLEN
  	|| tf_read((char *)(token->ticket), token->ticketLen) < 1
! 	|| tf_read((char *)&mit_compat, sizeof(mit_compat)) < 1) {
  	return TKT_FIL_FMT;
      }
+     token->startTime = mit_compat;
      token->endTime = life_to_time(token->startTime, lifetime);
      token->kvno = kvno;
      return 0;
***************
*** 1330,1335 ****
--- 1331,1337 ----
      off_t start;
      int lifetime, kvno;
      int count;			/* count for write */
+     long mit_compat;		/* MIT Kerberos 5 with Krb4 uses a "long" for issue_date */
  
      if (fd < 0) {		/* fd is ticket file as set by afs_tf_init */
  	return TKT_FIL_INI;
***************
*** 1399,1406 ****
      if (write(fd, atoken->ticket, count) != count)
  	goto bad;
      /* Issue date */
!     if (write(fd, (char *)&atoken->startTime, sizeof(afs_int32))
! 	!= sizeof(afs_int32))
  	goto bad;
  
      /* Actually, we should check each write for success */
--- 1401,1409 ----
      if (write(fd, atoken->ticket, count) != count)
  	goto bad;
      /* Issue date */
!     mit_compat = atoken->startTime;
!     if (write(fd, (char *)&mit_compat, sizeof(mit_compat))
! 	!= sizeof(mit_compat))
  	goto bad;
  
      /* Actually, we should check each write for success */
Index: openafs/src/butc/butc_xbsa.c
diff -c openafs/src/butc/butc_xbsa.c:1.8 openafs/src/butc/butc_xbsa.c:1.8.14.1
*** openafs/src/butc/butc_xbsa.c:1.8	Wed Jul 14 00:46:48 2004
--- openafs/src/butc/butc_xbsa.c	Mon Jul 16 16:42:05 2007
***************
*** 13,19 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/butc/butc_xbsa.c,v 1.8 2004/07/14 04:46:48 shadow Exp $");
  
  #include <sys/types.h>
  #include <afs/stds.h>
--- 13,19 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/butc/butc_xbsa.c,v 1.8.14.1 2007/07/16 20:42:05 shadow Exp $");
  
  #include <sys/types.h>
  #include <afs/stds.h>
***************
*** 132,138 ****
  		       RTLD_NOW | RTLD_LOCAL | RTLD_MEMBER);
  	}
  #elif defined(AFS_SUN5_ENV)
! 	dynlib = dlopen("/usr/lib/libXApi.so", RTLD_NOW | RTLD_LOCAL);
  #else
  	dynlib = NULL;
  #endif
--- 132,139 ----
  		       RTLD_NOW | RTLD_LOCAL | RTLD_MEMBER);
  	}
  #elif defined(AFS_SUN5_ENV)
! 	dlopen ("/usr/lib/libCstd.so.1", RTLD_NOW | RTLD_GLOBAL);
! 	dynlib = dlopen("/usr/lib/libXApi.so", RTLD_NOW | RTLD_GLOBAL);
  #else
  	dynlib = NULL;
  #endif
Index: openafs/src/config/NTMakefile.amd64_w2k
diff -c openafs/src/config/NTMakefile.amd64_w2k:1.24.2.25 openafs/src/config/NTMakefile.amd64_w2k:1.24.2.26
*** openafs/src/config/NTMakefile.amd64_w2k:1.24.2.25	Tue Jul 10 16:17:28 2007
--- openafs/src/config/NTMakefile.amd64_w2k	Thu Aug  9 18:34:21 2007
***************
*** 84,90 ****
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=2100
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
--- 84,90 ----
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=2200
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
Index: openafs/src/config/NTMakefile.i386_nt40
diff -c openafs/src/config/NTMakefile.i386_nt40:1.84.2.24 openafs/src/config/NTMakefile.i386_nt40:1.84.2.25
*** openafs/src/config/NTMakefile.i386_nt40:1.84.2.24	Tue Jul 10 16:17:28 2007
--- openafs/src/config/NTMakefile.i386_nt40	Thu Aug  9 18:34:21 2007
***************
*** 84,90 ****
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=2100
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
--- 84,90 ----
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=2200
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
Index: openafs/src/config/NTMakefile.i386_w2k
diff -c openafs/src/config/NTMakefile.i386_w2k:1.23.2.24 openafs/src/config/NTMakefile.i386_w2k:1.23.2.25
*** openafs/src/config/NTMakefile.i386_w2k:1.23.2.24	Tue Jul 10 16:17:28 2007
--- openafs/src/config/NTMakefile.i386_w2k	Thu Aug  9 18:34:21 2007
***************
*** 84,90 ****
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=2100
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
--- 84,90 ----
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=2200
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
Index: openafs/src/config/param.sparc_linux24.h
diff -c openafs/src/config/param.sparc_linux24.h:1.10.6.3 openafs/src/config/param.sparc_linux24.h:1.10.6.4
*** openafs/src/config/param.sparc_linux24.h:1.10.6.3	Wed Jun  6 13:33:28 2007
--- openafs/src/config/param.sparc_linux24.h	Tue Jul 17 00:05:29 2007
***************
*** 98,108 ****
  #endif
  #endif
  
! #ifdef __GLIBC__
! #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 3)
! #define USE_UCONTEXT
! #endif
! #endif
  
  #endif /* AFS_PARAM_H */
  
--- 98,105 ----
  #endif
  #endif
  
! /* Don't define USE_UCONTEXT on this platform.  It requires getcontext and
!    setcontext from glibc, which aren't implemented for 32-bit SPARC. */
  
  #endif /* AFS_PARAM_H */
  
Index: openafs/src/kauth/krb_tf.c
diff -c openafs/src/kauth/krb_tf.c:1.6 openafs/src/kauth/krb_tf.c:1.6.14.1
*** openafs/src/kauth/krb_tf.c:1.6	Tue Jul 15 19:15:17 2003
--- openafs/src/kauth/krb_tf.c	Thu Aug  9 10:58:23 2007
***************
*** 48,54 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/kauth/krb_tf.c,v 1.6 2003/07/15 23:15:17 shadow Exp $");
  
  #ifdef HAVE_FCNTL_H
  #include <fcntl.h>
--- 48,54 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/kauth/krb_tf.c,v 1.6.14.1 2007/08/09 14:58:23 shadow Exp $");
  
  #ifdef HAVE_FCNTL_H
  #include <fcntl.h>
***************
*** 84,89 ****
--- 84,90 ----
      char *tf_name;
      struct ktc_principal client, server;
      struct ktc_token token;
+     long mit_compat;	/* MIT Kerberos 5 with Krb4 uses a "long" for issue_date */
  
      if ((strlen(realm) >= sizeof(client.cell)))
  	return KABADNAME;
***************
*** 149,156 ****
      if (write(fd, (char *)(token.ticket), count) != count)
  	goto bad;
      /* Issue date */
!     if (write(fd, (char *)&token.startTime, sizeof(afs_int32))
! 	!= sizeof(afs_int32))
  	goto bad;
      close(fd);
      return 0;
--- 150,158 ----
      if (write(fd, (char *)(token.ticket), count) != count)
  	goto bad;
      /* Issue date */
!     mit_compat = token.startTime;
!     if (write(fd, (char *)&mit_compat, sizeof(mit_compat))
! 	!= sizeof(mit_compat))
  	goto bad;
      close(fd);
      return 0;
Index: openafs/src/libadmin/client/afs_clientAdmin.c
diff -c openafs/src/libadmin/client/afs_clientAdmin.c:1.11 openafs/src/libadmin/client/afs_clientAdmin.c:1.11.4.1
*** openafs/src/libadmin/client/afs_clientAdmin.c:1.11	Thu Jul 21 00:56:02 2005
--- openafs/src/libadmin/client/afs_clientAdmin.c	Sun Jul 15 20:02:16 2007
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/libadmin/client/afs_clientAdmin.c,v 1.11 2005/07/21 04:56:02 shadow Exp $");
  
  #include <afs/stds.h>
  #include "afs_clientAdmin.h"
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/libadmin/client/afs_clientAdmin.c,v 1.11.4.1 2007/07/16 00:02:16 jaltman Exp $");
  
  #include <afs/stds.h>
  #include "afs_clientAdmin.h"
***************
*** 193,199 ****
  	 * The token has been retrieved successfully, initialize
  	 * the rest of the token handle structure
  	 */
! 	strcpy(t_handle->cell, cellName);
  	t_handle->afs_token_set = 1;
  	t_handle->from_kernel = 1;
  	t_handle->kas_token_set = 0;
--- 193,200 ----
  	 * The token has been retrieved successfully, initialize
  	 * the rest of the token handle structure
  	 */
! 	strncpy(t_handle->cell, cellName, MAXCELLCHARS);
!         t_handle->cell[MAXCELLCHARS - 1] = '\0';
  	t_handle->afs_token_set = 1;
  	t_handle->from_kernel = 1;
  	t_handle->kas_token_set = 0;
***************
*** 568,574 ****
  
  	if ((GetAFSToken(cellName, principal, password, t_handle, &tst))
  	    && (GetKASToken(cellName, principal, password, t_handle, &tst))) {
! 	    strcpy(t_handle->cell, cellName);
  	    t_handle->from_kernel = 0;
  	    t_handle->afs_token_set = 1;
  	    t_handle->kas_token_set = 1;
--- 569,576 ----
  
  	if ((GetAFSToken(cellName, principal, password, t_handle, &tst))
  	    && (GetKASToken(cellName, principal, password, t_handle, &tst))) {
! 	    strncpy(t_handle->cell, cellName, MAXCELLCHARS);
!             t_handle->cell[MAXCELLCHARS - 1] = '\0';
  	    t_handle->from_kernel = 0;
  	    t_handle->afs_token_set = 1;
  	    t_handle->kas_token_set = 1;
***************
*** 868,874 ****
       * information for each server in the cell
       */
  
!     strcpy(c_handle->working_cell, cellName);
      if (!(tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) {
  	tst = ADMCLIENTBADCLIENTCONFIG;
  	goto fail_afsclient_CellOpen;
--- 870,877 ----
       * information for each server in the cell
       */
  
!     strncpy(c_handle->working_cell, cellName, MAXCELLCHARS);
!     c_handle->working_cell[MAXCELLCHARS - 1] = '\0';
      if (!(tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) {
  	tst = ADMCLIENTBADCLIENTCONFIG;
  	goto fail_afsclient_CellOpen;
***************
*** 878,884 ****
       * We must copy the cellName here because afsconf_GetCellInfo
       * actually writes over the cell name it is passed.
       */
!     strncpy(copyCell, cellName, MAXCELLCHARS - 1);
      for (i = 0; (i < NUM_SERVER_TYPES); i++) {
  	if (i == KAS) {
  	    tst =
--- 881,888 ----
       * We must copy the cellName here because afsconf_GetCellInfo
       * actually writes over the cell name it is passed.
       */
!     strncpy(copyCell, cellName, MAXCELLCHARS);
!     copyCell[MAXCELLCHARS - 1] ='\0';
      for (i = 0; (i < NUM_SERVER_TYPES); i++) {
  	if (i == KAS) {
  	    tst =
***************
*** 1963,1968 ****
--- 1967,1973 ----
  	if (host != NULL) {
  	    strncpy(serv->server[iserv].serverName, host->h_name,
  		    AFS_MAX_SERVER_NAME_LEN);
+             serv->server[iserv].serverName[AFS_MAX_SERVER_NAME_LEN - 1] = '\0';
  	}
      }
      UNLOCK_GLOBAL_MUTEX;
Index: openafs/src/libadmin/kas/afs_kasAdmin.c
diff -c openafs/src/libadmin/kas/afs_kasAdmin.c:1.13 openafs/src/libadmin/kas/afs_kasAdmin.c:1.13.4.1
*** openafs/src/libadmin/kas/afs_kasAdmin.c:1.13	Tue Aug 16 14:09:49 2005
--- openafs/src/libadmin/kas/afs_kasAdmin.c	Sun Jul 15 20:02:17 2007
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/libadmin/kas/afs_kasAdmin.c,v 1.13 2005/08/16 18:09:49 shadow Exp $");
  
  #include <stdio.h>
  
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/libadmin/kas/afs_kasAdmin.c,v 1.13.4.1 2007/07/16 00:02:17 jaltman Exp $");
  
  #include <stdio.h>
  
***************
*** 35,42 ****
  
  #undef ENCRYPT
  
- extern int ubik_Call();
- 
  typedef struct {
      int begin_magic;
      int is_valid;
--- 35,40 ----
***************
*** 539,545 ****
      afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
      kas_server_p k_handle = (kas_server_p) serverHandle;
      kas_server_t kaserver;
!     struct kas_encryptionKey key;
  
      /*
       * Validate input arguments and make rpc.
--- 537,544 ----
      afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
      kas_server_p k_handle = (kas_server_p) serverHandle;
      kas_server_t kaserver;
!     EncryptionKey key;
!     struct kas_encryptionKey kas_key;
  
      /*
       * Validate input arguments and make rpc.
***************
*** 559,570 ****
  	goto fail_kas_PrincipalCreate;
      }
  
!     if (!kas_StringToKey(kaserver.cell, password, &key, &tst)) {
  	goto fail_kas_PrincipalCreate;
      }
  
      tst =
! 	ubik_Call(KAM_CreateUser, kaserver.servers, 0, who->principal,
  		  who->instance, key);
      if (tst) {
  	goto fail_kas_PrincipalCreate;
--- 558,571 ----
  	goto fail_kas_PrincipalCreate;
      }
  
!     if (!kas_StringToKey(kaserver.cell, password, &kas_key, &tst)) {
  	goto fail_kas_PrincipalCreate;
      }
  
+     memcpy(&key, &kas_key, sizeof(key));
+ 
      tst =
! 	ubik_KAM_CreateUser(kaserver.servers, 0, who->principal,
  		  who->instance, key);
      if (tst) {
  	goto fail_kas_PrincipalCreate;
***************
*** 624,630 ****
  	goto fail_kas_PrincipalDelete;
      }
      tst =
! 	ubik_Call(KAM_DeleteUser, kaserver.servers, 0, who->principal,
  		  who->instance);
      if (tst) {
  	goto fail_kas_PrincipalDelete;
--- 625,631 ----
  	goto fail_kas_PrincipalDelete;
      }
      tst =
! 	ubik_KAM_DeleteUser(kaserver.servers, 0, who->principal,
  		  who->instance);
      if (tst) {
  	goto fail_kas_PrincipalDelete;
***************
*** 802,808 ****
      }
  
      tst =
! 	ubik_Call(KAM_GetEntry, kaserver.servers, 0, who->principal,
  		  who->instance, KAMAJORVERSION, &entry);
      if (tst) {
  	goto fail_kas_PrincipalGet;
--- 803,809 ----
      }
  
      tst =
! 	ubik_KAM_GetEntry(kaserver.servers, 0, who->principal,
  		  who->instance, KAMAJORVERSION, &entry);
      if (tst) {
  	goto fail_kas_PrincipalGet;
***************
*** 858,865 ****
      principal_get_p prin = (principal_get_p) rpc_specific;
  
      tst =
! 	ubik_Call(KAM_ListEntry, prin->kaserver.servers, 0, prin->current,
! 		  &prin->next, &prin->count, &prin->principal[slot]);
      if (tst == 0) {
  	prin->current = prin->next;
  	if (prin->next == 0) {
--- 859,866 ----
      principal_get_p prin = (principal_get_p) rpc_specific;
  
      tst =
! 	ubik_KAM_ListEntry(prin->kaserver.servers, 0, prin->current,
!                            &prin->next, &prin->count, (kaident *)&prin->principal[slot]);
      if (tst == 0) {
  	prin->current = prin->next;
  	if (prin->next == 0) {
***************
*** 1109,1121 ****
  int ADMINAPI
  kas_PrincipalKeySet(const void *cellHandle, const void *serverHandle,
  		    const kas_identity_p who, int keyVersion,
! 		    const kas_encryptionKey_p key, afs_status_p st)
  {
      int rc = 0;
      afs_status_t tst = 0;
      afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
      kas_server_p k_handle = (kas_server_p) serverHandle;
      kas_server_t kaserver;
  
      /*
       * Validate input arguments and make rpc.
--- 1110,1123 ----
  int ADMINAPI
  kas_PrincipalKeySet(const void *cellHandle, const void *serverHandle,
  		    const kas_identity_p who, int keyVersion,
! 		    const kas_encryptionKey_p kas_keyp, afs_status_p st)
  {
      int rc = 0;
      afs_status_t tst = 0;
      afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
      kas_server_p k_handle = (kas_server_p) serverHandle;
      kas_server_t kaserver;
+     EncryptionKey key; 
  
      /*
       * Validate input arguments and make rpc.
***************
*** 1126,1132 ****
  	goto fail_kas_PrincipalKeySet;
      }
  
!     if (key == NULL) {
  	tst = ADMKASKEYNULL;
  	goto fail_kas_PrincipalKeySet;
      }
--- 1128,1134 ----
  	goto fail_kas_PrincipalKeySet;
      }
  
!     if (kas_keyp == NULL) {
  	tst = ADMKASKEYNULL;
  	goto fail_kas_PrincipalKeySet;
      }
***************
*** 1135,1143 ****
  	goto fail_kas_PrincipalKeySet;
      }
  
      tst =
! 	ubik_Call(KAM_SetPassword, kaserver.servers, 0, who->principal,
! 		  who->instance, keyVersion, *key);
      if (tst) {
  	goto fail_kas_PrincipalKeySet;
      }
--- 1137,1148 ----
  	goto fail_kas_PrincipalKeySet;
      }
  
+     memcpy(&key, kas_keyp, sizeof(key));
+ 
      tst =
! 	ubik_KAM_SetPassword(kaserver.servers, 0, who->principal,
! 		  who->instance, keyVersion, key);
!     memset(&key, 0, sizeof(key));
      if (tst) {
  	goto fail_kas_PrincipalKeySet;
      }
***************
*** 1311,1317 ****
      }
  
      tst =
! 	ubik_Call(KAM_GetEntry, kaserver.servers, 0, who->principal,
  		  who->instance, KAMAJORVERSION, &tentry);
      if (tst == 0) {
  	*cur_flags = tentry.flags;
--- 1316,1322 ----
      }
  
      tst =
! 	ubik_KAM_GetEntry(kaserver.servers, 0, who->principal,
  		  who->instance, KAMAJORVERSION, &tentry);
      if (tst == 0) {
  	*cur_flags = tentry.flags;
***************
*** 1518,1524 ****
  	    goto fail_kas_PrincipalFieldsSet;
  	}
  	tst =
! 	    ubik_Call(KAM_SetFields, kaserver.servers, 0, who->principal,
  		      who->instance, flags, expiration, lifetime, -1,
  		      was_spare, 0);
  	if (tst == 0) {
--- 1523,1529 ----
  	    goto fail_kas_PrincipalFieldsSet;
  	}
  	tst =
! 	    ubik_KAM_SetFields(kaserver.servers, 0, who->principal,
  		      who->instance, flags, expiration, lifetime, -1,
  		      was_spare, 0);
  	if (tst == 0) {
***************
*** 1584,1590 ****
      }
  
      tst =
! 	ubik_Call(KAM_GetStats, kaserver.servers, 0, KAMAJORVERSION, &admins,
  		  &statics, &dynamics);
      if (tst) {
  	goto fail_kas_ServerStatsGet;
--- 1589,1595 ----
      }
  
      tst =
! 	ubik_KAM_GetStats(kaserver.servers, 0, KAMAJORVERSION, &admins,
  		  &statics, &dynamics);
      if (tst) {
  	goto fail_kas_ServerStatsGet;
***************
*** 1672,1678 ****
      if (!ChooseValidServer(c_handle, k_handle, &kaserver, &tst)) {
  	goto fail_kas_ServerDebugGet;
      }
!     tst = ubik_Call(KAM_Debug, kaserver.servers, 0, KAMAJORVERSION, 0, &info);
      if (tst) {
  	goto fail_kas_ServerDebugGet;
      }
--- 1677,1683 ----
      if (!ChooseValidServer(c_handle, k_handle, &kaserver, &tst)) {
  	goto fail_kas_ServerDebugGet;
      }
!     tst = ubik_KAM_Debug(kaserver.servers, 0, KAMAJORVERSION, 0, &info);
      if (tst) {
  	goto fail_kas_ServerDebugGet;
      }
***************
*** 1741,1759 ****
  
  int ADMINAPI
  kas_ServerRandomKeyGet(const void *cellHandle, const void *serverHandle,
! 		       kas_encryptionKey_p key, afs_status_p st)
  {
      int rc = 0;
      afs_status_t tst = 0;
      afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
      kas_server_p k_handle = (kas_server_p) serverHandle;
      kas_server_t kaserver;
  
      /*
       * Validate input arguments and make rpc.
       */
  
!     if (key == NULL) {
  	tst = ADMKASKEYNULL;
  	goto fail_kas_ServerRandomKeyGet;
      }
--- 1746,1765 ----
  
  int ADMINAPI
  kas_ServerRandomKeyGet(const void *cellHandle, const void *serverHandle,
! 		       kas_encryptionKey_p kas_keyp, afs_status_p st)
  {
      int rc = 0;
      afs_status_t tst = 0;
      afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
      kas_server_p k_handle = (kas_server_p) serverHandle;
      kas_server_t kaserver;
+     EncryptionKey key;
  
      /*
       * Validate input arguments and make rpc.
       */
  
!     if (kas_keyp == NULL) {
  	tst = ADMKASKEYNULL;
  	goto fail_kas_ServerRandomKeyGet;
      }
***************
*** 1762,1771 ****
  	goto fail_kas_ServerRandomKeyGet;
      }
  
!     tst = ubik_Call(KAM_GetRandomKey, kaserver.servers, 0, key);
      if (tst) {
  	goto fail_kas_ServerRandomKeyGet;
      }
      rc = 1;
  
    fail_kas_ServerRandomKeyGet:
--- 1768,1778 ----
  	goto fail_kas_ServerRandomKeyGet;
      }
  
!     tst = ubik_KAM_GetRandomKey(kaserver.servers, 0, &key);
      if (tst) {
  	goto fail_kas_ServerRandomKeyGet;
      }
+     memcpy(kas_keyp, &key, sizeof(*kas_keyp));
      rc = 1;
  
    fail_kas_ServerRandomKeyGet:
Index: openafs/src/libadmin/pts/afs_ptsAdmin.c
diff -c openafs/src/libadmin/pts/afs_ptsAdmin.c:1.11 openafs/src/libadmin/pts/afs_ptsAdmin.c:1.11.14.1
*** openafs/src/libadmin/pts/afs_ptsAdmin.c:1.11	Fri Apr  2 01:54:15 2004
--- openafs/src/libadmin/pts/afs_ptsAdmin.c	Sun Jul 15 20:02:17 2007
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/libadmin/pts/afs_ptsAdmin.c,v 1.11 2004/04/02 06:54:15 jaltman Exp $");
  
  #include <stdio.h>
  
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/libadmin/pts/afs_ptsAdmin.c,v 1.11.14.1 2007/07/16 00:02:17 jaltman Exp $");
  
  #include <stdio.h>
  
***************
*** 124,130 ****
  	}
      }
  
!     tst = ubik_Call(PR_NameToID, cellHandle->pts, 0, names, ids);
  
      if (tst) {
  	goto fail_TranslatePTSNames;
--- 124,130 ----
  	}
      }
  
!     tst = ubik_PR_NameToID(cellHandle->pts, 0, names, ids);
  
      if (tst) {
  	goto fail_TranslatePTSNames;
***************
*** 200,206 ****
--- 200,208 ----
      names.namelist_val = (prname *) & tmp_array[0];
  
      strncpy(names.namelist_val[0], id1, PTS_MAX_NAME_LEN);
+     names.namelist_val[0][PTS_MAX_NAME_LEN - 1] = '\0';
      strncpy(names.namelist_val[1], id2, PTS_MAX_NAME_LEN);
+     names.namelist_val[1][PTS_MAX_NAME_LEN - 1] = '\0';
      ids->idlist_val = 0;
      ids->idlist_len = 0;
  
***************
*** 277,283 ****
      names[0].namelist_len = 1;
      names[0].namelist_val = (prname *) & tmp_array[0];
  
!     strncpy(names[0].namelist_val, ptsName, PTS_MAX_NAME_LEN);
      ids.idlist_val = 0;
      ids.idlist_len = 0;
  
--- 279,286 ----
      names[0].namelist_len = 1;
      names[0].namelist_val = (prname *) & tmp_array[0];
  
!     strncpy((char *)names[0].namelist_val, ptsName, PTS_MAX_NAME_LEN);
!     ((char *)names[0].namelist_val)[PTS_MAX_NAME_LEN - 1] = '\0';
      ids.idlist_val = 0;
      ids.idlist_len = 0;
  
***************
*** 344,350 ****
      int rc = 0;
      afs_status_t tst = 0;
  
!     tst = ubik_Call(PR_IDToName, cellHandle->pts, 0, ids, names);
  
      if (tst) {
  	goto fail_TranslatePTSIds;
--- 347,353 ----
      int rc = 0;
      afs_status_t tst = 0;
  
!     tst = ubik_PR_IDToName(cellHandle->pts, 0, ids, names);
  
      if (tst) {
  	goto fail_TranslatePTSIds;
***************
*** 419,425 ****
       */
  
      tst =
! 	ubik_Call(PR_AddToGroup, c_handle->pts, 0, ids.idlist_val[0],
  		  ids.idlist_val[1]);
  
      if (tst != 0) {
--- 422,428 ----
       */
  
      tst =
! 	ubik_PR_AddToGroup(c_handle->pts, 0, ids.idlist_val[0],
  		  ids.idlist_val[1]);
  
      if (tst != 0) {
***************
*** 499,505 ****
       */
  
      tst =
! 	ubik_Call(PR_ChangeEntry, c_handle->pts, 0, ids.idlist_val[1], "",
  		  ids.idlist_val[0], 0);
  
      if (tst != 0) {
--- 502,508 ----
       */
  
      tst =
! 	ubik_PR_ChangeEntry(c_handle->pts, 0, ids.idlist_val[1], "",
  		  ids.idlist_val[0], 0);
  
      if (tst != 0) {
***************
*** 596,606 ****
  
      if (*newGroupId != 0) {
  	tst =
! 	    ubik_Call(PR_INewEntry, c_handle->pts, 0, newGroup, *newGroupId,
  		      newOwnerId);
      } else {
  	tst =
! 	    ubik_Call(PR_NewEntry, c_handle->pts, 0, newGroup, PRGRP,
  		      newOwnerId, newGroupId);
      }
  
--- 599,609 ----
  
      if (*newGroupId != 0) {
  	tst =
! 	    ubik_PR_INewEntry(c_handle->pts, 0, newGroup, *newGroupId,
  		      newOwnerId);
      } else {
  	tst =
! 	    ubik_PR_NewEntry(c_handle->pts, 0, newGroup, PRGRP,
  		      newOwnerId, newGroupId);
      }
  
***************
*** 722,728 ****
       * Retrieve information about the group
       */
  
!     tst = ubik_Call(PR_ListEntry, c_handle->pts, 0, groupId, &groupEntry);
  
      if (tst != 0) {
  	goto fail_pts_GroupGet;
--- 725,731 ----
       * Retrieve information about the group
       */
  
!     tst = ubik_PR_ListEntry(c_handle->pts, 0, groupId, &groupEntry);
  
      if (tst != 0) {
  	goto fail_pts_GroupGet;
***************
*** 732,738 ****
      groupP->nameUid = groupEntry.id;
      groupP->ownerUid = groupEntry.owner;
      groupP->creatorUid = groupEntry.creator;
!     strcpy(groupP->name, groupEntry.name);
      /*
       * Set the access rights based upon the value of the flags member
       * of the groupEntry struct.
--- 735,742 ----
      groupP->nameUid = groupEntry.id;
      groupP->ownerUid = groupEntry.owner;
      groupP->creatorUid = groupEntry.creator;
!     strncpy(groupP->name, groupEntry.name, PTS_MAX_NAME_LEN);
!     groupP->name[PTS_MAX_NAME_LEN - 1] = '\0';
      /*
       * Set the access rights based upon the value of the flags member
       * of the groupEntry struct.
***************
*** 821,828 ****
  	goto fail_pts_GroupGet;
      }
  
!     strcpy(groupP->owner, names.namelist_val[0]);
!     strcpy(groupP->creator, names.namelist_val[1]);
      free(names.namelist_val);
      rc = 1;
  
--- 825,834 ----
  	goto fail_pts_GroupGet;
      }
  
!     strncpy(groupP->owner, names.namelist_val[0], PTS_MAX_NAME_LEN);
!     groupP->owner[PTS_MAX_NAME_LEN - 1] = '\0';
!     strncpy(groupP->creator, names.namelist_val[1], PTS_MAX_NAME_LEN);
!     groupP->creator[PTS_MAX_NAME_LEN - 1] = '\0';
      free(names.namelist_val);
      rc = 1;
  
***************
*** 894,900 ****
       * Make the rpc
       */
  
!     tst = ubik_Call(PR_Delete, c_handle->pts, 0, entryId);
  
      if (tst != 0) {
  	goto fail_EntryDelete;
--- 900,906 ----
       * Make the rpc
       */
  
!     tst = ubik_PR_Delete(c_handle->pts, 0, entryId);
  
      if (tst != 0) {
  	goto fail_EntryDelete;
***************
*** 981,987 ****
  	goto fail_pts_GroupMaxGet;
      }
  
!     tst = ubik_Call(PR_ListMax, c_handle->pts, 0, &maxUserId, maxGroupId);
  
      if (tst != 0) {
  	goto fail_pts_GroupMaxGet;
--- 987,993 ----
  	goto fail_pts_GroupMaxGet;
      }
  
!     tst = ubik_PR_ListMax(c_handle->pts, 0, &maxUserId, maxGroupId);
  
      if (tst != 0) {
  	goto fail_pts_GroupMaxGet;
***************
*** 1031,1037 ****
  	goto fail_pts_GroupMaxSet;
      }
  
!     tst = ubik_Call(PR_SetMax, c_handle->pts, 0, maxGroupId, PRGRP);
  
      if (tst != 0) {
  	goto fail_pts_GroupMaxSet;
--- 1037,1043 ----
  	goto fail_pts_GroupMaxSet;
      }
  
!     tst = ubik_PR_SetMax(c_handle->pts, 0, maxGroupId, PRGRP);
  
      if (tst != 0) {
  	goto fail_pts_GroupMaxSet;
***************
*** 1202,1208 ****
      iter->ids.prlist_val = 0;
  
      tst =
! 	ubik_Call(PR_ListElements, c_handle->pts, 0, groupId, &iter->ids,
  		  &exceeded);
  
      if (tst != 0) {
--- 1208,1214 ----
      iter->ids.prlist_val = 0;
  
      tst =
! 	ubik_PR_ListElements(c_handle->pts, 0, groupId, &iter->ids,
  		  &exceeded);
  
      if (tst != 0) {
***************
*** 1510,1516 ****
       */
  
      tst =
! 	ubik_Call(PR_RemoveFromGroup, c_handle->pts, 0, ids.idlist_val[0],
  		  ids.idlist_val[1]);
  
      if (tst != 0) {
--- 1516,1522 ----
       */
  
      tst =
! 	ubik_PR_RemoveFromGroup(c_handle->pts, 0, ids.idlist_val[0],
  		  ids.idlist_val[1]);
  
      if (tst != 0) {
***************
*** 1592,1598 ****
       * Make the rpc
       */
  
!     tst = ubik_Call(PR_ChangeEntry, c_handle->pts, 0, groupId, newName, 0, 0);
  
      if (tst != 0) {
  	goto fail_pts_GroupRename;
--- 1598,1604 ----
       * Make the rpc
       */
  
!     tst = ubik_PR_ChangeEntry(c_handle->pts, 0, groupId, newName, 0, 0);
  
      if (tst != 0) {
  	goto fail_pts_GroupRename;
***************
*** 1751,1757 ****
       */
  
      tst =
! 	ubik_Call(PR_SetFieldsEntry, c_handle->pts, 0, groupId, PR_SF_ALLBITS,
  		  flags, 0, 0, 0, 0);
  
      if (tst != 0) {
--- 1757,1763 ----
       */
  
      tst =
! 	ubik_PR_SetFieldsEntry(c_handle->pts, 0, groupId, PR_SF_ALLBITS,
  		  flags, 0, 0, 0, 0);
  
      if (tst != 0) {
***************
*** 1823,1833 ****
  
      if (*newUserId != 0) {
  	tst =
! 	    ubik_Call(PR_INewEntry, c_handle->pts, 0, userName, *newUserId,
  		      0);
      } else {
  	tst =
! 	    ubik_Call(PR_NewEntry, c_handle->pts, 0, userName, 0, 0,
  		      newUserId);
      }
  
--- 1829,1839 ----
  
      if (*newUserId != 0) {
  	tst =
! 	    ubik_PR_INewEntry(c_handle->pts, 0, userName, *newUserId,
  		      0);
      } else {
  	tst =
! 	    ubik_PR_NewEntry(c_handle->pts, 0, userName, 0, 0,
  		      newUserId);
      }
  
***************
*** 1945,1951 ****
  	    goto fail_IsAdministrator;
  	}
  	tst =
! 	    ubik_Call(PR_IsAMemberOf, c_handle->pts, 0, userId, adminId,
  		      &isAdmin);
  	if (tst != 0) {
  	    goto fail_IsAdministrator;
--- 1951,1957 ----
  	    goto fail_IsAdministrator;
  	}
  	tst =
! 	    ubik_PR_IsAMemberOf(c_handle->pts, 0, userId, adminId,
  		      &isAdmin);
  	if (tst != 0) {
  	    goto fail_IsAdministrator;
***************
*** 2035,2041 ****
       * Retrieve information about the group
       */
  
!     tst = ubik_Call(PR_ListEntry, c_handle->pts, 0, userId, &userEntry);
  
      if (tst != 0) {
  	goto fail_pts_UserGet;
--- 2041,2047 ----
       * Retrieve information about the group
       */
  
!     tst = ubik_PR_ListEntry(c_handle->pts, 0, userId, &userEntry);
  
      if (tst != 0) {
  	goto fail_pts_UserGet;
***************
*** 2060,2066 ****
      userP->nameUid = userEntry.id;
      userP->ownerUid = userEntry.owner;
      userP->creatorUid = userEntry.creator;
!     strcpy(userP->name, userEntry.name);
  
      /*
       * The permission bits are described in the GroupGet function above.
--- 2066,2073 ----
      userP->nameUid = userEntry.id;
      userP->ownerUid = userEntry.owner;
      userP->creatorUid = userEntry.creator;
!     strncpy(userP->name, userEntry.name, PTS_MAX_NAME_LEN);
!     userP->name[PTS_MAX_NAME_LEN - 1] = '\0';
  
      /*
       * The permission bits are described in the GroupGet function above.
***************
*** 2104,2111 ****
  	goto fail_pts_UserGet;
      }
  
!     strcpy(userP->owner, names.namelist_val[0]);
!     strcpy(userP->creator, names.namelist_val[1]);
      free(names.namelist_val);
      rc = 1;
  
--- 2111,2120 ----
  	goto fail_pts_UserGet;
      }
  
!     strncpy(userP->owner, names.namelist_val[0], PTS_MAX_NAME_LEN);
!     userP->owner[PTS_MAX_NAME_LEN - 1] ='\0';
!     strncpy(userP->creator, names.namelist_val[1], PTS_MAX_NAME_LEN);
!     userP->creator[PTS_MAX_NAME_LEN - 1] = '\0';
      free(names.namelist_val);
      rc = 1;
  
***************
*** 2179,2185 ****
       * Make the rpc
       */
  
!     tst = ubik_Call(PR_ChangeEntry, c_handle->pts, 0, userId, newName, 0, 0);
  
      if (tst != 0) {
  	goto fail_pts_UserRename;
--- 2188,2194 ----
       * Make the rpc
       */
  
!     tst = ubik_PR_ChangeEntry(c_handle->pts, 0, userId, newName, 0, 0);
  
      if (tst != 0) {
  	goto fail_pts_UserRename;
***************
*** 2323,2329 ****
       */
  
      tst =
! 	ubik_Call(PR_SetFieldsEntry, c_handle->pts, 0, userId, mask, flags,
  		  newQuota, 0, 0, 0);
  
      if (tst != 0) {
--- 2332,2338 ----
       */
  
      tst =
! 	ubik_PR_SetFieldsEntry(c_handle->pts, 0, userId, mask, flags,
  		  newQuota, 0, 0, 0);
  
      if (tst != 0) {
***************
*** 2380,2386 ****
  	goto fail_pts_UserMaxGet;
      }
  
!     tst = ubik_Call(PR_ListMax, c_handle->pts, 0, maxUserId, &maxGroupId);
  
      if (tst != 0) {
  	goto fail_pts_UserMaxGet;
--- 2389,2395 ----
  	goto fail_pts_UserMaxGet;
      }
  
!     tst = ubik_PR_ListMax(c_handle->pts, 0, maxUserId, &maxGroupId);
  
      if (tst != 0) {
  	goto fail_pts_UserMaxGet;
***************
*** 2430,2436 ****
  	goto fail_pts_UserMaxSet;
      }
  
!     tst = ubik_Call(PR_SetMax, c_handle->pts, 0, maxUserId, 0);
  
      if (tst != 0) {
  	goto fail_pts_UserMaxSet;
--- 2439,2445 ----
  	goto fail_pts_UserMaxSet;
      }
  
!     tst = ubik_PR_SetMax(c_handle->pts, 0, maxUserId, 0);
  
      if (tst != 0) {
  	goto fail_pts_UserMaxSet;
***************
*** 2595,2601 ****
  
      if ((!list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
  	tst =
! 	    ubik_Call(PR_ListOwned, list->c_handle->pts, 0, list->owner,
  		      &list->owned_ids, &list->more);
  	if (tst != 0) {
  	    goto fail_GetOwnedGroupRPC;
--- 2604,2610 ----
  
      if ((!list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
  	tst =
! 	    ubik_PR_ListOwned(list->c_handle->pts, 0, list->owner,
  		      &list->owned_ids, &list->more);
  	if (tst != 0) {
  	    goto fail_GetOwnedGroupRPC;
***************
*** 2940,2946 ****
  	bulkentries.prentries_len = 0;
  
  	tst =
! 	    ubik_Call(PR_ListEntries, list->c_handle->pts, 0, list->flag,
  		      start, &bulkentries, &(list->nextstartindex));
  
  	if (tst != 0) {
--- 2949,2955 ----
  	bulkentries.prentries_len = 0;
  
  	tst =
! 	    ubik_PR_ListEntries(list->c_handle->pts, 0, list->flag,
  		      start, &bulkentries, &(list->nextstartindex));
  
  	if (tst != 0) {
Index: openafs/src/libadmin/pts/afs_ptsAdmin.h
diff -c openafs/src/libadmin/pts/afs_ptsAdmin.h:1.5 openafs/src/libadmin/pts/afs_ptsAdmin.h:1.5.14.1
*** openafs/src/libadmin/pts/afs_ptsAdmin.h:1.5	Tue Jul 15 19:15:31 2003
--- openafs/src/libadmin/pts/afs_ptsAdmin.h	Sun Jul 15 20:02:17 2007
***************
*** 13,20 ****
  #include <afs/param.h>
  #include <afs/afs_Admin.h>
  
! #define PTS_MAX_NAME_LEN 64
! #define PTS_MAX_GROUPS 5000
  
  typedef enum {
      PTS_USER_OWNER_ACCESS,
--- 13,20 ----
  #include <afs/param.h>
  #include <afs/afs_Admin.h>
  
! #define PTS_MAX_NAME_LEN 64     /* must equal PR_MAXNAMELEN */
! #define PTS_MAX_GROUPS 5000     /* must equal PR_MAXGROUPS */
  
  typedef enum {
      PTS_USER_OWNER_ACCESS,
Index: openafs/src/libadmin/vos/afs_vosAdmin.c
diff -c openafs/src/libadmin/vos/afs_vosAdmin.c:1.11 openafs/src/libadmin/vos/afs_vosAdmin.c:1.11.4.1
*** openafs/src/libadmin/vos/afs_vosAdmin.c:1.11	Tue Oct 25 02:30:52 2005
--- openafs/src/libadmin/vos/afs_vosAdmin.c	Sun Jul 15 20:02:18 2007
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/libadmin/vos/afs_vosAdmin.c,v 1.11 2005/10/25 06:30:52 shadow Exp $");
  
  #include <afs/stds.h>
  #include <stdio.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/libadmin/vos/afs_vosAdmin.c,v 1.11.4.1 2007/07/16 00:02:18 jaltman Exp $");
  
  #include <afs/stds.h>
  #include <stdio.h>
***************
*** 567,574 ****
      if (tst) {
  	goto fail_vos_PartitionGet;
      }
!     strcpy(partitionP->name, part_info.name);
!     strcpy(partitionP->deviceName, part_info.devName);
      partitionP->lockFileDescriptor = part_info.lock_fd;
      partitionP->totalSpace = part_info.minFree;
      partitionP->totalFreeSpace = part_info.free;
--- 567,576 ----
      if (tst) {
  	goto fail_vos_PartitionGet;
      }
!     strncpy(partitionP->name, part_info.name, VOS_MAX_PARTITION_NAME_LEN);
!     partitionP->name[VOS_MAX_PARTITION_NAME_LEN-1] = '\0';
!     strncpy(partitionP->deviceName, part_info.devName, VOS_MAX_PARTITION_NAME_LEN);
!     partitionP->deviceName[VOS_MAX_PARTITION_NAME_LEN-1] = '\0';
      partitionP->lockFileDescriptor = part_info.lock_fd;
      partitionP->totalSpace = part_info.minFree;
      partitionP->totalFreeSpace = part_info.free;
***************
*** 1215,1221 ****
  	    addr_multi.bulkaddrs_val = 0;
  	    addr_multi.bulkaddrs_len = 0;
  	    tst =
! 		ubik_Call(VL_GetAddrsU, serv->vldb, 0, &m_attrs, &m_uuid,
  			  &m_unique, &total_multi, &addr_multi);
  	    if (tst) {
  		goto fail_GetServerRPC;
--- 1217,1223 ----
  	    addr_multi.bulkaddrs_val = 0;
  	    addr_multi.bulkaddrs_len = 0;
  	    tst =
! 		ubik_VL_GetAddrsU(serv->vldb, 0, &m_attrs, &m_uuid,
  			  &m_unique, &total_multi, &addr_multi);
  	    if (tst) {
  		goto fail_GetServerRPC;
***************
*** 1880,1886 ****
  	dest->status |= VOS_VLDB_ENTRY_BACKEXISTS;
      }
  
!     strcpy(dest->name, source->name);
      for (i = 0; i < VOS_MAX_REPLICA_SITES; i++) {
  	dest->volumeSites[i].serverAddress = source->serverNumber[i];
  	dest->volumeSites[i].serverPartition = source->serverPartition[i];
--- 1882,1889 ----
  	dest->status |= VOS_VLDB_ENTRY_BACKEXISTS;
      }
  
!     strncpy(dest->name, source->name, VOS_MAX_VOLUME_NAME_LEN);
!     dest->name[VOS_MAX_VOLUME_NAME_LEN - 1] = '\0';
      for (i = 0; i < VOS_MAX_REPLICA_SITES; i++) {
  	dest->volumeSites[i].serverAddress = source->serverNumber[i];
  	dest->volumeSites[i].serverPartition = source->serverPartition[i];
***************
*** 2354,2360 ****
       */
  
      if (volumeId != NULL) {
! 	tst = ubik_Call(VL_DeleteEntry, c_handle->vos, 0, *volumeId, -1);
  	if (tst != 0) {
  	    goto fail_vos_VLDBEntryRemove;
  	}
--- 2357,2363 ----
       */
  
      if (volumeId != NULL) {
! 	tst = ubik_VL_DeleteEntry(c_handle->vos, 0, *volumeId, -1);
  	if (tst != 0) {
  	    goto fail_vos_VLDBEntryRemove;
  	}
***************
*** 2392,2399 ****
      }
  
      for (i = 0; i < nentries; i++) {
! 	ubik_Call(VL_DeleteEntry, c_handle->vos, 0,
! 		  entries.nbulkentries_val[i].volumeId[RWVOL]);
      }
      rc = 1;
  
--- 2395,2402 ----
      }
  
      for (i = 0; i < nentries; i++) {
! 	ubik_VL_DeleteEntry(c_handle->vos, 0,
! 		  entries.nbulkentries_val[i].volumeId[RWVOL], -1);
      }
      rc = 1;
  
***************
*** 2546,2552 ****
  	goto fail_vos_VLDBEntryLock;
      }
  
!     tst = ubik_Call(VL_SetLock, c_handle->vos, 0, volumeId, -1, VLOP_DELETE);
      if (tst != 0) {
  	goto fail_vos_VLDBEntryLock;
      }
--- 2549,2555 ----
  	goto fail_vos_VLDBEntryLock;
      }
  
!     tst = ubik_VL_SetLock(c_handle->vos, 0, volumeId, -1, VLOP_DELETE);
      if (tst != 0) {
  	goto fail_vos_VLDBEntryLock;
      }
***************
*** 2600,2606 ****
  
  
      tst =
! 	ubik_Call(VL_ReleaseLock, c_handle->vos, 0, volumeId, -1,
  		  LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
      if (tst != 0) {
  	goto fail_vos_VLDBEntryUnlock;
--- 2603,2609 ----
  
  
      tst =
! 	ubik_VL_ReleaseLock(c_handle->vos, 0, volumeId, -1,
  		  LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
      if (tst != 0) {
  	goto fail_vos_VLDBEntryUnlock;
***************
*** 3545,3551 ****
       */
  
      if (dest->status == VOS_OK) {
! 	strcpy(dest->name, source->name);
  	dest->id = source->volid;
  	if (source->type == 0) {
  	    dest->type = VOS_READ_WRITE_VOLUME;
--- 3548,3555 ----
       */
  
      if (dest->status == VOS_OK) {
! 	strncpy(dest->name, source->name, VOS_MAX_VOLUME_NAME_LEN);
!         dest->name[VOS_MAX_VOLUME_NAME_LEN - 1] = '\0';
  	dest->id = source->volid;
  	if (source->type == 0) {
  	    dest->type = VOS_READ_WRITE_VOLUME;
Index: openafs/src/libadmin/vos/vosutils.c
diff -c openafs/src/libadmin/vos/vosutils.c:1.12.4.1 openafs/src/libadmin/vos/vosutils.c:1.12.4.2
*** openafs/src/libadmin/vos/vosutils.c:1.12.4.1	Tue Apr  3 09:34:52 2007
--- openafs/src/libadmin/vos/vosutils.c	Sun Jul 15 20:02:18 2007
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/libadmin/vos/vosutils.c,v 1.12.4.1 2007/04/03 13:34:52 jaltman Exp $");
  
  #include "vosutils.h"
  #include "vsprocs.h"
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/libadmin/vos/vosutils.c,v 1.12.4.2 2007/07/16 00:02:18 jaltman Exp $");
  
  #include "vosutils.h"
  #include "vsprocs.h"
***************
*** 108,114 ****
  
      do {
  	if (cellHandle->vos_new) {
! 	    tst = ubik_Call(VL_CreateEntryN, cellHandle->vos, 0, entryp);
  	    if (tst) {
  		if (tst == RXGEN_OPCODE) {
  		    cellHandle->vos_new = 0;
--- 108,114 ----
  
      do {
  	if (cellHandle->vos_new) {
! 	    tst = ubik_VL_CreateEntryN(cellHandle->vos, 0, entryp);
  	    if (tst) {
  		if (tst == RXGEN_OPCODE) {
  		    cellHandle->vos_new = 0;
***************
*** 118,124 ****
  	    }
  	} else {
  	    if (NewVLDB_to_OldVLDB(entryp, &oentry, &tst)) {
! 		tst = ubik_Call(VL_CreateEntry, cellHandle->vos, 0, &oentry);
  		if (!tst) {
  		    rc = 1;
  		}
--- 118,124 ----
  	    }
  	} else {
  	    if (NewVLDB_to_OldVLDB(entryp, &oentry, &tst)) {
! 		tst = ubik_VL_CreateEntry(cellHandle->vos, 0, &oentry);
  		if (!tst) {
  		    rc = 1;
  		}
***************
*** 144,150 ****
      do {
  	if (cellHandle->vos_new) {
  	    tst =
! 		ubik_Call(VL_GetEntryByIDN, cellHandle->vos, 0, volid,
  			  voltype, entryp);
  	    if (tst) {
  		if (tst == RXGEN_OPCODE) {
--- 144,150 ----
      do {
  	if (cellHandle->vos_new) {
  	    tst =
! 		ubik_VL_GetEntryByIDN(cellHandle->vos, 0, volid,
  			  voltype, entryp);
  	    if (tst) {
  		if (tst == RXGEN_OPCODE) {
***************
*** 155,161 ****
  	    }
  	} else {
  	    tst =
! 		ubik_Call(VL_GetEntryByID, cellHandle->vos, 0, volid, voltype,
  			  &oentry);
  	    if (tst == 0) {
  		rc = OldVLDB_to_NewVLDB(&oentry, entryp, &tst);
--- 155,161 ----
  	    }
  	} else {
  	    tst =
! 		ubik_VL_GetEntryByID(cellHandle->vos, 0, volid, voltype,
  			  &oentry);
  	    if (tst == 0) {
  		rc = OldVLDB_to_NewVLDB(&oentry, entryp, &tst);
***************
*** 181,187 ****
      do {
  	if (cellHandle->vos_new) {
  	    tst =
! 		ubik_Call(VL_GetEntryByNameN, cellHandle->vos, 0, namep,
  			  entryp);
  	    if (tst) {
  		if (tst == RXGEN_OPCODE) {
--- 181,187 ----
      do {
  	if (cellHandle->vos_new) {
  	    tst =
! 		ubik_VL_GetEntryByNameN(cellHandle->vos, 0, namep,
  			  entryp);
  	    if (tst) {
  		if (tst == RXGEN_OPCODE) {
***************
*** 192,198 ****
  	    }
  	} else {
  	    tst =
! 		ubik_Call(VL_GetEntryByNameO, cellHandle->vos, 0, namep,
  			  &oentry);
  	    if (tst == 0) {
  		rc = OldVLDB_to_NewVLDB(&oentry, entryp, &tst);
--- 192,198 ----
  	    }
  	} else {
  	    tst =
! 		ubik_VL_GetEntryByNameO(cellHandle->vos, 0, namep,
  			  &oentry);
  	    if (tst == 0) {
  		rc = OldVLDB_to_NewVLDB(&oentry, entryp, &tst);
***************
*** 219,225 ****
      do {
  	if (cellHandle->vos_new) {
  	    tst =
! 		ubik_Call(VL_ReplaceEntryN, cellHandle->vos, 0, volid,
  			  voltype, entryp, releasetype);
  	    if (tst) {
  		if (tst == RXGEN_OPCODE) {
--- 219,225 ----
      do {
  	if (cellHandle->vos_new) {
  	    tst =
! 		ubik_VL_ReplaceEntryN(cellHandle->vos, 0, volid,
  			  voltype, entryp, releasetype);
  	    if (tst) {
  		if (tst == RXGEN_OPCODE) {
***************
*** 231,237 ****
  	} else {
  	    if (NewVLDB_to_OldVLDB(entryp, &oentry, &tst)) {
  		tst =
! 		    ubik_Call(VL_ReplaceEntry, cellHandle->vos, 0, volid,
  			      voltype, &oentry, releasetype);
  		if (!tst) {
  		    rc = 1;
--- 231,237 ----
  	} else {
  	    if (NewVLDB_to_OldVLDB(entryp, &oentry, &tst)) {
  		tst =
! 		    ubik_VL_ReplaceEntry(cellHandle->vos, 0, volid,
  			      voltype, &oentry, releasetype);
  		if (!tst) {
  		    rc = 1;
***************
*** 259,265 ****
      do {
  	if (cellHandle->vos_new) {
  	    tst =
! 		ubik_Call(VL_ListAttributesN, cellHandle->vos, 0, attrp,
  			  entriesp, blkentriesp);
  	    if (tst) {
  		if (tst == RXGEN_OPCODE) {
--- 259,265 ----
      do {
  	if (cellHandle->vos_new) {
  	    tst =
! 		ubik_VL_ListAttributesN(cellHandle->vos, 0, attrp,
  			  entriesp, blkentriesp);
  	    if (tst) {
  		if (tst == RXGEN_OPCODE) {
***************
*** 271,278 ****
  	} else {
  	    memset((void *)&arrayEntries, 0, sizeof(arrayEntries));
  	    tst =
! 		ubik_Call(VL_ListAttributes, cellHandle->vos, 0, attrp,
! 			  entriesp, arrayEntries);
  	    if (tst == 0) {
  		blkentriesp->nbulkentries_val =
  		    (nvldbentry *) malloc(*entriesp * sizeof(*blkentriesp));
--- 271,278 ----
  	} else {
  	    memset((void *)&arrayEntries, 0, sizeof(arrayEntries));
  	    tst =
! 		ubik_VL_ListAttributes(cellHandle->vos, 0, attrp,
! 			  entriesp, &arrayEntries);
  	    if (tst == 0) {
  		blkentriesp->nbulkentries_val =
  		    (nvldbentry *) malloc(*entriesp * sizeof(*blkentriesp));
***************
*** 312,318 ****
      afs_status_t tst = 0;
  
      tst =
! 	ubik_Call(VL_ListAttributesN2, cellHandle->vos, 0, attrp,
  		  (name ? name : ""), thisindex, nentriesp, blkentriesp,
  		  nextindexp);
      if (!tst) {
--- 312,318 ----
      afs_status_t tst = 0;
  
      tst =
! 	ubik_VL_ListAttributesN2(cellHandle->vos, 0, attrp,
  		  (name ? name : ""), thisindex, nentriesp, blkentriesp,
  		  nextindexp);
      if (!tst) {
***************
*** 351,357 ****
      memset(&addrs, 0, sizeof(addrs));
      memset(&uuid, 0, sizeof(uuid));
      tst =
! 	ubik_Call(VL_GetAddrsU, cellHandle->vos, 0, &attrs, &uuid, &unique,
  		  &nentries, &addrs);
      if (tst) {
  	*equal = 0;
--- 351,357 ----
      memset(&addrs, 0, sizeof(addrs));
      memset(&uuid, 0, sizeof(uuid));
      tst =
! 	ubik_VL_GetAddrsU(cellHandle->vos, 0, &attrs, &uuid, &unique,
  		  &nentries, &addrs);
      if (tst) {
  	*equal = 0;
***************
*** 517,523 ****
      char sname[32];
      size_t total;
  
!     strcpy(sname, name);
      total = strlen(sname);
      if ((total > 9) && (!strcmp(&sname[total - 9], ".readonly"))) {
  	/*discard the last 8 chars */
--- 517,524 ----
      char sname[32];
      size_t total;
  
!     strncpy(sname, name, 32);
!     sname[31] ='\0';
      total = strlen(sname);
      if ((total > 9) && (!strcmp(&sname[total - 9], ".readonly"))) {
  	/*discard the last 8 chars */
Index: openafs/src/libadmin/vos/vsprocs.c
diff -c openafs/src/libadmin/vos/vsprocs.c:1.13 openafs/src/libadmin/vos/vsprocs.c:1.13.4.2
*** openafs/src/libadmin/vos/vsprocs.c:1.13	Tue Oct 25 02:30:52 2005
--- openafs/src/libadmin/vos/vsprocs.c	Wed Jul 18 10:22:43 2007
***************
*** 22,28 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/libadmin/vos/vsprocs.c,v 1.13 2005/10/25 06:30:52 shadow Exp $");
  
  #include "vsprocs.h"
  #include "vosutils.h"
--- 22,28 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/libadmin/vos/vsprocs.c,v 1.13.4.2 2007/07/18 14:22:43 shadow Exp $");
  
  #include "vsprocs.h"
  #include "vosutils.h"
***************
*** 150,156 ****
      tstatus.maxquota = quota;
  
      /* next the next 3 available ids from the VLDB */
!     tst = ubik_Call(VL_GetNewVolumeId, cellHandle->vos, 0, 3, volumeId);
      if (tst) {
  	goto fail_UV_CreateVolume;
      }
--- 150,156 ----
      tstatus.maxquota = quota;
  
      /* next the next 3 available ids from the VLDB */
!     tst = ubik_VL_GetNewVolumeId(cellHandle->vos, 0, 3, volumeId);
      if (tst) {
  	goto fail_UV_CreateVolume;
      }
***************
*** 229,235 ****
  
      /* Find and read the VLDB entry for this volume */
      tst =
! 	ubik_Call(VL_SetLock, cellHandle->vos, 0, volumeId, avoltype,
  		  VLOP_DELETE);
      if (tst) {
  	if (tst != VL_NOENT) {
--- 229,235 ----
  
      /* Find and read the VLDB entry for this volume */
      tst =
! 	ubik_VL_SetLock(cellHandle->vos, 0, volumeId, avoltype,
  		  VLOP_DELETE);
      if (tst) {
  	if (tst != VL_NOENT) {
***************
*** 332,338 ****
      }
  
      if ((entry.nServers <= 0) || !(entry.flags & (RO_EXISTS | RW_EXISTS))) {
! 	tst = ubik_Call(VL_DeleteEntry, cellHandle->vos, 0, volumeId, vtype);
  	if (tst) {
  	    goto fail_UV_DeleteVolume;
  	}
--- 332,338 ----
      }
  
      if ((entry.nServers <= 0) || !(entry.flags & (RO_EXISTS | RW_EXISTS))) {
! 	tst = ubik_VL_DeleteEntry(cellHandle->vos, 0, volumeId, vtype);
  	if (tst) {
  	    goto fail_UV_DeleteVolume;
  	}
***************
*** 364,370 ****
  
      if (islocked) {
  	temp =
! 	    ubik_Call(VL_ReleaseLock, cellHandle->vos, 0, volumeId, -1,
  		      (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
  	if (temp) {
  	    if (!tst)
--- 364,370 ----
  
      if (islocked) {
  	temp =
! 	    ubik_VL_ReleaseLock(cellHandle->vos, 0, volumeId, -1,
  		      (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
  	if (temp) {
  	    if (!tst)
***************
*** 437,443 ****
      }
  
      tst =
! 	ubik_Call(VL_SetLock, cellHandle->vos, 0, afromvol, RWVOL, VLOP_MOVE);
      if (tst) {
  	goto fail_UV_MoveVolume;
      }
--- 437,443 ----
      }
  
      tst =
! 	ubik_VL_SetLock(cellHandle->vos, 0, afromvol, RWVOL, VLOP_MOVE);
      if (tst) {
  	goto fail_UV_MoveVolume;
      }
***************
*** 454,460 ****
  	if (!Lp_Match(cellHandle, &entry, atoserver, atopart, &tst)) {
  	    /* the to server and partition do not exist in the vldb entry corresponding to volid */
  	    tst =
! 		ubik_Call(VL_ReleaseLock, cellHandle->vos, 0, afromvol, -1,
  			  (LOCKREL_OPCODE | LOCKREL_AFSID |
  			   LOCKREL_TIMESTAMP));
  	    if (tst) {
--- 454,460 ----
  	if (!Lp_Match(cellHandle, &entry, atoserver, atopart, &tst)) {
  	    /* the to server and partition do not exist in the vldb entry corresponding to volid */
  	    tst =
! 		ubik_VL_ReleaseLock(cellHandle->vos, 0, afromvol, -1,
  			  (LOCKREL_OPCODE | LOCKREL_AFSID |
  			   LOCKREL_TIMESTAMP));
  	    if (tst) {
***************
*** 561,567 ****
  
      /* Get a clone id */
      newVol = 0;
!     tst = ubik_Call(VL_GetNewVolumeId, cellHandle->vos, 0, 1, &newVol);
      if (tst) {
  	goto fail_UV_MoveVolume;
      }
--- 561,567 ----
  
      /* Get a clone id */
      newVol = 0;
!     tst = ubik_VL_GetNewVolumeId(cellHandle->vos, 0, 1, &newVol);
      if (tst) {
  	goto fail_UV_MoveVolume;
      }
***************
*** 824,830 ****
  
      if (islocked) {
  	etst =
! 	    ubik_Call(VL_ReleaseLock, cellHandle->vos, 0, afromvol, -1,
  		      (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
  	if (etst) {
  	    if (!tst)
--- 824,830 ----
  
      if (islocked) {
  	etst =
! 	    ubik_VL_ReleaseLock(cellHandle->vos, 0, afromvol, -1,
  		      (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
  	if (etst) {
  	    if (!tst)
***************
*** 878,884 ****
  
      /* unlock VLDB entry */
      if (islocked)
! 	ubik_Call(VL_ReleaseLock, cellHandle->vos, 0, afromvol, -1,
  		  (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
  
      if (clonetid)
--- 878,884 ----
  
      /* unlock VLDB entry */
      if (islocked)
! 	ubik_VL_ReleaseLock(cellHandle->vos, 0, afromvol, -1,
  		  (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
  
      if (clonetid)
***************
*** 962,968 ****
      }
  
      /* unlock VLDB entry */
!     ubik_Call(VL_ReleaseLock, cellHandle->vos, 0, afromvol, -1,
  	      (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
  
    done:			/* routine cleanup */
--- 962,968 ----
      }
  
      /* unlock VLDB entry */
!     ubik_VL_ReleaseLock(cellHandle->vos, 0, afromvol, -1,
  	      (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
  
    done:			/* routine cleanup */
***************
*** 1018,1024 ****
  	/* no assigned backup volume id */
  
  	tst =
! 	    ubik_Call(VL_SetLock, cellHandle->vos, 0, avolid, RWVOL,
  		      VLOP_BACKUP);
  	if (tst) {
  	    goto fail_UV_BackupVolume;
--- 1018,1024 ----
  	/* no assigned backup volume id */
  
  	tst =
! 	    ubik_VL_SetLock(cellHandle->vos, 0, avolid, RWVOL,
  		      VLOP_BACKUP);
  	if (tst) {
  	    goto fail_UV_BackupVolume;
***************
*** 1041,1047 ****
  	/* Get a backup volume id from the VLDB and update the vldb
  	 * entry with it. 
  	 */
! 	tst = ubik_Call(VL_GetNewVolumeId, cellHandle->vos, 0, 1, &backupID);
  	if (tst) {
  	    goto fail_UV_BackupVolume;
  	}
--- 1041,1047 ----
  	/* Get a backup volume id from the VLDB and update the vldb
  	 * entry with it. 
  	 */
! 	tst = ubik_VL_GetNewVolumeId(cellHandle->vos, 0, 1, &backupID);
  	if (tst) {
  	    goto fail_UV_BackupVolume;
  	}
***************
*** 1160,1166 ****
  	    }
  	} else {
  	    temp =
! 		ubik_Call(VL_ReleaseLock, cellHandle->vos, 0, avolid, RWVOL,
  			  (LOCKREL_OPCODE | LOCKREL_AFSID |
  			   LOCKREL_TIMESTAMP));
  	    if (temp) {
--- 1160,1166 ----
  	    }
  	} else {
  	    temp =
! 		ubik_VL_ReleaseLock(cellHandle->vos, 0, avolid, RWVOL,
  			  (LOCKREL_OPCODE | LOCKREL_AFSID |
  			   LOCKREL_TIMESTAMP));
  	    if (temp) {
***************
*** 1223,1229 ****
      /* Get the RO volume id. Allocate a new one if need to */
      *rovidp = entry->volumeId[ROVOL];
      if (*rovidp == INVALID_BID) {
! 	tst = ubik_Call(VL_GetNewVolumeId, cellHandle->vos, 0, 1, rovidp);
  	if (tst) {
  	    goto fail_CloneVol;
  	}
--- 1223,1229 ----
      /* Get the RO volume id. Allocate a new one if need to */
      *rovidp = entry->volumeId[ROVOL];
      if (*rovidp == INVALID_BID) {
! 	tst = ubik_VL_GetNewVolumeId(cellHandle->vos, 0, 1, rovidp);
  	if (tst) {
  	    goto fail_CloneVol;
  	}
***************
*** 1495,1501 ****
      memset((char *)&results, 0, sizeof(results));
  
      tst =
! 	ubik_Call(VL_SetLock, cellHandle->vos, 0, afromvol, RWVOL,
  		  VLOP_RELEASE);
      if ((tst) && (tst != VL_RERELEASE)) {
  	goto fail_UV_ReleaseVolume;
--- 1495,1501 ----
      memset((char *)&results, 0, sizeof(results));
  
      tst =
! 	ubik_VL_SetLock(cellHandle->vos, 0, afromvol, RWVOL,
  		  VLOP_RELEASE);
      if ((tst) && (tst != VL_RERELEASE)) {
  	goto fail_UV_ReleaseVolume;
***************
*** 1544,1550 ****
      /* Make sure we have a RO volume id to work with */
      if (entry.volumeId[ROVOL] == INVALID_BID) {
  	/* need to get a new RO volume id */
! 	tst = ubik_Call(VL_GetNewVolumeId, cellHandle->vos, 0, 1, &roVolId);
  	if (tst) {
  	    goto fail_UV_ReleaseVolume;
  	}
--- 1544,1550 ----
      /* Make sure we have a RO volume id to work with */
      if (entry.volumeId[ROVOL] == INVALID_BID) {
  	/* need to get a new RO volume id */
! 	tst = ubik_VL_GetNewVolumeId(cellHandle->vos, 0, 1, &roVolId);
  	if (tst) {
  	    goto fail_UV_ReleaseVolume;
  	}
***************
*** 1969,1975 ****
      }
      if (islocked) {
  	tst =
! 	    ubik_Call(VL_ReleaseLock, cellHandle->vos, 0, afromvol, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (tst) {
  	    rc = 0;
--- 1969,1975 ----
      }
      if (islocked) {
  	tst =
! 	    ubik_VL_ReleaseLock(cellHandle->vos, 0, afromvol, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (tst) {
  	    rc = 0;
***************
*** 2154,2160 ****
  
      if (islocked) {
  	etst =
! 	    ubik_Call(VL_ReleaseLock, cellHandle->vos, 0, afromvol, -1,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (etst) {
  	    if (!tst)
--- 2154,2160 ----
  
      if (islocked) {
  	etst =
! 	    ubik_VL_ReleaseLock(cellHandle->vos, 0, afromvol, -1,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (etst) {
  	    if (!tst)
***************
*** 2332,2338 ****
  	aVLDB_GetEntryByName(cellHandle, tovolname, &entry, &tst);
  	if (tst == VL_NOENT) {
  	    tst =
! 		ubik_Call(VL_GetNewVolumeId, cellHandle->vos, 0, 1, &pvolid);
  	    if (tst) {
  		goto fail_UV_RestoreVolume;
  	    }
--- 2332,2338 ----
  	aVLDB_GetEntryByName(cellHandle, tovolname, &entry, &tst);
  	if (tst == VL_NOENT) {
  	    tst =
! 		ubik_VL_GetNewVolumeId(cellHandle->vos, 0, 1, &pvolid);
  	    if (tst) {
  		goto fail_UV_RestoreVolume;
  	    }
***************
*** 2479,2485 ****
  	    islocked = 0;
  	} else {		/*update the existing entry */
  	    tst =
! 		ubik_Call(VL_SetLock, cellHandle->vos, 0, pvolid, RWVOL,
  			  VLOP_RESTORE);
  	    if (tst) {
  		goto fail_UV_RestoreVolume;
--- 2479,2485 ----
  	    islocked = 0;
  	} else {		/*update the existing entry */
  	    tst =
! 		ubik_VL_SetLock(cellHandle->vos, 0, pvolid, RWVOL,
  			  VLOP_RESTORE);
  	    if (tst) {
  		goto fail_UV_RestoreVolume;
***************
*** 2557,2563 ****
      }
      if (islocked) {
  	etst =
! 	    ubik_Call(VL_ReleaseLock, cellHandle->vos, 0, pvolid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (etst) {
  	    if (!tst)
--- 2557,2563 ----
      }
      if (islocked) {
  	etst =
! 	    ubik_VL_ReleaseLock(cellHandle->vos, 0, pvolid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (etst) {
  	    if (!tst)
***************
*** 2607,2613 ****
      int same = 0;
  
      tst =
! 	ubik_Call(VL_SetLock, cellHandle->vos, 0, volid, RWVOL, VLOP_ADDSITE);
      if (tst) {
  	goto fail_UV_AddSite;
      }
--- 2607,2613 ----
      int same = 0;
  
      tst =
! 	ubik_VL_SetLock(cellHandle->vos, 0, volid, RWVOL, VLOP_ADDSITE);
      if (tst) {
  	goto fail_UV_AddSite;
      }
***************
*** 2665,2671 ****
  
      if (islocked) {
  	tst =
! 	    ubik_Call(VL_ReleaseLock, cellHandle->vos, 0, volid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
      }
  
--- 2665,2671 ----
  
      if (islocked) {
  	tst =
! 	    ubik_VL_ReleaseLock(cellHandle->vos, 0, volid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
      }
  
***************
*** 2686,2692 ****
      int islocked = 0;
  
      tst =
! 	ubik_Call(VL_SetLock, cellHandle->vos, 0, volid, RWVOL, VLOP_ADDSITE);
      if (tst) {
  	goto fail_UV_RemoveSite;
      }
--- 2686,2692 ----
      int islocked = 0;
  
      tst =
! 	ubik_VL_SetLock(cellHandle->vos, 0, volid, RWVOL, VLOP_ADDSITE);
      if (tst) {
  	goto fail_UV_RemoveSite;
      }
***************
*** 2704,2710 ****
  	if ((entry.nServers == 1) && (entry.flags & RW_EXISTS))
  	    entry.flags &= ~RO_EXISTS;
  	if (entry.nServers < 1) {	/*this is the last ref */
! 	    tst = ubik_Call(VL_DeleteEntry, cellHandle->vos, 0, volid, ROVOL);
  	    if (tst) {
  		goto fail_UV_RemoveSite;
  	    }
--- 2704,2710 ----
  	if ((entry.nServers == 1) && (entry.flags & RW_EXISTS))
  	    entry.flags &= ~RO_EXISTS;
  	if (entry.nServers < 1) {	/*this is the last ref */
! 	    tst = ubik_VL_DeleteEntry(cellHandle->vos, 0, volid, ROVOL);
  	    if (tst) {
  		goto fail_UV_RemoveSite;
  	    }
***************
*** 2721,2727 ****
  
      if (islocked) {
  	afs_status_t t;
! 	t = ubik_Call(VL_ReleaseLock, cellHandle->vos, 0, volid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (tst == 0) {
  	    tst = t;
--- 2721,2727 ----
  
      if (islocked) {
  	afs_status_t t;
! 	t = ubik_VL_ReleaseLock(cellHandle->vos, 0, volid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (tst == 0) {
  	    tst = t;
***************
*** 3017,3023 ****
      counter = 0;
  
      /* get the next  available id's from the vldb server */
!     vcode = ubik_Call(VL_GetNewVolumeId, cellHandle->vos, 0, 0, &maxVolid);
      if (vcode) {
  	return (vcode);
      }
--- 3017,3023 ----
      counter = 0;
  
      /* get the next  available id's from the vldb server */
!     vcode = ubik_VL_GetNewVolumeId(cellHandle->vos, 0, 0, &maxVolid);
      if (vcode) {
  	return (vcode);
      }
***************
*** 3039,3045 ****
  	    temp2 = elem.ids[RWVOL] - maxVolid + 1;
  	    maxVolid = 0;
  	    vcode =
! 		ubik_Call(VL_GetNewVolumeId, cellHandle->vos, 0, temp2,
  			  &maxVolid);
  	    maxVolid += temp2;
  
--- 3039,3045 ----
  	    temp2 = elem.ids[RWVOL] - maxVolid + 1;
  	    maxVolid = 0;
  	    vcode =
! 		ubik_VL_GetNewVolumeId(cellHandle->vos, 0, temp2,
  			  &maxVolid);
  	    maxVolid += temp2;
  
***************
*** 3051,3057 ****
  	    temp2 = elem.ids[ROVOL] - maxVolid + 1;
  	    maxVolid = 0;
  	    vcode =
! 		ubik_Call(VL_GetNewVolumeId, cellHandle->vos, 0, temp2,
  			  &maxVolid);
  	    maxVolid += temp2;
  
--- 3051,3057 ----
  	    temp2 = elem.ids[ROVOL] - maxVolid + 1;
  	    maxVolid = 0;
  	    vcode =
! 		ubik_VL_GetNewVolumeId(cellHandle->vos, 0, temp2,
  			  &maxVolid);
  	    maxVolid += temp2;
  
***************
*** 3061,3067 ****
  	    temp2 = elem.ids[BACKVOL] - temp1 + 1;
  	    maxVolid = 0;
  	    vcode =
! 		ubik_Call(VL_GetNewVolumeId, cellHandle->vos, 0, temp2,
  			  &maxVolid);
  	    maxVolid += temp2;
  
--- 3061,3067 ----
  	    temp2 = elem.ids[BACKVOL] - temp1 + 1;
  	    maxVolid = 0;
  	    vcode =
! 		ubik_VL_GetNewVolumeId(cellHandle->vos, 0, temp2,
  			  &maxVolid);
  	    maxVolid += temp2;
  
***************
*** 3248,3254 ****
  		totalUE++;
  
  		vcode =
! 		    ubik_Call(VL_ReleaseLock, cellHandle->vos, 0,
  			      elem.ids[RWVOL], RWVOL,
  			      LOCKREL_OPCODE | LOCKREL_AFSID |
  			      LOCKREL_TIMESTAMP);
--- 3248,3254 ----
  		totalUE++;
  
  		vcode =
! 		    ubik_VL_ReleaseLock(cellHandle->vos, 0,
  			      elem.ids[RWVOL], RWVOL,
  			      LOCKREL_OPCODE | LOCKREL_AFSID |
  			      LOCKREL_TIMESTAMP);
***************
*** 3548,3554 ****
       */
      if (++pass == 2) {
  	tst =
! 	    ubik_Call(VL_SetLock, cellHandle->vos, 0, entry->volumeId[RWVOL],
  		      RWVOL, VLOP_DELETE);
  	if (tst) {
  	    goto fail_CheckVldb;
--- 3548,3554 ----
       */
      if (++pass == 2) {
  	tst =
! 	    ubik_VL_SetLock(cellHandle->vos, 0, entry->volumeId[RWVOL],
  		      RWVOL, VLOP_DELETE);
  	if (tst) {
  	    goto fail_CheckVldb;
***************
*** 3588,3594 ****
  	    && !(entry->flags & RO_EXISTS)) {
  	    /* The RW, BK, nor RO volumes do not exist. Delete the VLDB entry */
  	    tst =
! 		ubik_Call(VL_DeleteEntry, cellHandle->vos, 0,
  			  entry->volumeId[RWVOL], RWVOL);
  	    if (tst) {
  		goto fail_CheckVldb;
--- 3588,3594 ----
  	    && !(entry->flags & RO_EXISTS)) {
  	    /* The RW, BK, nor RO volumes do not exist. Delete the VLDB entry */
  	    tst =
! 		ubik_VL_DeleteEntry(cellHandle->vos, 0,
  			  entry->volumeId[RWVOL], RWVOL);
  	    if (tst) {
  		goto fail_CheckVldb;
***************
*** 3613,3622 ****
  
      if (islocked) {
  	vcode =
! 	    ubik_Call(VL_ReleaseLock, cellHandle->vos, 0,
! 		      entry->volumeId[RWVOL], RWVOL,
! 		      (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP),
! 		      &tst);
  	if (vcode) {
  	    if (!tst)
  		tst = vcode;
--- 3613,3621 ----
  
      if (islocked) {
  	vcode =
! 	    ubik_VL_ReleaseLock(cellHandle->vos, 0,
! 				entry->volumeId[RWVOL], RWVOL,
! 				(LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
  	if (vcode) {
  	    if (!tst)
  		tst = vcode;
***************
*** 3721,3727 ****
      tid = 0;
      islocked = 0;
  
!     tst = ubik_Call(VL_SetLock, cellHandle->vos, 0, entry->volumeId[RWVOL], RWVOL, VLOP_ADDSITE);	/*last param is dummy */
      if (tst) {
  	goto fail_UV_RenameVolume;
      }
--- 3720,3726 ----
      tid = 0;
      islocked = 0;
  
!     tst = ubik_VL_SetLock(cellHandle->vos, 0, entry->volumeId[RWVOL], RWVOL, VLOP_ADDSITE);	/*last param is dummy */
      if (tst) {
  	goto fail_UV_RenameVolume;
      }
***************
*** 3853,3859 ****
  
      if (islocked) {
  	etst =
! 	    ubik_Call(VL_ReleaseLock, cellHandle->vos, 0,
  		      entry->volumeId[RWVOL], RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (etst) {
--- 3852,3858 ----
  
      if (islocked) {
  	etst =
! 	    ubik_VL_ReleaseLock(cellHandle->vos, 0,
  		      entry->volumeId[RWVOL], RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (etst) {
Index: openafs/src/libafs/afs.ppc_darwin_70.plist.in
diff -c openafs/src/libafs/afs.ppc_darwin_70.plist.in:1.2.10.17 openafs/src/libafs/afs.ppc_darwin_70.plist.in:1.2.10.18
*** openafs/src/libafs/afs.ppc_darwin_70.plist.in:1.2.10.17	Wed Jul 11 00:36:17 2007
--- openafs/src/libafs/afs.ppc_darwin_70.plist.in	Thu Aug  9 23:26:55 2007
***************
*** 15,25 ****
  	<key>CFBundlePackageType</key>
  	<string>KEXT</string>
  	<key>CFBundleShortVersionString</key>
! 	<string>1.5.21</string>
  	<key>CFBundleSignature</key>
  	<string>????</string>
  	<key>CFBundleVersion</key>
! 	<string>1.5.21</string>
  	<key>OSBundleLibraries</key>
  	<dict>
  		<key>com.apple.kernel.bsd</key>
--- 15,25 ----
  	<key>CFBundlePackageType</key>
  	<string>KEXT</string>
  	<key>CFBundleShortVersionString</key>
! 	<string>1.5.22</string>
  	<key>CFBundleSignature</key>
  	<string>????</string>
  	<key>CFBundleVersion</key>
! 	<string>1.5.22</string>
  	<key>OSBundleLibraries</key>
  	<dict>
  		<key>com.apple.kernel.bsd</key>
Index: openafs/src/libafs/afs.ppc_darwin_80.plist.in
diff -c openafs/src/libafs/afs.ppc_darwin_80.plist.in:1.2.4.17 openafs/src/libafs/afs.ppc_darwin_80.plist.in:1.2.4.18
*** openafs/src/libafs/afs.ppc_darwin_80.plist.in:1.2.4.17	Wed Jul 11 00:36:17 2007
--- openafs/src/libafs/afs.ppc_darwin_80.plist.in	Thu Aug  9 23:26:55 2007
***************
*** 15,25 ****
  	<key>CFBundlePackageType</key>
  	<string>KEXT</string>
  	<key>CFBundleShortVersionString</key>
! 	<string>1.5.21</string>
  	<key>CFBundleSignature</key>
  	<string>????</string>
  	<key>CFBundleVersion</key>
! 	<string>1.5.21</string>
  	<key>OSBundleLibraries</key>
  	<dict>
  		<key>com.apple.kpi.bsd</key>
--- 15,25 ----
  	<key>CFBundlePackageType</key>
  	<string>KEXT</string>
  	<key>CFBundleShortVersionString</key>
! 	<string>1.5.22</string>
  	<key>CFBundleSignature</key>
  	<string>????</string>
  	<key>CFBundleVersion</key>
! 	<string>1.5.22</string>
  	<key>OSBundleLibraries</key>
  	<dict>
  		<key>com.apple.kpi.bsd</key>
Index: openafs/src/libafs/afs.ppc_darwin_90.plist.in
diff -c openafs/src/libafs/afs.ppc_darwin_90.plist.in:1.1.6.17 openafs/src/libafs/afs.ppc_darwin_90.plist.in:1.1.6.18
*** openafs/src/libafs/afs.ppc_darwin_90.plist.in:1.1.6.17	Wed Jul 11 00:36:17 2007
--- openafs/src/libafs/afs.ppc_darwin_90.plist.in	Thu Aug  9 23:26:55 2007
***************
*** 15,25 ****
  	<key>CFBundlePackageType</key>
  	<string>KEXT</string>
  	<key>CFBundleShortVersionString</key>
! 	<string>1.5.21</string>
  	<key>CFBundleSignature</key>
  	<string>????</string>
  	<key>CFBundleVersion</key>
! 	<string>1.5.21</string>
  	<key>OSBundleLibraries</key>
  	<dict>
  		<key>com.apple.kpi.bsd</key>
--- 15,25 ----
  	<key>CFBundlePackageType</key>
  	<string>KEXT</string>
  	<key>CFBundleShortVersionString</key>
! 	<string>1.5.22</string>
  	<key>CFBundleSignature</key>
  	<string>????</string>
  	<key>CFBundleVersion</key>
! 	<string>1.5.22</string>
  	<key>OSBundleLibraries</key>
  	<dict>
  		<key>com.apple.kpi.bsd</key>
Index: openafs/src/libafs/afs.x86_darwin_80.plist.in
diff -c openafs/src/libafs/afs.x86_darwin_80.plist.in:1.1.6.17 openafs/src/libafs/afs.x86_darwin_80.plist.in:1.1.6.18
*** openafs/src/libafs/afs.x86_darwin_80.plist.in:1.1.6.17	Wed Jul 11 00:36:17 2007
--- openafs/src/libafs/afs.x86_darwin_80.plist.in	Thu Aug  9 23:26:55 2007
***************
*** 15,25 ****
  	<key>CFBundlePackageType</key>
  	<string>KEXT</string>
  	<key>CFBundleShortVersionString</key>
! 	<string>1.5.21</string>
  	<key>CFBundleSignature</key>
  	<string>????</string>
  	<key>CFBundleVersion</key>
! 	<string>1.5.21</string>
  	<key>OSBundleLibraries</key>
  	<dict>
  		<key>com.apple.kpi.bsd</key>
--- 15,25 ----
  	<key>CFBundlePackageType</key>
  	<string>KEXT</string>
  	<key>CFBundleShortVersionString</key>
! 	<string>1.5.22</string>
  	<key>CFBundleSignature</key>
  	<string>????</string>
  	<key>CFBundleVersion</key>
! 	<string>1.5.22</string>
  	<key>OSBundleLibraries</key>
  	<dict>
  		<key>com.apple.kpi.bsd</key>
Index: openafs/src/libafs/afs.x86_darwin_90.plist.in
diff -c openafs/src/libafs/afs.x86_darwin_90.plist.in:1.1.6.17 openafs/src/libafs/afs.x86_darwin_90.plist.in:1.1.6.18
*** openafs/src/libafs/afs.x86_darwin_90.plist.in:1.1.6.17	Wed Jul 11 00:36:17 2007
--- openafs/src/libafs/afs.x86_darwin_90.plist.in	Thu Aug  9 23:26:55 2007
***************
*** 15,25 ****
  	<key>CFBundlePackageType</key>
  	<string>KEXT</string>
  	<key>CFBundleShortVersionString</key>
! 	<string>1.5.21</string>
  	<key>CFBundleSignature</key>
  	<string>????</string>
  	<key>CFBundleVersion</key>
! 	<string>1.5.21</string>
  	<key>OSBundleLibraries</key>
  	<dict>
  		<key>com.apple.kpi.bsd</key>
--- 15,25 ----
  	<key>CFBundlePackageType</key>
  	<string>KEXT</string>
  	<key>CFBundleShortVersionString</key>
! 	<string>1.5.22</string>
  	<key>CFBundleSignature</key>
  	<string>????</string>
  	<key>CFBundleVersion</key>
! 	<string>1.5.22</string>
  	<key>OSBundleLibraries</key>
  	<dict>
  		<key>com.apple.kpi.bsd</key>
Index: openafs/src/libafsrpc/NTMakefile
diff -c openafs/src/libafsrpc/NTMakefile:1.11.4.1 openafs/src/libafsrpc/NTMakefile:1.11.4.2
*** openafs/src/libafsrpc/NTMakefile:1.11.4.1	Tue Jul  4 02:28:25 2006
--- openafs/src/libafsrpc/NTMakefile	Thu Aug  2 01:21:36 2007
***************
*** 39,45 ****
  LIBRXKAD_OBJS = $(OUT)\rxkad_client.obj $(OUT)\rxkad_server.obj $(OUT)\rxkad_common.obj $(OUT)\ticket.obj \
  	$(OUT)\ticket5.obj $(OUT)\crc.obj $(OUT)\md4.obj $(OUT)\md5.obj $(OUT)\AFS_component_version_number.obj
  
! LIBRXKAD_REGOBJS = $(OUT)\fcrypt.obj $(OUT)\crypt_conn.obj
  
  DESOBJS_INT = $(OUT)\des.obj $(OUT)\cbc_encrypt.obj $(OUT)\pcbc_encrypt.obj $(OUT)\cksum.obj $(OUT)\new_rnd_key.obj \
  	$(OUT)\key_sched.obj $(OUT)\debug_decl.obj $(OUT)\quad_cksum.obj $(OUT)\key_parity.obj \
--- 39,45 ----
  LIBRXKAD_OBJS = $(OUT)\rxkad_client.obj $(OUT)\rxkad_server.obj $(OUT)\rxkad_common.obj $(OUT)\ticket.obj \
  	$(OUT)\ticket5.obj $(OUT)\crc.obj $(OUT)\md4.obj $(OUT)\md5.obj $(OUT)\AFS_component_version_number.obj
  
! LIBRXKAD_REGOBJS = $(OUT)\bg-fcrypt.obj
  
  DESOBJS_INT = $(OUT)\des.obj $(OUT)\cbc_encrypt.obj $(OUT)\pcbc_encrypt.obj $(OUT)\cksum.obj $(OUT)\new_rnd_key.obj \
  	$(OUT)\key_sched.obj $(OUT)\debug_decl.obj $(OUT)\quad_cksum.obj $(OUT)\key_parity.obj \
Index: openafs/src/lwp/process.c
diff -c openafs/src/lwp/process.c:1.23.2.1 openafs/src/lwp/process.c:1.23.2.2
*** openafs/src/lwp/process.c:1.23.2.1	Wed May 16 16:22:30 2007
--- openafs/src/lwp/process.c	Mon Jul 16 23:12:36 2007
***************
*** 13,19 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/lwp/process.c,v 1.23.2.1 2007/05/16 20:22:30 shadow Exp $");
  
  #include <stdio.h>
  #include <assert.h>
--- 13,19 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/lwp/process.c,v 1.23.2.2 2007/07/17 03:12:36 shadow Exp $");
  
  #include <stdio.h>
  #include <assert.h>
***************
*** 151,157 ****
  #ifdef __GLIBC__
  #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 3)
  
! #ifdef AFS_SPARC64_LINUX24_ENV
  #undef ptr_mangle
  static int ptr_mangle(int p)
  {   
--- 151,161 ----
  #ifdef __GLIBC__
  #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 3)
  
! #if defined(AFS_SPARC64_LINUX24_ENV) || defined(AFS_SPARC_LINUX24_ENV)
! /* technically we should use POINTER_GUARD 
!  * ( == offsetof (tcbhead_t, pointer_guard) )
!  * instead of 0x18
!  */
  #undef ptr_mangle
  static int ptr_mangle(int p)
  {   
Index: openafs/src/packaging/MacOS/OpenAFS.Info.plist
diff -c openafs/src/packaging/MacOS/OpenAFS.Info.plist:1.2.10.18 openafs/src/packaging/MacOS/OpenAFS.Info.plist:1.2.10.19
*** openafs/src/packaging/MacOS/OpenAFS.Info.plist:1.2.10.18	Wed Jul 11 00:36:19 2007
--- openafs/src/packaging/MacOS/OpenAFS.Info.plist	Thu Aug  9 23:26:56 2007
***************
*** 3,15 ****
  <plist version="1.0">
  <dict>
  	<key>CFBundleGetInfoString</key>
! 	<string>OpenAFS 1.5.21</string>
  	<key>CFBundleIdentifier</key>
  	<string>org.openafs.OpenAFS.pkg</string>
  	<key>CFBundleName</key>
  	<string>OpenAFS</string>
  	<key>CFBundleShortVersionString</key>
! 	<string>1.5.21</string>
  	<key>IFMajorVersion</key>
  	<integer>1</integer>
  	<key>IFMinorVersion</key>
--- 3,15 ----
  <plist version="1.0">
  <dict>
  	<key>CFBundleGetInfoString</key>
! 	<string>OpenAFS 1.5.22</string>
  	<key>CFBundleIdentifier</key>
  	<string>org.openafs.OpenAFS.pkg</string>
  	<key>CFBundleName</key>
  	<string>OpenAFS</string>
  	<key>CFBundleShortVersionString</key>
! 	<string>1.5.22</string>
  	<key>IFMajorVersion</key>
  	<integer>1</integer>
  	<key>IFMinorVersion</key>
Index: openafs/src/packaging/MacOS/OpenAFS.info
diff -c openafs/src/packaging/MacOS/OpenAFS.info:1.1.12.17 openafs/src/packaging/MacOS/OpenAFS.info:1.1.12.18
*** openafs/src/packaging/MacOS/OpenAFS.info:1.1.12.17	Wed Jul 11 00:36:19 2007
--- openafs/src/packaging/MacOS/OpenAFS.info	Thu Aug  9 23:26:56 2007
***************
*** 1,5 ****
  Title OpenAFS
! Version 1.5.21
  Description The OpenAFS distributed filesystem. This package installs an almost-ready-to-run client for OpenAFS. see http://www.openafs.org for more information.
  DefaultLocation /
  Diskname (null)
--- 1,5 ----
  Title OpenAFS
! Version 1.5.22
  Description The OpenAFS distributed filesystem. This package installs an almost-ready-to-run client for OpenAFS. see http://www.openafs.org for more information.
  DefaultLocation /
  Diskname (null)
Index: openafs/src/rxkad/bg-fcrypt.c
diff -c openafs/src/rxkad/bg-fcrypt.c:1.7.4.1 openafs/src/rxkad/bg-fcrypt.c:1.7.4.3
*** openafs/src/rxkad/bg-fcrypt.c:1.7.4.1	Wed Aug  2 15:01:22 2006
--- openafs/src/rxkad/bg-fcrypt.c	Tue Jul 31 18:20:59 2007
***************
*** 38,44 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/bg-fcrypt.c,v 1.7.4.1 2006/08/02 19:01:22 shadow Exp $");
  
  #define DEBUG 0
  #ifdef KERNEL
--- 38,44 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/bg-fcrypt.c,v 1.7.4.3 2007/07/31 22:20:59 shadow Exp $");
  
  #define DEBUG 0
  #ifdef KERNEL
***************
*** 550,557 ****
      const unsigned char *key = key_;
  
      /* Do we have 56 bit longs or even longer longs? */
! #if ((1ul << 31) << 1) && defined(ULONG_MAX) && ((ULONG_MAX >> 55) != 0) && ((1ul << 55) != 0)
!     unsigned long k;		/* k holds all 56 non parity bits */
  
      /* Compress out parity bits */
      k = (*key++) >> 1;
--- 550,557 ----
      const unsigned char *key = key_;
  
      /* Do we have 56 bit longs or even longer longs? */
! #ifdef AFS_64BIT_ENV
!     afs_uint64 k;		/* k holds all 56 non parity bits */
  
      /* Compress out parity bits */
      k = (*key++) >> 1;
Index: openafs/src/sys/pioctl_nt.c
diff -c openafs/src/sys/pioctl_nt.c:1.34.4.6 openafs/src/sys/pioctl_nt.c:1.34.4.7
*** openafs/src/sys/pioctl_nt.c:1.34.4.6	Wed Jun 27 23:40:14 2007
--- openafs/src/sys/pioctl_nt.c	Wed Jul 18 09:03:44 2007
***************
*** 35,41 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/sys/pioctl_nt.c,v 1.34.4.6 2007/06/28 03:40:14 jaltman Exp $");
  
  #include <afs/stds.h>
  #include <windows.h>
--- 35,41 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/sys/pioctl_nt.c,v 1.34.4.7 2007/07/18 13:03:44 jaltman Exp $");
  
  #include <afs/stds.h>
  #include <windows.h>
***************
*** 53,65 ****
  #include <osi.h>
  
  #include <cm.h>
- #include <cm_dir.h>
  #include <cm_server.h>
  #include <cm_cell.h>
  #include <cm_user.h>
  #include <cm_conn.h>
  #include <cm_scache.h>
  #include <cm_buf.h>
  #include <cm_utils.h>
  #include <cm_ioctl.h>
  
--- 53,65 ----
  #include <osi.h>
  
  #include <cm.h>
  #include <cm_server.h>
  #include <cm_cell.h>
  #include <cm_user.h>
  #include <cm_conn.h>
  #include <cm_scache.h>
  #include <cm_buf.h>
+ #include <cm_dir.h>
  #include <cm_utils.h>
  #include <cm_ioctl.h>
  
Index: openafs/src/tsm41/Makefile.in
diff -c openafs/src/tsm41/Makefile.in:1.8.2.1 openafs/src/tsm41/Makefile.in:1.8.2.2
*** openafs/src/tsm41/Makefile.in:1.8.2.1	Thu Jul 13 13:23:29 2006
--- openafs/src/tsm41/Makefile.in	Fri Jul 13 15:55:00 2007
***************
*** 48,53 ****
--- 48,56 ----
  		aix_auth_common.o \
  		aix_ktc_null.o
  
+ AUTH_KRB5_OBJS = \
+ 		aix_aklog.o 
+ 
  AUTH_KRB_OBJS = \
  		aix_auth.o \
  		aix_ident.o \
***************
*** 56,65 ****
--- 59,70 ----
  
  AUTHLIBS= \
  		afs_dynamic_auth \
+ 		aklog_dynamic_auth \
  		afs_dynamic_kerbauth
  
  IMPORTS = -bI:/lib/aio.exp -bI:/lib/netinet.exp -bI:/lib/sockets.exp -bI:/lib/statcmd.exp 
  LDFLAGS = -eafs_initialize ${IMPORTS} -lsys -lcsys -lc
+ AKLDFLAGS = -eaklog_initialize ${IMPORTS} -lsys -lcsys -lc
  
  all: $(AUTHLIBS)
  
***************
*** 71,82 ****
--- 76,93 ----
  afs_dynamic_auth: ${AUTH_OBJS} ${AFSLIBS} ${AUTHFILES}
  	$(LD) -o $@ ${AUTH_OBJS} $(AFSLIBS) ${AUTHFILES} ${XLIBS} ${LDFLAGS}
  
+ aklog_dynamic_auth: ${AUTH_KRB5_OBJS} ${AFSLIBS} ${AUTHFILES}
+ 	$(LD) -o $@ ${AUTH_KRB5_OBJS} $(AFSLIBS) ${AUTHFILES} @KRB5LIBS@ ${XLIBS} ${AKLDFLAGS}
+ 
  afs_dynamic_kerbauth: ${AUTH_KRB_OBJS} ${KAFSLIBS} ${AUTHFILES}
  	$(LD) -o $@ ${AUTH_KRB_OBJS} $(KAFSLIBS) ${AUTHFILES} ${XLIBS} ${LDFLAGS}
  
  aix_auth_common.o: ${srcdir}/aix_auth_common.c
  	${CCRULE}
  
+ aix_aklog.o: ${srcdir}/aix_aklog.c
+ 	${CCRULE} @KRB5CFLAGS@
+ 
  aix_ktc_krb.o: ${srcdir}/aix_ktc.c
  	${CCRULE} -DAFS_KERBEROS_ENV
  
Index: openafs/src/tsm41/aix_aklog.c
diff -c /dev/null openafs/src/tsm41/aix_aklog.c:1.1.2.2
*** /dev/null	Fri Aug 10 00:27:58 2007
--- openafs/src/tsm41/aix_aklog.c	Fri Jul 13 15:55:00 2007
***************
*** 0 ****
--- 1,563 ----
+ /*
+  * Copyright 2000, International Business Machines Corporation and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ #include <afsconfig.h>
+ #include <afs/param.h>
+ 
+ RCSID
+     ("$Header: /cvs/openafs/src/tsm41/aix_aklog.c,v 1.1.2.2 2007/07/13 19:55:00 shadow Exp $");
+ 
+ #if defined(AFS_AIX51_ENV)
+ #include <sys/types.h>
+ #include <sys/param.h>
+ #include <stdio.h>
+ #include <locale.h>
+ #include <nl_types.h>
+ #include <pwd.h>
+ #include <netdb.h>
+ #include <sys/socket.h>
+ #include <sys/file.h>
+ #include <errno.h>
+ #include <usersec.h>
+ 
+ #include <krb5.h>
+ 
+ #include <afs/cellconfig.h>
+ #include <afs/dirpath.h>
+ #include <rx/rxkad.h>
+ #include <afs/auth.h>
+ #include "aix_auth_prototypes.h"
+ 
+ struct afsconf_cell ak_cellconfig; /* General information about the cell */
+ static char linkedcell[MAXCELLCHARS+1];
+ static krb5_ccache  _krb425_ccache = NULL;
+ 
+ #define AFSKEY "afs"
+ #define AFSINST ""
+ 
+ #ifndef ANAME_SZ
+ #define ANAME_SZ 40
+ #endif /* ANAME_SZ */
+ #ifndef REALM_SZ
+ #define REALM_SZ 40
+ #endif /* REALM_SZ */
+ #ifndef SNAME_SZ
+ #define SNAME_SZ 40
+ #endif /* SNAME_SZ */
+ #ifndef INST_SZ
+ #define INST_SZ 40
+ #endif /* INST_SZ */
+ 
+ /*
+  * Why doesn't AFS provide these prototypes?
+  */
+ 
+ extern int pioctl(char *, afs_int32, struct ViceIoctl *, afs_int32);
+ 
+ /*
+  * Other prototypes
+  */
+ 
+ static krb5_error_code get_credv5(krb5_context context, char *, char *,
+ 				  char *, krb5_creds **);
+ static int get_user_realm(krb5_context, char *);
+ 
+ #if defined(HAVE_KRB5_PRINC_SIZE) || defined(krb5_princ_size)
+ 
+ #define get_princ_str(c, p, n) krb5_princ_component(c, p, n)->data
+ #define get_princ_len(c, p, n) krb5_princ_component(c, p, n)->length
+ #define second_comp(c, p) (krb5_princ_size(c, p) > 1)
+ #define realm_data(c, p) krb5_princ_realm(c, p)->data
+ #define realm_len(c, p) krb5_princ_realm(c, p)->length
+ 
+ #elif defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING)
+ 
+ #define get_princ_str(c, p, n) krb5_principal_get_comp_string(c, p, n)
+ #define get_princ_len(c, p, n) strlen(krb5_principal_get_comp_string(c, p, n))
+ #define second_comp(c, p) (krb5_principal_get_comp_string(c, p, 1) != NULL)
+ #define realm_data(c, p) krb5_realm_data(krb5_principal_get_realm(c, p))
+ #define realm_len(c, p) krb5_realm_length(krb5_principal_get_realm(c, p))
+ 
+ #else
+ #error "Must have either krb5_princ_size or krb5_principal_get_comp_string"
+ #endif
+ 
+ #if defined(HAVE_KRB5_CREDS_KEYBLOCK)
+ 
+ #define get_cred_keydata(c) c->keyblock.contents
+ #define get_cred_keylen(c) c->keyblock.length
+ #define get_creds_enctype(c) c->keyblock.enctype
+ 
+ #elif defined(HAVE_KRB5_CREDS_SESSION)
+ 
+ #define get_cred_keydata(c) c->session.keyvalue.data
+ #define get_cred_keylen(c) c->session.keyvalue.length
+ #define get_creds_enctype(c) c->session.keytype
+ 
+ #else
+ #error "Must have either keyblock or session member of krb5_creds"
+ #endif
+ 
+ char *afs_realm_of_cell(krb5_context context, struct afsconf_cell *cellconfig, int fallback)
+ {
+     static char krbrlm[REALM_SZ+1];
+         char **hrealms = 0;
+         krb5_error_code retval;
+ 
+     if (!cellconfig)
+         return 0;
+ 
+     if (fallback) {
+         char * p;
+         p = strchr(cellconfig->hostName[0], '.');
+         if (p++)
+             strcpy(krbrlm, p);
+         else
+             strcpy(krbrlm, cellconfig->name);
+         for (p=krbrlm; *p; p++) {
+             if (islower(*p)) 
+                 *p = toupper(*p);
+         }
+     } else {
+         if (retval = krb5_get_host_realm(context,
+                                          cellconfig->hostName[0], &hrealms))
+             return 0; 
+         if(!hrealms[0]) return 0;
+         strcpy(krbrlm, hrealms[0]);
+ 
+         if (hrealms) krb5_free_host_realm(context, hrealms);
+     }
+     return krbrlm;
+ }
+ 
+ int
+ aklog_authenticate(char *userName, char *response, int *reenter, char **message)
+ {
+     char *reason, *pword, prompt[256];
+     struct passwd *pwd;
+     int code, unixauthneeded, password_expires = -1;
+     int status;
+     krb5_context context;
+ 
+     krb5_init_context(&context);
+     *reenter = 0;
+     *message = (char *)0;
+ 
+ #if 0
+     if ((pwd = getpwnam(userName)) == NULL) {
+ 	*message = (char *)malloc(256);
+ 	sprintf(*message, "getpwnam for user failed\n");
+ 	return AUTH_FAILURE;
+     }
+ #endif
+ 
+     status = auth_to_cell(context, NULL, NULL);
+     if (status) {
+ 	*message = (char *)malloc(1024);
+ 	sprintf(*message, "Unable to obtain AFS tokens: %s.\n",
+ 		afs_error_message(status));
+ 	return AUTH_FAILURE; /* NOTFOUND? */
+     }
+     
+ #if 0
+     /*
+      * Local hack - if the person has a file in their home
+      * directory called ".xlog", read that for a list of
+      * extra cells to authenticate to
+      */
+     
+     if ((pwd = getpwuid(getuid())) != NULL) {
+ 	struct stat sbuf;
+ 	FILE *f;
+ 	char fcell[100], xlog_path[512];
+ 	
+ 	strcpy(xlog_path, pwd->pw_dir);
+ 	strcat(xlog_path, "/.xlog");
+ 	
+ 	if ((stat(xlog_path, &sbuf) == 0) &&
+ 	    ((f = fopen(xlog_path, "r")) != NULL)) {
+ 	    
+ 	    while (fgets(fcell, 100, f) != NULL) {
+ 		int auth_status;
+ 		
+ 		fcell[strlen(fcell) - 1] = '\0';
+ 		
+ 		auth_status = auth_to_cell(context, fcell, NULL);
+ 		if (status == AKLOG_SUCCESS)
+ 		    status = auth_status;
+ 		else
+ 		    status = AKLOG_SOMETHINGSWRONG;
+ 	    }
+ 	}
+     }
+ #endif
+     return AUTH_SUCCESS;
+ }
+ 	
+ static krb5_error_code get_credv5(krb5_context context, 
+ 			char *name, char *inst, char *realm,
+ 			krb5_creds **creds)
+ {
+     krb5_creds increds;
+     krb5_error_code r;
+     static krb5_principal client_principal = 0;
+ 
+     memset((char *)&increds, 0, sizeof(increds));
+     /* instance may be ptr to a null string. Pass null then */
+     if ((r = krb5_build_principal(context, &increds.server,
+                      strlen(realm), realm,
+                      name,
+            (inst && strlen(inst)) ? inst : (void *) NULL,
+                      (void *) NULL))) {
+         return r;
+     }
+ 
+     if (!_krb425_ccache) {
+         r = krb5_cc_default(context, &_krb425_ccache);
+ 	if (r)
+ 	    return r;
+     }
+     if (!client_principal) {
+         r = krb5_cc_get_principal(context, _krb425_ccache, &client_principal);
+ 	if (r)
+ 	    return r;
+     }
+ 
+     increds.client = client_principal;
+     increds.times.endtime = 0;
+ 	/* Ask for DES since that is what V4 understands */
+     get_creds_enctype((&increds)) = ENCTYPE_DES_CBC_CRC;
+ 
+     r = krb5_get_credentials(context, 0, _krb425_ccache, &increds, creds);
+ 
+     return r;
+ }
+ 
+ 
+ static int get_user_realm(krb5_context context, char *realm)
+ {
+     static krb5_principal client_principal = 0;
+     int i;
+ 
+     if (!_krb425_ccache)
+         krb5_cc_default(context, &_krb425_ccache);
+     if (!client_principal)
+         krb5_cc_get_principal(context, _krb425_ccache, &client_principal);
+ 
+     i = realm_len(context, client_principal);
+     if (i > REALM_SZ-1) i = REALM_SZ-1;
+     strncpy(realm,realm_data(context, client_principal), i);
+     realm[i] = 0;
+ 
+     return 0;
+ }
+ 
+ int
+ aklog_chpass(char *userName, char *oldPasswd, char *newPasswd, char **message)
+ {
+     return AUTH_SUCCESS;
+ }
+ 
+ int
+ aklog_passwdexpired(char *userName, char **message)
+ {
+     return AUTH_SUCCESS;
+ }
+ 
+ int
+ aklog_passwdrestrictions(char *userName, char *newPasswd, char *oldPasswd,
+ 		       char **message)
+ {
+     return AUTH_SUCCESS;
+ }
+ 
+ char *
+ aklog_getpasswd(char * userName)
+ {
+     errno = ENOSYS;
+     return NULL;
+ }
+ 
+ 
+ static int get_cellconfig(char *cell, struct afsconf_cell *cellconfig, char *local_cell, char *linkedcell)
+ {
+     int status = 0;
+     struct afsconf_dir *configdir;
+ 
+     memset(local_cell, 0, sizeof(local_cell));
+     memset((char *)cellconfig, 0, sizeof(*cellconfig));
+ 
+     if (!(configdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) {
+ 	return AFSCONF_NODB;
+     }
+ 
+     if (afsconf_GetLocalCell(configdir, local_cell, MAXCELLCHARS)) {
+ 	return AFSCONF_FAILURE;
+     }
+ 
+     if ((cell == NULL) || (cell[0] == 0))
+ 	cell = local_cell;
+ 
+ 	linkedcell[0] = '\0';
+     if (afsconf_GetCellInfo(configdir, cell, NULL, cellconfig)) {
+ 	status = AFSCONF_NOTFOUND;
+     }
+     if (cellconfig->linkedCell) 
+ 	strncpy(linkedcell,cellconfig->linkedCell,MAXCELLCHARS);
+ 
+     (void) afsconf_Close(configdir);
+ 
+     return(status);
+ }
+ 
+ /* 
+  * Log to a cell.  If the cell has already been logged to, return without
+  * doing anything.  Otherwise, log to it and mark that it has been logged
+  * to.
+  */
+ static int auth_to_cell(krb5_context context, char *cell, char *realm)
+ {
+     int status = 0;
+     char username[BUFSIZ];	/* To hold client username structure */
+     afs_int32 viceId;		/* AFS uid of user */
+ 
+     char name[ANAME_SZ];	/* Name of afs key */
+     char primary_instance[INST_SZ];	/* Instance of afs key */
+     char secondary_instance[INST_SZ];	/* Backup instance to try */
+     int try_secondary = 0;		/* Flag to indicate if we try second */
+     char realm_of_user[REALM_SZ]; /* Kerberos realm of user */
+     char realm_of_cell[REALM_SZ]; /* Kerberos realm of cell */
+     char local_cell[MAXCELLCHARS+1];
+     char cell_to_use[MAXCELLCHARS+1]; /* Cell to authenticate to */
+     static char lastcell[MAXCELLCHARS+1] = { 0 };
+     static char confname[512] = { 0 };
+     krb5_creds *v5cred = NULL;
+     struct ktc_principal aserver;
+     struct ktc_principal aclient;
+     struct ktc_token atoken, btoken;
+     int afssetpag = 1;
+ 
+     memset(name, 0, sizeof(name));
+     memset(primary_instance, 0, sizeof(primary_instance));
+     memset(secondary_instance, 0, sizeof(secondary_instance));
+     memset(realm_of_user, 0, sizeof(realm_of_user));
+     memset(realm_of_cell, 0, sizeof(realm_of_cell));
+ 
+     if (confname[0] == '\0') {
+ 	strncpy(confname, AFSDIR_CLIENT_ETC_DIRPATH, sizeof(confname));
+ 	confname[sizeof(confname) - 2] = '\0';
+     }
+ 
+     /* NULL or empty cell returns information on local cell */
+     if ((status = get_cellconfig(cell, &ak_cellconfig,
+ 			 local_cell, linkedcell)))
+ 	return(status);
+ 
+     strncpy(cell_to_use, ak_cellconfig.name, MAXCELLCHARS);
+     cell_to_use[MAXCELLCHARS] = 0;
+ 
+     /*
+      * Find out which realm we're supposed to authenticate to.  If one
+      * is not included, use the kerberos realm found in the credentials
+      * cache.
+      */
+     
+     if (realm && realm[0]) {
+ 	strcpy(realm_of_cell, realm);
+     }
+     else {
+ 	char *afs_realm = afs_realm_of_cell(context, &ak_cellconfig, FALSE);
+ 	
+ 	if (!afs_realm) {
+ 	    return AFSCONF_FAILURE;
+ 	}
+ 	
+ 	strcpy(realm_of_cell, afs_realm);
+     }
+     
+     /* We use the afs.<cellname> convention here... 
+      *
+      * Doug Engert's original code had principals of the form:
+      *
+      * "afsx/cell@realm"
+      *
+      * in the KDC, so the name wouldn't conflict with DFS.  Since we're
+      * not using DFS, I changed it just to look for the following
+      * principals:
+      *
+      * afs/<cell>@<realm>
+      * afs@<realm>
+      *
+      * Because people are transitioning from afs@realm to afs/cell,
+      * we configure things so that if the first one isn't found, we
+      * try the second one.  You can select which one you prefer with
+      * a configure option.
+      */
+     
+     strcpy(name, AFSKEY);
+     
+     if (1 || strcasecmp(cell_to_use, realm_of_cell) != 0) {
+ 	strncpy(primary_instance, cell_to_use, sizeof(primary_instance));
+ 	primary_instance[sizeof(primary_instance)-1] = '\0';
+ 	if (strcasecmp(cell_to_use, realm_of_cell) == 0) {
+ 	    try_secondary = 1;
+ 	    secondary_instance[0] = '\0';
+ 	}
+     } else {
+ 	primary_instance[0] = '\0';
+ 	try_secondary = 1;
+ 	strncpy(secondary_instance, cell_to_use,
+ 		sizeof(secondary_instance));
+ 	secondary_instance[sizeof(secondary_instance)-1] = '\0';
+     }
+     
+     /* 
+      * Extract the session key from the ticket file and hand-frob an
+      * afs style authenticator.
+      */
+     
+     /*
+      * Try to obtain AFS tickets.  Because there are two valid service
+      * names, we will try both, but trying the more specific first.
+      *
+      *	afs/<cell>@<realm> i.e. allow for single name with "."
+      * 	afs@<realm>
+      */
+     
+     status = get_credv5(context, name, primary_instance, realm_of_cell,
+ 			&v5cred);
+     
+     if ((status == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN || 
+ 	 status == KRB5KRB_ERR_GENERIC) && !realm_of_cell[0]) {
+ 	char *afs_realm = afs_realm_of_cell(context, &ak_cellconfig, TRUE);
+ 	
+ 	if (!afs_realm) {
+ 	    return AFSCONF_FAILURE;
+ 	}
+ 	
+ 	strcpy(realm_of_cell, afs_realm);
+ 	
+ 	if (strcasecmp(cell_to_use, realm_of_cell) == 0) {
+ 	    try_secondary = 1;
+ 	    secondary_instance[0] = '\0';
+ 	}
+ 	
+ 	status = get_credv5(context, name, primary_instance, realm_of_cell,
+ 			    &v5cred);
+ 	
+     }
+     if (status == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN || 
+ 	status == KRB5KRB_ERR_GENERIC) {
+ 	if (try_secondary)
+ 	    status = get_credv5(context, name, secondary_instance,
+ 				realm_of_cell, &v5cred);
+     }
+     
+     if (status) {
+ 	return status;
+     }
+     
+     strncpy(aserver.name, AFSKEY, MAXKTCNAMELEN - 1);
+     strncpy(aserver.instance, AFSINST, MAXKTCNAMELEN - 1);
+     strncpy(aserver.cell, cell_to_use, MAXKTCREALMLEN - 1);
+     
+     /*
+      * The default is to use rxkad2b, which means we put in a full
+      * V5 ticket.  If the user specifies -524, we talk to the
+      * 524 ticket converter.
+      */
+     
+     {
+ 	char *p;
+ 	int len;
+ 	
+ 	len = min(get_princ_len(context, v5cred->client, 0),
+ 		  second_comp(context, v5cred->client) ?
+ 		  MAXKTCNAMELEN - 2 : MAXKTCNAMELEN - 1);
+ 	strncpy(username, get_princ_str(context, v5cred->client, 0), len);
+ 	username[len] = '\0';
+ 	
+ 	if (second_comp(context, v5cred->client)) {
+ 	    strcat(username, ".");
+ 	    p = username + strlen(username);
+ 	    len = min(get_princ_len(context, v5cred->client, 1),
+ 		      MAXKTCNAMELEN - strlen(username) - 1);
+ 	    strncpy(p, get_princ_str(context, v5cred->client, 1), len);
+ 	    p[len] = '\0';
+ 	}
+ 	
+ 	memset(&atoken, 0, sizeof(atoken));
+ 	atoken.kvno = RXKAD_TKT_TYPE_KERBEROS_V5;
+ 	atoken.startTime = v5cred->times.starttime;;
+ 	atoken.endTime = v5cred->times.endtime;
+ 	memcpy(&atoken.sessionKey, get_cred_keydata(v5cred),
+ 	       get_cred_keylen(v5cred));
+ 	atoken.ticketLen = v5cred->ticket.length;
+ 	memcpy(atoken.ticket, v5cred->ticket.data, atoken.ticketLen);
+     }
+ 	
+     if ((status = get_user_realm(context, realm_of_user))) {
+ 	return KRB5_REALM_UNKNOWN;
+     }
+     if (strcmp(realm_of_user, realm_of_cell)) {
+ 	strcat(username, "@");
+ 	strcat(username, realm_of_user);
+     }
+     
+     strcpy(lastcell, aserver.cell);
+     
+     if (!pr_Initialize (0, confname, aserver.cell))
+ 	status = pr_SNameToId (username, &viceId);
+     
+     /*
+      * This is a crock, but it is Transarc's crock, so
+      * we have to play along in order to get the
+      * functionality.  The way the afs id is stored is
+      * as a string in the username field of the token.
+      * Contrary to what you may think by looking at
+      * the code for tokens, this hack (AFS ID %d) will
+      * not work if you change %d to something else.
+      */
+     
+     /* Reset the "aclient" structure before we call ktc_SetToken.
+      * This structure was first set by the ktc_GetToken call when
+      * we were comparing whether identical tokens already existed.
+      */
+     strncpy(aclient.name, username, MAXKTCNAMELEN - 1);
+     strcpy(aclient.instance, "");
+     strncpy(aclient.cell, realm_of_user, MAXKTCREALMLEN - 1);
+     
+     /* on AIX 4.1.4 with AFS 3.4a+ if a write is not done before 
+      * this routine, it will not add the token. It is not clear what 
+      * is going on here! So we will do the following operation
+      */
+     write(2,"",0); /* dummy write */
+     status = ktc_SetToken(&aserver, &atoken, &aclient, afssetpag);
+ 
+     return(status);
+ }
+ 
+ int
+ aklog_initialize(struct secmethod_table *meths)
+ {
+     memset(meths, 0, sizeof(struct secmethod_table));
+ 
+     /*
+      * Initialize the exported interface routines.
+      * Aside from method_authenticate, these are just no-ops.
+      */
+     meths->method_chpass = aklog_chpass;
+     meths->method_authenticate = aklog_authenticate;
+     meths->method_passwdexpired = aklog_passwdexpired;
+     meths->method_passwdrestrictions = aklog_passwdrestrictions;
+     meths->method_getpasswd = aklog_getpasswd;
+ 
+     return (0);
+ }
+ #endif /* AFS_AIX51_ENV */
Index: openafs/src/viced/afsfileprocs.c
diff -c openafs/src/viced/afsfileprocs.c:1.113.2.15 openafs/src/viced/afsfileprocs.c:1.113.2.17
*** openafs/src/viced/afsfileprocs.c:1.113.2.15	Mon Apr 23 20:28:28 2007
--- openafs/src/viced/afsfileprocs.c	Mon Jul 30 09:19:02 2007
***************
*** 29,35 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/afsfileprocs.c,v 1.113.2.15 2007/04/24 00:28:28 jaltman Exp $");
  
  #include <stdio.h>
  #include <stdlib.h>
--- 29,35 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/afsfileprocs.c,v 1.113.2.17 2007/07/30 13:19:02 shadow Exp $");
  
  #include <stdio.h>
  #include <stdlib.h>
***************
*** 321,326 ****
--- 321,331 ----
      H_LOCK;
    retry:
      tclient = h_FindClient_r(*tconn);
+     if (!tclient) {
+ 	ViceLog(0, ("CallPreamble: Couldn't get CPS. Too many lockers\n"));
+ 	H_UNLOCK;
+ 	return VBUSY;
+     }
      thost = tclient->host;
      if (tclient->prfail == 1) {	/* couldn't get the CPS */
  	if (!retry_flag) {
***************
*** 424,429 ****
--- 429,436 ----
  
      H_LOCK;
      tclient = h_FindClient_r(aconn);
+     if (!tclient) 
+ 	goto busyout;
      thost = tclient->host;
      if (thost->hostFlags & HERRORTRANS)
  	translate = 1;
***************
*** 445,450 ****
--- 452,458 ----
  		afs_inet_ntoa_r(thost->host, hoststr), ntohs(thost->port),
  		thost));
      }
+  busyout:
      H_UNLOCK;
      return (translate ? sys_error_to_et(ret) : ret);
  }				/*CallPostamble */
***************
*** 1098,1104 ****
      }
  
      ino = VN_GET_INO(targetptr);
!     assert(VALID_INO(ino));
      targFdP = IH_OPEN(targetptr->handle);
      if (targFdP == NULL) {
  	rc = errno;
--- 1106,1118 ----
      }
  
      ino = VN_GET_INO(targetptr);
!     if (!VALID_INO(ino)) {
! 	free(buff);
! 	VTakeOffline(volptr);
! 	ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
! 		    volptr->hashid));
! 	return EIO;
!     }    
      targFdP = IH_OPEN(targetptr->handle);
      if (targFdP == NULL) {
  	rc = errno;
***************
*** 1265,1270 ****
--- 1279,1287 ----
        */
      if ((*targetptr)->disk.uniquifier != fileFid->Unique) {
  	VTakeOffline(volptr);
+ 	ViceLog(0,
+ 		("Volume %u now offline, must be salvaged.\n",
+ 		 volptr->hashid));
  	errorCode = VSALVAGE;
  	return errorCode;
      }
***************
*** 1292,1301 ****
  			 errno));
  		if (errno != ENOENT)
  		{
  		    ViceLog(0,
  			    ("Volume %u now offline, must be salvaged.\n",
  			     volptr->hashid));
- 		    VTakeOffline(volptr);
  		    return (EIO);
  		}
  		DT1++;
--- 1309,1318 ----
  			 errno));
  		if (errno != ENOENT)
  		{
+ 		    VTakeOffline(volptr);
  		    ViceLog(0,
  			    ("Volume %u now offline, must be salvaged.\n",
  			     volptr->hashid));
  		    return (EIO);
  		}
  		DT1++;
***************
*** 1318,1327 ****
  		("Error %d deleting %s\n", code,
  		 (((*targetptr)->disk.type ==
  		   Directory) ? "directory" : "file")));
  	ViceLog(0,
  		("Volume %u now offline, must be salvaged.\n",
  		 volptr->hashid));
- 	VTakeOffline(volptr);
  	if (!errorCode)
  	    errorCode = code;
      }
--- 1335,1344 ----
  		("Error %d deleting %s\n", code,
  		 (((*targetptr)->disk.type ==
  		   Directory) ? "directory" : "file")));
+ 	VTakeOffline(volptr);
  	ViceLog(0,
  		("Volume %u now offline, must be salvaged.\n",
  		 volptr->hashid));
  	if (!errorCode)
  	    errorCode = code;
      }
***************
*** 3981,3986 ****
--- 3998,4006 ----
  	    VPutVnode(&errorCode, testvptr);
  	    if ((top == 1) && (testnode != 0)) {
  		VTakeOffline(volptr);
+ 		ViceLog(0,
+ 			("Volume %u now offline, must be salvaged.\n",
+ 			 volptr->hashid));
  		errorCode = EIO;
  		goto Bad_Rename;
  	    }
***************
*** 4310,4319 ****
  
      /* Write the contents of the symbolic link name into the target inode */
      fdP = IH_OPEN(targetptr->handle);
!     assert(fdP != NULL);
      len = strlen((char *) LinkContents);
!      code = (len == FDH_WRITE(fdP, (char *) LinkContents, len)) ? 0 : VDISKFULL;
!      if (code) ViceLog(0, ("SAFSS_Symlink FDH_WRITE failed for len=%d, Fid=%u.%d.%d\n", len, OutFid->Volume, OutFid->Vnode, OutFid->Unique));
      FDH_CLOSE(fdP);
      /*
       * Set up and return modified status for the parent dir and new symlink
--- 4330,4347 ----
  
      /* Write the contents of the symbolic link name into the target inode */
      fdP = IH_OPEN(targetptr->handle);
!     if (fdP == NULL) {
! 	(void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
! 			       volptr, &client);
! 	VTakeOffline(volptr);
! 	ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
! 		    volptr->hashid));
! 	return EIO;
!     }    
      len = strlen((char *) LinkContents);
!     code = (len == FDH_WRITE(fdP, (char *) LinkContents, len)) ? 0 : VDISKFULL;
!     if (code) 
! 	ViceLog(0, ("SAFSS_Symlink FDH_WRITE failed for len=%d, Fid=%u.%d.%d\n", len, OutFid->Volume, OutFid->Vnode, OutFid->Unique));
      FDH_CLOSE(fdP);
      /*
       * Set up and return modified status for the parent dir and new symlink
***************
*** 6805,6810 ****
--- 6833,6840 ----
      fdP = IH_OPEN(ihP);
      if (fdP == NULL) {
  	VTakeOffline(volptr);
+ 	ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
+ 		    volptr->hashid));
  	return EIO;
      }
      optSize = sendBufSize;
***************
*** 6814,6819 ****
--- 6844,6851 ----
      if (tlen < 0) {
  	FDH_CLOSE(fdP);
  	VTakeOffline(volptr);
+ 	ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
+ 		    volptr->hashid));
  	return EIO;
      }
      if (Pos > tlen) {
***************
*** 6852,6857 ****
--- 6884,6891 ----
  	    FDH_CLOSE(fdP);
  	    FreeSendBuffer((struct afs_buffer *)tbuffer);
  	    VTakeOffline(volptr);
+ 	    ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
+ 			volptr->hashid));
  	    return EIO;
  	}
  	errorCode = rx_Write(Call, tbuffer, wlen);
***************
*** 6866,6871 ****
--- 6900,6907 ----
  	if (errorCode != wlen) {
  	    FDH_CLOSE(fdP);
  	    VTakeOffline(volptr);
+ 	    ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
+ 			volptr->hashid));
  	    return EIO;
  	}
  	errorCode = rx_Writev(Call, tiov, tnio, wlen);
***************
*** 7038,7043 ****
--- 7074,7081 ----
  	if (GetLinkCountAndSize(volptr, fdP, &linkCount, &DataLength) < 0) {
  	    FDH_CLOSE(fdP);
  	    VTakeOffline(volptr);
+ 	    ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
+ 			volptr->hashid));
  	    return EIO;
  	}
  
***************
*** 7081,7087 ****
  	}
  	tinode = VN_GET_INO(targetptr);
      }
!     assert(VALID_INO(tinode));
  
      /* compute new file length */
      NewLength = DataLength;
--- 7119,7130 ----
  	}
  	tinode = VN_GET_INO(targetptr);
      }
!     if (!VALID_INO(tinode)) {
! 	VTakeOffline(volptr);
! 	ViceLog(0,("Volume %u now offline, must be salvaged.\n",
! 		   volptr->hashid));
! 	return EIO;
!     }
  
      /* compute new file length */
      NewLength = DataLength;
***************
*** 7405,7410 ****
--- 7448,7457 ----
  #else
      H_LOCK;
      tclient = h_FindClient_r(tcon);
+     if (!tclient) {
+ 	errorCode = VBUSY;
+ 	goto Bad_CallBackRxConnAddr;
+     }
      thost = tclient->host;
      
      /* nothing more can be done */
Index: openafs/src/viced/callback.c
diff -c openafs/src/viced/callback.c:1.77.2.2 openafs/src/viced/callback.c:1.77.2.4
*** openafs/src/viced/callback.c:1.77.2.2	Sat Jun 24 10:10:46 2006
--- openafs/src/viced/callback.c	Wed Aug  8 12:31:25 2007
***************
*** 85,91 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/callback.c,v 1.77.2.2 2006/06/24 14:10:46 jaltman Exp $");
  
  #include <stdio.h>
  #include <stdlib.h>		/* for malloc() */
--- 85,91 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/callback.c,v 1.77.2.4 2007/08/08 16:31:25 jaltman Exp $");
  
  #include <stdio.h>
  #include <stdlib.h>		/* for malloc() */
***************
*** 720,729 ****
  		    if (MultiBreakCallBackAlternateAddress(hp, afidp)) {
  			if (ShowProblems) {
  			    ViceLog(7,
! 				    ("BCB: Failed on file %u.%u.%u, Host %s:%d is down\n",
  				     afidp->AFSCBFids_val->Volume,
  				     afidp->AFSCBFids_val->Vnode,
  				     afidp->AFSCBFids_val->Unique,
  				     afs_inet_ntoa_r(hp->host, hoststr),
  				     ntohs(hp->port)));
  			}
--- 720,730 ----
  		    if (MultiBreakCallBackAlternateAddress(hp, afidp)) {
  			if (ShowProblems) {
  			    ViceLog(7,
! 				    ("BCB: Failed on file %u.%u.%u, Host %x (%s:%d) is down\n",
  				     afidp->AFSCBFids_val->Volume,
  				     afidp->AFSCBFids_val->Vnode,
  				     afidp->AFSCBFids_val->Unique,
+                                      hp,
  				     afs_inet_ntoa_r(hp->host, hoststr),
  				     ntohs(hp->port)));
  			}
***************
*** 790,797 ****
      char hoststr[16];
  
      ViceLog(7,
! 	    ("BCB: BreakCallBack(all but %s:%d, (%u,%u,%u))\n",
! 	     afs_inet_ntoa_r(xhost->host, hoststr), ntohs(xhost->port),
  	     fid->Volume, fid->Vnode, fid->Unique));
  
      H_LOCK;
--- 791,798 ----
      char hoststr[16];
  
      ViceLog(7,
! 	    ("BCB: BreakCallBack(Host %x all but %s:%d, (%u,%u,%u))\n",
! 	     xhost, afs_inet_ntoa_r(xhost->host, hoststr), ntohs(xhost->port),
  	     fid->Volume, fid->Vnode, fid->Unique));
  
      H_LOCK;
***************
*** 820,827 ****
  		    ViceLog(0, ("BCB: BOGUS! cb->hhead is NULL!\n"));
  		} else if (thishost->hostFlags & VENUSDOWN) {
  		    ViceLog(7,
! 			    ("BCB: %s:%d is down; delaying break call back\n",
! 			     afs_inet_ntoa_r(thishost->host, hoststr),
  			     ntohs(thishost->port)));
  		    cb->status = CB_DELAYED;
  		} else {
--- 821,828 ----
  		    ViceLog(0, ("BCB: BOGUS! cb->hhead is NULL!\n"));
  		} else if (thishost->hostFlags & VENUSDOWN) {
  		    ViceLog(7,
! 			    ("BCB: %x (%s:%d) is down; delaying break call back\n",
! 			     thishost, afs_inet_ntoa_r(thishost->host, hoststr),
  			     ntohs(thishost->port)));
  		    cb->status = CB_DELAYED;
  		} else {
***************
*** 882,889 ****
      pcb = FindCBPtr(fe, host);
      if (!*pcb) {
  	ViceLog(8,
! 		("DCB: No call back for host %s:%d, (%u, %u, %u)\n",
! 		 afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port),
  		 fid->Volume, fid->Vnode, fid->Unique));
  	h_Unlock_r(host);
  	H_UNLOCK;
--- 883,890 ----
      pcb = FindCBPtr(fe, host);
      if (!*pcb) {
  	ViceLog(8,
! 		("DCB: No call back for host %x (%s:%d), (%u, %u, %u)\n",
! 		 host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port),
  		 fid->Volume, fid->Vnode, fid->Unique));
  	h_Unlock_r(host);
  	H_UNLOCK;
***************
*** 1003,1017 ****
  	if (code) {
  	    if (ShowProblems) {
  		ViceLog(0,
! 			("CB: Call back connect back failed (in break delayed) for Host %s:%d\n",
! 			 afs_inet_ntoa_r(host->host, hoststr),
  			 ntohs(host->port)));
  	    }
  	    host->hostFlags |= VENUSDOWN;
  	} else {
  	    ViceLog(25,
! 		    ("InitCallBackState success on %s\n",
! 		     afs_inet_ntoa_r(host->host, hoststr)));
  	    /* reset was done successfully */
  	    host->hostFlags |= RESETDONE;
  	    host->hostFlags &= ~VENUSDOWN;
--- 1004,1018 ----
  	if (code) {
  	    if (ShowProblems) {
  		ViceLog(0,
! 			("CB: Call back connect back failed (in break delayed) for Host %x (%s:%d)\n",
! 			 host, afs_inet_ntoa_r(host->host, hoststr),
  			 ntohs(host->port)));
  	    }
  	    host->hostFlags |= VENUSDOWN;
  	} else {
  	    ViceLog(25,
! 		    ("InitCallBackState success on %x (%s:%d)\n",
! 		     host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
  	    /* reset was done successfully */
  	    host->hostFlags |= RESETDONE;
  	    host->hostFlags &= ~VENUSDOWN;
***************
*** 1050,1064 ****
  		int i;
  		if (ShowProblems) {
  		    ViceLog(0,
! 			    ("CB: XCallBackBulk failed, Host %s:%d; callback list follows:\n",
! 			     afs_inet_ntoa_r(host->host, hoststr),
  			     ntohs(host->port)));
  		}
  		for (i = 0; i < nfids; i++) {
  		    if (ShowProblems) {
  			ViceLog(0,
! 				("CB: Host %s:%d, file %u.%u.%u (part of bulk callback)\n",
! 				 afs_inet_ntoa_r(host->host, hoststr),
  				 ntohs(host->port), fids[i].Volume,
  				 fids[i].Vnode, fids[i].Unique));
  		    }
--- 1051,1065 ----
  		int i;
  		if (ShowProblems) {
  		    ViceLog(0,
! 			    ("CB: XCallBackBulk failed, Host %x (%s:%d); callback list follows:\n",
!                              host, afs_inet_ntoa_r(host->host, hoststr),
  			     ntohs(host->port)));
  		}
  		for (i = 0; i < nfids; i++) {
  		    if (ShowProblems) {
  			ViceLog(0,
! 				("CB: Host %x (%s:%d), file %u.%u.%u (part of bulk callback)\n",
! 				 host, afs_inet_ntoa_r(host->host, hoststr),
  				 ntohs(host->port), fids[i].Volume,
  				 fids[i].Vnode, fids[i].Unique));
  		    }
***************
*** 1105,1116 ****
  	    return 0;		/* Release hold */
  	}
  	ViceLog(8,
! 		("BVCB: volume call back for Host %s:%d failed\n",
! 		 afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
  	if (ShowProblems) {
  	    ViceLog(0,
! 		    ("CB: volume callback for Host %s:%d failed\n",
! 		     afs_inet_ntoa_r(host->host, hoststr),
  		     ntohs(host->port)));
  	}
  	DeleteAllCallBacks_r(host, deletefe);	/* Delete all callback state 
--- 1106,1117 ----
  	    return 0;		/* Release hold */
  	}
  	ViceLog(8,
! 		("BVCB: volume call back for Host %x (%s:%d) failed\n",
!                  host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
  	if (ShowProblems) {
  	    ViceLog(0,
! 		    ("CB: volume callback for Host %x (%s:%d) failed\n",
! 		     host, afs_inet_ntoa_r(host->host, hoststr),
  		     ntohs(host->port)));
  	}
  	DeleteAllCallBacks_r(host, deletefe);	/* Delete all callback state 
***************
*** 1367,1374 ****
  		/* leave hold for MultiBreakVolumeCallBack to clear */
  	    } else {
  		ViceLog(125,
! 			("Found host %s:%d non-DELAYED cb for %u:%u:%u\n", 
! 			 afs_inet_ntoa_r(host->host, hoststr),
  			 ntohs(host->port), fe->vnode, fe->unique, fe->volid));
  	    }
  	}
--- 1368,1375 ----
  		/* leave hold for MultiBreakVolumeCallBack to clear */
  	    } else {
  		ViceLog(125,
! 			("Found host %x (%s:%d) non-DELAYED cb for %u:%u:%u\n", 
! 			 host, afs_inet_ntoa_r(host->host, hoststr),
  			 ntohs(host->port), fe->vnode, fe->unique, fe->volid));
  	    }
  	}
***************
*** 1430,1437 ****
  		cb = itocb(cbi);
  		cbi = cb->tnext;
  		ViceLog(8,
! 			("CCB: deleting timed out call back %s:%d, (%u,%u,%u)\n",
! 			 afs_inet_ntoa_r(h_itoh(cb->hhead)->host, hoststr),
  			 h_itoh(cb->hhead)->port, itofe(cb->fhead)->volid,
  			 itofe(cb->fhead)->vnode, itofe(cb->fhead)->unique));
  		HDel(cb);
--- 1431,1439 ----
  		cb = itocb(cbi);
  		cbi = cb->tnext;
  		ViceLog(8,
! 			("CCB: deleting timed out call back %x (%s:%d), (%u,%u,%u)\n",
!                          h_itoh(cb->hhead)->host,
!                          afs_inet_ntoa_r(h_itoh(cb->hhead)->host, hoststr),
  			 h_itoh(cb->hhead)->port, itofe(cb->fhead)->volid,
  			 itofe(cb->fhead)->vnode, itofe(cb->fhead)->unique));
  		HDel(cb);
***************
*** 1588,1595 ****
      struct rx_connection *cb_conn = NULL;
  
      ViceLog(5,
! 	    ("GSS: Delete longest inactive host %s\n",
! 	     afs_inet_ntoa_r(hp->host, hoststr)));
      if (!(held = h_Held_r(hp)))
  	h_Hold_r(hp);
  
--- 1590,1597 ----
      struct rx_connection *cb_conn = NULL;
  
      ViceLog(5,
! 	    ("GSS: Delete longest inactive host %x (%s:%d)\n",
!              hp, afs_inet_ntoa_r(hp->host, hoststr), ntohs(hp->port)));
      if (!(held = h_Held_r(hp)))
  	h_Hold_r(hp);
  
***************
*** 2893,2902 ****
      if (!host->interface)
  	return 1;		/* failure */
  
-     assert(host->interface->numberOfInterfaces > 0);
- 
      /* the only address is the primary interface */
!     if (host->interface->numberOfInterfaces == 1)
  	return 1;		/* failure */
  
      /* initialise a security object only once */
--- 2895,2902 ----
      if (!host->interface)
  	return 1;		/* failure */
  
      /* the only address is the primary interface */
!     if (host->interface->numberOfInterfaces <= 1)
  	return 1;		/* failure */
  
      /* initialise a security object only once */
***************
*** 2930,2937 ****
  
      assert(j);			/* at least one alternate address */
      ViceLog(125,
! 	    ("Starting multibreakcall back on all addr for host %s\n",
! 	     afs_inet_ntoa_r(host->host, hoststr)));
      H_UNLOCK;
      multi_Rx(conns, j) {
  	multi_RXAFSCB_CallBack(afidp, &tc);
--- 2930,2937 ----
  
      assert(j);			/* at least one alternate address */
      ViceLog(125,
! 	    ("Starting multibreakcall back on all addr for host %x (%s:%d)\n",
!              host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
      H_UNLOCK;
      multi_Rx(conns, j) {
  	multi_RXAFSCB_CallBack(afidp, &tc);
***************
*** 2941,2954 ****
  	    if (host->callback_rxcon)
  		rx_DestroyConnection(host->callback_rxcon);
  	    host->callback_rxcon = conns[multi_i];
  	    host->host = interfaces[multi_i].addr;
  	    host->port = interfaces[multi_i].port;
  	    connSuccess = conns[multi_i];
  	    rx_SetConnDeadTime(host->callback_rxcon, 50);
  	    rx_SetConnHardDeadTime(host->callback_rxcon, AFS_HARDDEADTIME);
  	    ViceLog(125,
! 		    ("multibreakcall success with addr %s\n",
! 		     afs_inet_ntoa_r(interfaces[multi_i].addr, hoststr)));
  	    H_UNLOCK;
  	    multi_Abort;
  	}
--- 2941,2957 ----
  	    if (host->callback_rxcon)
  		rx_DestroyConnection(host->callback_rxcon);
  	    host->callback_rxcon = conns[multi_i];
+             h_DeleteHostFromAddrHashTable_r(host->host, host->port, host);
  	    host->host = interfaces[multi_i].addr;
  	    host->port = interfaces[multi_i].port;
+             h_AddHostToAddrHashTable_r(host->host, host->port, host);
  	    connSuccess = conns[multi_i];
  	    rx_SetConnDeadTime(host->callback_rxcon, 50);
  	    rx_SetConnHardDeadTime(host->callback_rxcon, AFS_HARDDEADTIME);
  	    ViceLog(125,
! 		    ("multibreakcall success with addr %s:%d\n",
! 		     afs_inet_ntoa_r(interfaces[multi_i].addr, hoststr),
!                      ntohs(interfaces[multi_i].port)));
  	    H_UNLOCK;
  	    multi_Abort;
  	}
***************
*** 3015,3022 ****
  
  	interfaces[j] = host->interface->interface[i];
  	conns[j] =
! 	    rx_NewConnection(interfaces[i].addr, 
! 			     interfaces[i].port, 1, sc, 0);
  	rx_SetConnDeadTime(conns[j], 2);
  	rx_SetConnHardDeadTime(conns[j], AFS_HARDDEADTIME);
  	j++;
--- 3018,3025 ----
  
  	interfaces[j] = host->interface->interface[i];
  	conns[j] =
! 	    rx_NewConnection(interfaces[j].addr, 
! 			     interfaces[j].port, 1, sc, 0);
  	rx_SetConnDeadTime(conns[j], 2);
  	rx_SetConnHardDeadTime(conns[j], AFS_HARDDEADTIME);
  	j++;
***************
*** 3024,3031 ****
  
      assert(j);			/* at least one alternate address */
      ViceLog(125,
! 	    ("Starting multiprobe on all addr for host %s\n",
! 	     afs_inet_ntoa_r(host->host, hoststr)));
      H_UNLOCK;
      multi_Rx(conns, j) {
  	multi_RXAFSCB_ProbeUuid(&host->interface->uuid);
--- 3027,3035 ----
  
      assert(j);			/* at least one alternate address */
      ViceLog(125,
! 	    ("Starting multiprobe on all addr for host %x (%s:%d)\n",
!              host, afs_inet_ntoa_r(host->host, hoststr),
!              ntohs(host->port)));
      H_UNLOCK;
      multi_Rx(conns, j) {
  	multi_RXAFSCB_ProbeUuid(&host->interface->uuid);
***************
*** 3035,3054 ****
  	    if (host->callback_rxcon)
  		rx_DestroyConnection(host->callback_rxcon);
  	    host->callback_rxcon = conns[multi_i];
  	    host->host = interfaces[multi_i].addr;
  	    host->port = interfaces[multi_i].port;
  	    connSuccess = conns[multi_i];
  	    rx_SetConnDeadTime(host->callback_rxcon, 50);
  	    rx_SetConnHardDeadTime(host->callback_rxcon, AFS_HARDDEADTIME);
  	    ViceLog(125,
! 		    ("multiprobe success with addr %s\n",
! 		     afs_inet_ntoa_r(interfaces[multi_i].addr, hoststr)));
  	    H_UNLOCK;
  	    multi_Abort;
  	} else {
  	    ViceLog(125,
! 		    ("multiprobe failure with addr %s\n",
! 		     afs_inet_ntoa_r(interfaces[multi_i].addr, hoststr)));
              
              /* This is less than desirable but its the best we can do.
               * The AFS Cache Manager will return either 0 for a Uuid  
--- 3039,3062 ----
  	    if (host->callback_rxcon)
  		rx_DestroyConnection(host->callback_rxcon);
  	    host->callback_rxcon = conns[multi_i];
+             h_DeleteHostFromAddrHashTable_r(host->host, host->port, host);
  	    host->host = interfaces[multi_i].addr;
  	    host->port = interfaces[multi_i].port;
+             h_AddHostToAddrHashTable_r(host->host, host->port, host);
  	    connSuccess = conns[multi_i];
  	    rx_SetConnDeadTime(host->callback_rxcon, 50);
  	    rx_SetConnHardDeadTime(host->callback_rxcon, AFS_HARDDEADTIME);
  	    ViceLog(125,
! 		    ("multiprobe success with addr %s:%d\n",
! 		     afs_inet_ntoa_r(interfaces[multi_i].addr, hoststr),
!                      ntohs(interfaces[multi_i].port)));
  	    H_UNLOCK;
  	    multi_Abort;
  	} else {
  	    ViceLog(125,
! 		    ("multiprobe failure with addr %s:%d\n",
! 		     afs_inet_ntoa_r(interfaces[multi_i].addr, hoststr),
!                      ntohs(interfaces[multi_i].port)));
              
              /* This is less than desirable but its the best we can do.
               * The AFS Cache Manager will return either 0 for a Uuid  
***************
*** 3060,3073 ****
              if (multi_error == 1) {
                  /* remove the current alternate address from this host */
                  H_LOCK;
!                 for (i = 0, j = 0; i < host->interface->numberOfInterfaces; i++) {
!                     if (interfaces[multi_i].addr != host->interface->interface[i].addr &&
! 			interfaces[multi_i].port != host->interface->interface[i].port) {
!                         host->interface->interface[j] = host->interface->interface[i];
!                         j++;
!                     }
!                 }
!                 host->interface->numberOfInterfaces--;
                  H_UNLOCK;
              }
          }
--- 3068,3074 ----
              if (multi_error == 1) {
                  /* remove the current alternate address from this host */
                  H_LOCK;
!                 removeInterfaceAddr_r(host, interfaces[multi_i].addr, interfaces[multi_i].port);
                  H_UNLOCK;
              }
          }
Index: openafs/src/viced/fsprobe.c
diff -c openafs/src/viced/fsprobe.c:1.12 openafs/src/viced/fsprobe.c:1.12.2.1
*** openafs/src/viced/fsprobe.c:1.12	Wed Feb 22 15:29:01 2006
--- openafs/src/viced/fsprobe.c	Wed Aug  8 12:31:25 2007
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/fsprobe.c,v 1.12 2006/02/22 20:29:01 rees Exp $");
  
  #include <afs/stds.h>
  #include <afs/afsint.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/fsprobe.c,v 1.12.2.1 2007/08/08 16:31:25 jaltman Exp $");
  
  #include <afs/stds.h>
  #include <afs/afsint.h>
***************
*** 168,174 ****
  	    } else if (!strcmp(oper, "fsstats")) {
  		struct afsStatistics stats;
  
! 		code = ubik_Call(AFS_GetStatistics, cstruct, 0, &stats);
  		printf("return code is %d\n", code);
  	    } else if (!strcmp(oper, "fd")) {
  		code = FetchData(argp);
--- 168,174 ----
  	    } else if (!strcmp(oper, "fsstats")) {
  		struct afsStatistics stats;
  
! 		code = ubik_AFS_GetStatistics(cstruct, 0, &stats);
  		printf("return code is %d\n", code);
  	    } else if (!strcmp(oper, "fd")) {
  		code = FetchData(argp);
***************
*** 364,370 ****
      fid.Vnode = vnode;
      fid.Unique = unique;
      code =
! 	ubik_Call(AFS_FetchStatus, cstruct, 0, &fid, &hyp0, 0, &OutStatus,
  		  &Token, &tsync);
      return (code);
  }
--- 364,370 ----
      fid.Vnode = vnode;
      fid.Unique = unique;
      code =
! 	ubik_AFS_FetchStatus(cstruct, 0, &fid, &hyp0, 0, &OutStatus,
  		  &Token, &tsync);
      return (code);
  }
***************
*** 390,396 ****
      fid.Vnode = vnode;
      fid.Unique = unique;
      code =
! 	ubik_Call(AFS_FetchACL, cstruct, 0, &fid, &hyp0, 0, &AccessList,
  		  &OutStatus, &tsync);
      return (code);
  }
--- 390,396 ----
      fid.Vnode = vnode;
      fid.Unique = unique;
      code =
! 	ubik_AFS_FetchACL(cstruct, 0, &fid, &hyp0, 0, &AccessList,
  		  &OutStatus, &tsync);
      return (code);
  }
***************
*** 515,521 ****
  	InStatus.mask |= AFS_SETLENGTH;
      }
      code =
! 	ubik_Call(AFS_StoreStatus, cstruct, 0, &fid, &InStatus, &hyp0, 0,
  		  &OutStatus, &tsync);
      return (code);
  }
--- 515,521 ----
  	InStatus.mask |= AFS_SETLENGTH;
      }
      code =
! 	ubik_AFS_StoreStatus(cstruct, 0, &fid, &InStatus, &hyp0, 0,
  		  &OutStatus, &tsync);
      return (code);
  }
***************
*** 546,552 ****
      AccessList.afsACL_len = strlen(string) + 1;
      AccessList.afsACL_val = string;
      code =
! 	ubik_Call(AFS_StoreACL, cstruct, 0, &fid, &AccessList, &hyp0, 0,
  		  &OutStatus, &tsync);
      return (code);
  }
--- 546,552 ----
      AccessList.afsACL_len = strlen(string) + 1;
      AccessList.afsACL_val = string;
      code =
! 	ubik_AFS_StoreACL(cstruct, 0, &fid, &AccessList, &hyp0, 0,
  		  &OutStatus, &tsync);
      return (code);
  }
***************
*** 576,582 ****
      memset(&nameFid, 0, sizeof(struct afsFidName));
      strcpy(nameFid.name, name);
      code =
! 	ubik_Call(AFS_RemoveFile, cstruct, 0, &fid, &nameFid, &hyp0, 0,
  		  &OutDirStatus, &OutFidStatus, &outFid, &tsync);
      return (code);
  }
--- 576,582 ----
      memset(&nameFid, 0, sizeof(struct afsFidName));
      strcpy(nameFid.name, name);
      code =
! 	ubik_AFS_RemoveFile(cstruct, 0, &fid, &nameFid, &hyp0, 0,
  		  &OutDirStatus, &OutFidStatus, &outFid, &tsync);
      return (code);
  }
***************
*** 624,630 ****
  	InStatus.mask |= AFS_SETLENGTH;
      }
      code =
! 	ubik_Call(AFS_CreateFile, cstruct, 0, &fid, name, &InStatus, &hyp0, 0,
  		  &outFid, &OutFidStatus, &OutDirStatus, &Token, &tsync);
      return (code);
  }
--- 624,630 ----
  	InStatus.mask |= AFS_SETLENGTH;
      }
      code =
! 	ubik_AFS_CreateFile(cstruct, 0, &fid, name, &InStatus, &hyp0, 0,
  		  &outFid, &OutFidStatus, &OutDirStatus, &Token, &tsync);
      return (code);
  }
***************
*** 667,673 ****
      memset(&NewName, 0, sizeof(struct afsFidName));
      strcpy(NewName.name, nname);
      code =
! 	ubik_Call(AFS_Rename, cstruct, 0, &OldDirFid, &OldName, &NewDirFid,
  		  &NewName, &hyp0, 0, &OutOldDirStatus, &OutNewDirStatus,
  		  &OutOldFileFid, &OutOldFileStatus, &OutNewFileFid,
  		  &OutNewFileStatus, &tsync);
--- 667,673 ----
      memset(&NewName, 0, sizeof(struct afsFidName));
      strcpy(NewName.name, nname);
      code =
! 	ubik_AFS_Rename(cstruct, 0, &OldDirFid, &OldName, &NewDirFid,
  		  &NewName, &hyp0, 0, &OutOldDirStatus, &OutNewDirStatus,
  		  &OutOldFileFid, &OutOldFileStatus, &OutNewFileFid,
  		  &OutNewFileStatus, &tsync);
***************
*** 719,725 ****
  	InStatus.mask |= AFS_SETLENGTH;
      }
      code =
! 	ubik_Call(AFS_Symlink, cstruct, 0, &fid, name, linkcontents,
  		  &InStatus, &hyp0, 0, &outFid, &OutFidStatus, &OutDirStatus,
  		  &Token, &tsync);
      return (code);
--- 719,725 ----
  	InStatus.mask |= AFS_SETLENGTH;
      }
      code =
! 	ubik_AFS_Symlink(cstruct, 0, &fid, name, linkcontents,
  		  &InStatus, &hyp0, 0, &outFid, &OutFidStatus, &OutDirStatus,
  		  &Token, &tsync);
      return (code);
***************
*** 755,761 ****
      existingFid.Vnode = vnode;
      existingFid.Unique = unique;
      code =
! 	ubik_Call(AFS_HardLink, cstruct, 0, &fid, name, &existingFid, &hyp0,
  		  0, &OutFidStatus, &OutDirStatus, &tsync);
      return (code);
  }
--- 755,761 ----
      existingFid.Vnode = vnode;
      existingFid.Unique = unique;
      code =
! 	ubik_AFS_HardLink(cstruct, 0, &fid, name, &existingFid, &hyp0,
  		  0, &OutFidStatus, &OutDirStatus, &tsync);
      return (code);
  }
***************
*** 803,809 ****
  	InStatus.mask |= AFS_SETLENGTH;
      }
      code =
! 	ubik_Call(AFS_MakeDir, cstruct, 0, &fid, name, &InStatus, &hyp0, 0,
  		  &outFid, &OutFidStatus, &OutDirStatus, &Token, &tsync);
      return (code);
  }
--- 803,809 ----
  	InStatus.mask |= AFS_SETLENGTH;
      }
      code =
! 	ubik_AFS_MakeDir(cstruct, 0, &fid, name, &InStatus, &hyp0, 0,
  		  &outFid, &OutFidStatus, &OutDirStatus, &Token, &tsync);
      return (code);
  }
***************
*** 833,839 ****
      memset(&nameFid, 0, sizeof(struct afsFidName));
      strcpy(nameFid.name, name);
      code =
! 	ubik_Call(AFS_RemoveDir, cstruct, 0, &fid, &nameFid, &hyp0, 0,
  		  &OutDirStatus, &outFid, &tsync);
      return (code);
  }
--- 833,839 ----
      memset(&nameFid, 0, sizeof(struct afsFidName));
      strcpy(nameFid.name, name);
      code =
! 	ubik_AFS_RemoveDir(cstruct, 0, &fid, &nameFid, &hyp0, 0,
  		  &OutDirStatus, &outFid, &tsync);
      return (code);
  }
***************
*** 930,936 ****
      name = &argp[0][0];
      ++argp;
      code =
! 	ubik_Call(AFS_Lookup, cstruct, 0, &fid, name, &hyp0, 0, &outFid,
  		  &OutFidStatus, &OutDirStatus, &tsync);
      return (code);
  }
--- 930,936 ----
      name = &argp[0][0];
      ++argp;
      code =
! 	ubik_AFS_Lookup(cstruct, 0, &fid, name, &hyp0, 0, &outFid,
  		  &OutFidStatus, &OutDirStatus, &tsync);
      return (code);
  }
***************
*** 959,965 ****
      memset(&MinToken, 0, sizeof(struct afsToken));
      MinToken.tokenID.low = tokenId;	/* XXX */
      code =
! 	ubik_Call(AFS_GetToken, cstruct, 0, &fid, &MinToken, &hyp0, 0,
  		  &RealToken, &OutStatus, &tsync);
      return (code);
  }
--- 959,965 ----
      memset(&MinToken, 0, sizeof(struct afsToken));
      MinToken.tokenID.low = tokenId;	/* XXX */
      code =
! 	ubik_AFS_GetToken(cstruct, 0, &fid, &MinToken, &hyp0, 0,
  		  &RealToken, &OutStatus, &tsync);
      return (code);
  }
***************
*** 1005,1011 ****
      fex.afsBulkFEX_val = &fx;
      fex.afsBulkFEX_len = 1;
      code =
! 	ubik_Call(AFS_BulkKeepAlive, cstruct, 0, &fex, numExec, 0, 0, 0,
  		  &spare4);
      return (code);
  }
--- 1005,1011 ----
      fex.afsBulkFEX_val = &fx;
      fex.afsBulkFEX_len = 1;
      code =
! 	ubik_AFS_BulkKeepAlive(cstruct, 0, &fex, numExec, 0, 0, 0,
  		  &spare4);
      return (code);
  }
Index: openafs/src/viced/host.c
diff -c openafs/src/viced/host.c:1.93.2.15 openafs/src/viced/host.c:1.93.2.19
*** openafs/src/viced/host.c:1.93.2.15	Tue Apr 10 14:39:56 2007
--- openafs/src/viced/host.c	Fri Aug 10 00:13:04 2007
***************
*** 13,19 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/host.c,v 1.93.2.15 2007/04/10 18:39:56 shadow Exp $");
  
  #include <stdio.h>
  #include <errno.h>
--- 13,19 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/host.c,v 1.93.2.19 2007/08/10 04:13:04 shadow Exp $");
  
  #include <stdio.h>
  #include <errno.h>
***************
*** 82,87 ****
--- 82,88 ----
  extern int lwps;		/* the max number of server threads */
  extern afsUUID FS_HostUUID;
  
+ afsUUID nulluuid;
  int CEs = 0;			/* active clients */
  int CEBlocks = 0;		/* number of blocks of CEs */
  struct client *CEFree = 0;	/* first free client */
***************
*** 93,101 ****
  static struct rx_securityClass *sc = NULL;
  
  static void h_SetupCallbackConn_r(struct host * host);
- static void h_AddHostToHashTable_r(afs_uint32 addr, afs_uint16 port, struct host * host);
- static void h_AddHostToUuidHashTable_r(afsUUID * uuid, struct host * host);
- static int h_DeleteHostFromHashTableByAddr_r(afs_uint32 addr, afs_uint16 port, struct host *host);
  
  #define CESPERBLOCK 73
  struct CEBlock {		/* block of CESPERBLOCK file entries */
--- 94,99 ----
***************
*** 103,109 ****
  };
  
  static void h_TossStuff_r(register struct host *host);
- static int hashDelete_r(afs_uint32 addr, afs_uint16 port, struct host *host);
  
  /*
   * Make sure the subnet macros have been defined.
--- 101,106 ----
***************
*** 197,204 ****
   * to map IP addresses onto host pointers, and another
   * to map host UUIDs onto host pointers.
   */
! static struct h_hashChain *hostHashTable[h_HASHENTRIES];
! static struct h_hashChain *hostUuidHashTable[h_HASHENTRIES];
  #define h_HashIndex(hostip) ((hostip) & (h_HASHENTRIES-1))
  #define h_UuidHashIndex(uuidp) (((int)(afs_uuid_hash(uuidp))) & (h_HASHENTRIES-1))
  
--- 194,201 ----
   * to map IP addresses onto host pointers, and another
   * to map host UUIDs onto host pointers.
   */
! static struct h_AddrHashChain *hostAddrHashTable[h_HASHENTRIES];
! static struct h_UuidHashChain *hostUuidHashTable[h_HASHENTRIES];
  #define h_HashIndex(hostip) ((hostip) & (h_HASHENTRIES-1))
  #define h_UuidHashIndex(uuidp) (((int)(afs_uuid_hash(uuidp))) & (h_HASHENTRIES-1))
  
***************
*** 686,691 ****
--- 683,689 ----
      code = hpr_GetHostCPS(ntohl(host->host), &host->hcps);
      H_LOCK;
      if (code) {
+         char hoststr[16];
  	/*
  	 * Although ubik_Call (called by pr_GetHostCPS) traverses thru all protection servers
  	 * and reevaluates things if no sync server or quorum is found we could still end up
***************
*** 707,719 ****
  	     */
  	    host->hcpsfailed = 1;
  	    ViceLog(0,
! 		    ("Warning:  GetHostCPS failed (%d) for %x; will retry\n",
! 		     code, host->host));
  	} else {
  	    host->hcpsfailed = 0;
  	    ViceLog(1,
! 		    ("gethost:  GetHostCPS failed (%d) for %x; ignored\n",
! 		     code, host->host));
  	}
  	if (host->hcps.prlist_val)
  	    free(host->hcps.prlist_val);
--- 705,717 ----
  	     */
  	    host->hcpsfailed = 1;
  	    ViceLog(0,
! 		    ("Warning:  GetHostCPS failed (%d) for %x (%s:%d); will retry\n",
! 		     code, host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
  	} else {
  	    host->hcpsfailed = 0;
  	    ViceLog(1,
! 		    ("gethost:  GetHostCPS failed (%d) for %x (%s:%d); ignored\n",
! 		     code, host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
  	}
  	if (host->hcps.prlist_val)
  	    free(host->hcps.prlist_val);
***************
*** 775,781 ****
      host->host = rxr_HostOf(r_con);
      host->port = rxr_PortOf(r_con);
  
!     h_AddHostToHashTable_r(host->host, host->port, host);
  
      if (consolePort == 0) {	/* find the portal number for console */
  #if	defined(AFS_OSF_ENV)
--- 773,779 ----
      host->host = rxr_HostOf(r_con);
      host->port = rxr_PortOf(r_con);
  
!     h_AddHostToAddrHashTable_r(host->host, host->port, host);
  
      if (consolePort == 0) {	/* find the portal number for console */
  #if	defined(AFS_OSF_ENV)
***************
*** 842,854 ****
  h_Lookup_r(afs_uint32 haddr, afs_uint16 hport, int *heldp)
  {
      afs_int32 now;
!     struct host *host = 0;
!     struct h_hashChain *chain;
      int index = h_HashIndex(haddr);
      extern int hostaclRefresh;
  
    restart:
!     for (chain = hostHashTable[index]; chain; chain = chain->next) {
  	host = chain->hostPtr;
  	assert(host);
  	if (!(host->hostFlags & HOSTDELETED) && chain->addr == haddr
--- 840,852 ----
  h_Lookup_r(afs_uint32 haddr, afs_uint16 hport, int *heldp)
  {
      afs_int32 now;
!     struct host *host = NULL;
!     struct h_AddrHashChain *chain;
      int index = h_HashIndex(haddr);
      extern int hostaclRefresh;
  
    restart:
!     for (chain = hostAddrHashTable[index]; chain; chain = chain->next) {
  	host = chain->hostPtr;
  	assert(host);
  	if (!(host->hostFlags & HOSTDELETED) && chain->addr == haddr
***************
*** 889,895 ****
  h_LookupUuid_r(afsUUID * uuidp)
  {
      struct host *host = 0;
!     struct h_hashChain *chain;
      int index = h_UuidHashIndex(uuidp);
  
      for (chain = hostUuidHashTable[index]; chain; chain = chain->next) {
--- 887,893 ----
  h_LookupUuid_r(afsUUID * uuidp)
  {
      struct host *host = 0;
!     struct h_UuidHashChain *chain;
      int index = h_UuidHashIndex(uuidp);
  
      for (chain = hostUuidHashTable[index]; chain; chain = chain->next) {
***************
*** 933,940 ****
      if (h_NBLock_r(host) != 0) {
  	char hoststr[16];
  	ViceLog(0,
! 		("Warning:  h_TossStuff_r failed; Host %s:%d was locked.\n",
! 		 afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
  	return;
      } else {
  	h_Unlock_r(host);
--- 931,938 ----
      if (h_NBLock_r(host) != 0) {
  	char hoststr[16];
  	ViceLog(0,
! 		("Warning:  h_TossStuff_r failed; Host %x (%s:%d) was locked.\n",
! 		 host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
  	return;
      } else {
  	h_Unlock_r(host);
***************
*** 948,955 ****
  	    if (code < 0) {
  		char hoststr[16];
  		ViceLog(0,
! 			("Warning: h_TossStuff_r failed: Host %s:%d client %x was locked.\n",
! 			 afs_inet_ntoa_r(host->host, hoststr),
  			 ntohs(host->port), client));
  		return;
  	    }
--- 946,953 ----
  	    if (code < 0) {
  		char hoststr[16];
  		ViceLog(0,
! 			("Warning: h_TossStuff_r failed: Host %x (%s:%d) client %x was locked.\n",
! 			 host, afs_inet_ntoa_r(host->host, hoststr),
  			 ntohs(host->port), client));
  		return;
  	    }
***************
*** 957,964 ****
  	    if (client->refCount) {
  		char hoststr[16];
  		ViceLog(0,
! 			("Warning: h_TossStuff_r failed: Host %s:%d client %x refcount %d.\n",
! 			 afs_inet_ntoa_r(host->host, hoststr),
  			 ntohs(host->port), client, client->refCount));
  		/* This is the same thing we do if the host is locked */
  		ReleaseWriteLock(&client->lock);
--- 955,962 ----
  	    if (client->refCount) {
  		char hoststr[16];
  		ViceLog(0,
! 			("Warning: h_TossStuff_r failed: Host %x (%s:%d) client %x refcount %d.\n",
! 			 host, afs_inet_ntoa_r(host->host, hoststr),
  			 ntohs(host->port), client, client->refCount));
  		/* This is the same thing we do if the host is locked */
  		ReleaseWriteLock(&client->lock);
***************
*** 980,986 ****
      host->hostFlags &= ~CLIENTDELETED;
  
      if (host->hostFlags & HOSTDELETED) {
! 	register struct h_hashChain **hp, *th;
  	register struct rx_connection *rxconn;
  	afsUUID *uuidp;
  	struct AddrPort hostAddrPort;
--- 978,984 ----
      host->hostFlags &= ~CLIENTDELETED;
  
      if (host->hostFlags & HOSTDELETED) {
!         register struct h_AddrHashChain **ahp, *ath;
  	register struct rx_connection *rxconn;
  	afsUUID *uuidp;
  	struct AddrPort hostAddrPort;
***************
*** 1001,1049 ****
  
  	/* if alternate addresses do not exist */
  	if (!(host->interface)) {
! 	    for (hp = &hostHashTable[h_HashIndex(host->host)]; (th = *hp);
! 		 hp = &th->next) {
! 		assert(th->hostPtr);
! 		if (th->hostPtr == host) {
! 		    *hp = th->next;
! 		    h_DeleteList_r(host);
! 		    FreeHT(host);
! 		    free(th);
  		    break;
  		}
  	    }
  	} else {
! 	    /* delete all hash entries for the UUID */
  	    uuidp = &host->interface->uuid;
! 	    for (hp = &hostUuidHashTable[h_UuidHashIndex(uuidp)]; (th = *hp);
! 		 hp = &th->next) {
! 		assert(th->hostPtr);
! 		if (th->hostPtr == host) {
! 		    *hp = th->next;
! 		    free(th);
  		    break;
  		}
  	    }
! 	    /* delete all hash entries for alternate addresses */
! 	    assert(host->interface->numberOfInterfaces > 0);
  	    for (i = 0; i < host->interface->numberOfInterfaces; i++) {
  		hostAddrPort = host->interface->interface[i];
  
! 		for (hp = &hostHashTable[h_HashIndex(hostAddrPort.addr)]; (th = *hp);
! 		     hp = &th->next) {
! 		    assert(th->hostPtr);
! 		    if (th->hostPtr == host) {
! 			*hp = th->next;
! 			free(th);
  			break;
  		    }
  		}
  	    }
  	    free(host->interface);
  	    host->interface = NULL;
- 	    h_DeleteList_r(host);	/* remove host from global host List */
- 	    FreeHT(host);
  	}			/* if alternate address exists */
      }
  }				/*h_TossStuff_r */
  
--- 999,1049 ----
  
  	/* if alternate addresses do not exist */
  	if (!(host->interface)) {
! 	    for (ahp = &hostAddrHashTable[h_HashIndex(host->host)]; (ath = *ahp);
! 		 ahp = &ath->next) {
! 		assert(ath->hostPtr);
! 		if (ath->hostPtr == host) {
! 		    *ahp = ath->next;
! 		    free(ath);
  		    break;
  		}
  	    }
  	} else {
!             register struct h_UuidHashChain **uhp, *uth;
! 	    /* delete the hash entry for the UUID */
  	    uuidp = &host->interface->uuid;
! 	    for (uhp = &hostUuidHashTable[h_UuidHashIndex(uuidp)]; (uth = *uhp);
! 		 uhp = &uth->next) {
! 		assert(uth->hostPtr);
! 		if (uth->hostPtr == host) {
! 		    *uhp = uth->next;
! 		    free(uth);
  		    break;
  		}
  	    }
! 	    /* delete the hash entry for each alternate addresses */
  	    for (i = 0; i < host->interface->numberOfInterfaces; i++) {
  		hostAddrPort = host->interface->interface[i];
  
!                 if (!hostAddrPort.valid)
!                     continue;
! 
! 		for (ahp = &hostAddrHashTable[h_HashIndex(hostAddrPort.addr)]; (ath = *ahp);
! 		     ahp = &ath->next) {
! 		    assert(ath->hostPtr);
! 		    if (ath->hostPtr == host) {
! 			*ahp = ath->next;
! 			free(ath);
  			break;
  		    }
  		}
  	    }
  	    free(host->interface);
  	    host->interface = NULL;
  	}			/* if alternate address exists */
+ 
+         h_DeleteList_r(host);	/* remove host from global host List */
+         FreeHT(host);
      }
  }				/*h_TossStuff_r */
  
***************
*** 1132,1148 ****
  }				/*h_Enumerate_r */
  
  /* inserts a new HashChain structure corresponding to this UUID */
! static void
  h_AddHostToUuidHashTable_r(struct afsUUID *uuid, struct host *host)
  {
      int index;
!     struct h_hashChain *chain;
  
      /* hash into proper bucket */
      index = h_UuidHashIndex(uuid);
  
      /* insert into beginning of list for this bucket */
!     chain = (struct h_hashChain *)malloc(sizeof(struct h_hashChain));
      if (!chain) {
  	ViceLog(0, ("Failed malloc in h_AddHostToUuidHashTable_r\n"));
  	assert(0);
--- 1132,1154 ----
  }				/*h_Enumerate_r */
  
  /* inserts a new HashChain structure corresponding to this UUID */
! void
  h_AddHostToUuidHashTable_r(struct afsUUID *uuid, struct host *host)
  {
      int index;
!     struct h_UuidHashChain *chain;
  
      /* hash into proper bucket */
      index = h_UuidHashIndex(uuid);
  
+     /* don't add the same entry multiple times */
+     for (chain = hostUuidHashTable[index]; chain; chain = chain->next) {
+ 	if (host->interface && afs_uuid_equal(&host->interface->uuid, uuid))
+ 	    return;
+     }
+ 
      /* insert into beginning of list for this bucket */
!     chain = (struct h_UuidHashChain *)malloc(sizeof(struct h_UuidHashChain));
      if (!chain) {
  	ViceLog(0, ("Failed malloc in h_AddHostToUuidHashTable_r\n"));
  	assert(0);
***************
*** 1155,1193 ****
  
  
  /* inserts a new HashChain structure corresponding to this address */
! static void
! h_AddHostToHashTable_r(afs_uint32 addr, afs_uint16 port, struct host *host)
  {
      int index;
!     struct h_hashChain *chain;
  
      /* hash into proper bucket */
      index = h_HashIndex(addr);
  
      /* don't add the same entry multiple times */
!     for (chain = hostHashTable[index]; chain; chain = chain->next) {
! 	if (chain->hostPtr == host && chain->addr == addr && chain->port == port)
! 	    return;
      }
  
      /* insert into beginning of list for this bucket */
!     chain = (struct h_hashChain *)malloc(sizeof(struct h_hashChain));
      if (!chain) {
! 	ViceLog(0, ("Failed malloc in h_AddHostToHashTable_r\n"));
  	assert(0);
      }
      chain->hostPtr = host;
!     chain->next = hostHashTable[index];
      chain->addr = addr;
      chain->port = port;
!     hostHashTable[index] = chain;
  }
  
  /*
   * This is called with host locked and held. At this point, the
!  * hostHashTable should not be having entries for the alternate
   * interfaces. This function has to insert these entries in the
!  * hostHashTable.
   *
   * All addresses are in network byte order.
   */
--- 1161,1210 ----
  
  
  /* inserts a new HashChain structure corresponding to this address */
! void
! h_AddHostToAddrHashTable_r(afs_uint32 addr, afs_uint16 port, struct host *host)
  {
      int index;
!     struct h_AddrHashChain *chain;
!     int found = 0;
!     char hoststr[16];
  
      /* hash into proper bucket */
      index = h_HashIndex(addr);
  
      /* don't add the same entry multiple times */
!     for (chain = hostAddrHashTable[index]; chain; chain = chain->next) {
! 	if (chain->addr == addr && chain->port == port) {
!             if (chain->hostPtr == host)
!                 found = 1;
!             else if (!(host->hostFlags & HOSTDELETED))
!                 ViceLog(125, ("Addr %s:%d assigned to %x and %x.\n",
!                             afs_inet_ntoa_r(addr, hoststr), ntohs(port),
!                             host, chain));
!         }
      }
  
+     if (found)
+         return;
+ 
      /* insert into beginning of list for this bucket */
!     chain = (struct h_AddrHashChain *)malloc(sizeof(struct h_AddrHashChain));
      if (!chain) {
! 	ViceLog(0, ("Failed malloc in h_AddHostToAddrHashTable_r\n"));
  	assert(0);
      }
      chain->hostPtr = host;
!     chain->next = hostAddrHashTable[index];
      chain->addr = addr;
      chain->port = port;
!     hostAddrHashTable[index] = chain;
  }
  
  /*
   * This is called with host locked and held. At this point, the
!  * hostAddrHashTable should not have entries for the alternate
   * interfaces. This function has to insert these entries in the
!  * hostAddrHashTable.
   *
   * All addresses are in network byte order.
   */
***************
*** 1203,1212 ****
      assert(host);
      assert(host->interface);
  
-     ViceLog(125, ("addInterfaceAddr : host %s:%d addr %s:%d\n", 
- 		   afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port), 
- 		   afs_inet_ntoa_r(addr, hoststr2), ntohs(port)));
- 
      /*
       * Make sure this address is on the list of known addresses
       * for this host.
--- 1220,1225 ----
***************
*** 1214,1222 ****
      number = host->interface->numberOfInterfaces;
      for (i = 0, found = 0; i < number && !found; i++) {
  	if (host->interface->interface[i].addr == addr &&
! 	    host->interface->interface[i].port == port)
  	    found = 1;
      }
      if (!found) {
  	interface = (struct Interface *)
  	    malloc(sizeof(struct Interface) + (sizeof(struct AddrPort) * number));
--- 1227,1242 ----
      number = host->interface->numberOfInterfaces;
      for (i = 0, found = 0; i < number && !found; i++) {
  	if (host->interface->interface[i].addr == addr &&
!              host->interface->interface[i].port == port) {
  	    found = 1;
+             host->interface->interface[i].valid = 1;
+         }
      }
+ 
+     ViceLog(125, ("addInterfaceAddr : host %s:%d addr %s:%d : found:%d\n", 
+ 		   afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port), 
+ 		   afs_inet_ntoa_r(addr, hoststr2), ntohs(port), found));
+     
      if (!found) {
  	interface = (struct Interface *)
  	    malloc(sizeof(struct Interface) + (sizeof(struct AddrPort) * number));
***************
*** 1230,1253 ****
  	    interface->interface[i] = host->interface->interface[i];
  	interface->interface[number].addr = addr;
  	interface->interface[number].port = port;
  	free(host->interface);
  	host->interface = interface;
      }
  
-     /*
-      * Create a hash table entry for this address
-      */
-     h_AddHostToHashTable_r(addr, port, host);
- 
      return 0;
  }
  
  
  /*
   * This is called with host locked and held. At this point, the
!  * hostHashTable should not be having entries for the alternate
   * interfaces. This function has to insert these entries in the
!  * hostHashTable.
   *
   * All addresses are in network byte order.
   */
--- 1250,1269 ----
  	    interface->interface[i] = host->interface->interface[i];
  	interface->interface[number].addr = addr;
  	interface->interface[number].port = port;
+         interface->interface[number].valid = 1;
  	free(host->interface);
  	host->interface = interface;
      }
  
      return 0;
  }
  
  
  /*
   * This is called with host locked and held. At this point, the
!  * hostAddrHashTable should not be having entries for the alternate
   * interfaces. This function has to insert these entries in the
!  * hostAddrHashTable.
   *
   * All addresses are in network byte order.
   */
***************
*** 1273,1290 ****
       */
      interface = host->interface;
      number = host->interface->numberOfInterfaces;
!     for (i = 0, found = 0; i < number; i++) {
  	if (interface->interface[i].addr == addr &&
  	    interface->interface[i].port == port) {
  	    found = 1;
! 	    break;
  	}
      }
      if (found) {
  	number--;
  	for (; i < number; i++) {
! 	    interface->interface[i].addr = interface->interface[i+1].addr;
! 	    interface->interface[i].port = interface->interface[i+1].port;
  	}
  	interface->numberOfInterfaces = number;
      }
--- 1289,1305 ----
       */
      interface = host->interface;
      number = host->interface->numberOfInterfaces;
!     for (i = 0, found = 0; i < number && !found; i++) {
  	if (interface->interface[i].addr == addr &&
  	    interface->interface[i].port == port) {
  	    found = 1;
!             interface->interface[i].valid = 0;
  	}
      }
      if (found) {
  	number--;
  	for (; i < number; i++) {
! 	    interface->interface[i] = interface->interface[i+1];
  	}
  	interface->numberOfInterfaces = number;
      }
***************
*** 1292,1302 ****
      /*
       * Remove the hash table entry for this address
       */
!     h_DeleteHostFromHashTableByAddr_r(addr, port, host);
  
      return 0;
  }
  
  
  /* Host is returned held */
  struct host *
--- 1307,1415 ----
      /*
       * Remove the hash table entry for this address
       */
!     h_DeleteHostFromAddrHashTable_r(addr, port, host);
  
      return 0;
  }
  
+ /*
+  * This is called with host locked and held.  This function differs
+  * from removeInterfaceAddr_r in that it is called when the address
+  * is being removed from the host regardless of whether or not there
+  * is an interface list for the host.  This function will delete the
+  * host if there are no addresses left on it.
+  *
+  * All addresses are in network byte order.
+  */
+ int
+ removeAddress_r(struct host *host, afs_uint32 addr, afs_uint16 port)
+ {
+     int i;
+     char hoststr[16], hoststr2[16];
+ 
+     if (!host->interface) {
+         if (host->host == addr && host->port == port) {
+             ViceLog(25,
+                     ("Removing only address for host %x (%s:%d), deleting host.\n",
+                      host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
+             host->hostFlags |= HOSTDELETED;
+         }
+     } else {
+         removeInterfaceAddr_r(host, host->host, host->port);
+         if (host->interface->numberOfInterfaces == 0) {
+             ViceLog(25,
+                      ("Removed only address for host %x (%s:%d), no alternate interfaces, deleting host.\n",
+                        host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
+             host->hostFlags |= HOSTDELETED;
+         } else {
+             struct rx_connection *rxconn;
+ 
+             rxconn = host->callback_rxcon;
+             host->callback_rxcon = NULL;
+ 
+             if (rxconn) {
+                 struct client *client;
+                 /*
+                 * If rx_DestroyConnection calls h_FreeConnection we will
+                 * deadlock on the host_glock_mutex. Work around the problem
+                 * by unhooking the client from the connection before
+                 * destroying the connection.
+                 */
+                 client = rx_GetSpecific(rxconn, rxcon_client_key);
+                 rx_SetSpecific(rxconn, rxcon_client_key, (void *)0);
+                 rx_DestroyConnection(rxconn);
+             }
+ 
+             for (i=0; i < host->interface->numberOfInterfaces; i++) {
+                 if (host->interface->interface[i].valid) {
+                     ViceLog(25,
+                              ("Removed address for host %x (%s:%d), new primary interface %s:%d.\n",
+                                host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port),
+                                afs_inet_ntoa_r(host->interface->interface[i].addr, hoststr2), 
+                                ntohs(host->interface->interface[i].port)));
+                     host->host = host->interface->interface[i].addr;
+                     host->port = host->interface->interface[i].port;
+                     h_AddHostToAddrHashTable_r(host->host, host->port, host);
+                     break;
+                 }
+             }
+ 
+             if (i == host->interface->numberOfInterfaces) {
+                 ViceLog(25,
+                          ("Removed only address for host %x (%s:%d), no valid alternate interfaces, deleting host.\n",
+                            host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
+                 host->hostFlags |= HOSTDELETED;
+             } else {
+                 if (!sc)
+                     sc = rxnull_NewClientSecurityObject();
+                 host->callback_rxcon =
+                     rx_NewConnection(host->host, host->port, 1, sc, 0);
+                 rx_SetConnDeadTime(host->callback_rxcon, 50);
+                 rx_SetConnHardDeadTime(host->callback_rxcon, AFS_HARDDEADTIME);
+             }
+         }
+     }
+ 
+     return 0;
+ }
+ int 
+ h_threadquota(int waiting) 
+ {
+     if (lwps > 64) {
+ 	if (waiting > 5)
+ 	    return 1;
+     } else if (lwps > 32) {
+ 	if (waiting > 4)
+ 	    return 1;
+     } else if (lwps > 16) {
+ 	if (waiting > 3)
+ 	    return 1;
+     } else {
+ 	if (waiting > 2)
+ 	    return 1;
+     }
+     return 0;
+ }
  
  /* Host is returned held */
  struct host *
***************
*** 1305,1311 ****
      struct host *host;
      struct host *oldHost;
      int code;
!     int held, oheld;
      struct interfaceAddr interf;
      int interfValid = 0;
      struct Identity *identP = NULL;
--- 1418,1424 ----
      struct host *host;
      struct host *oldHost;
      int code;
!     int held;
      struct interfaceAddr interf;
      int interfValid = 0;
      struct Identity *identP = NULL;
***************
*** 1333,1347 ****
  	 * structure for this address. Verify that the identity
  	 * of the caller matches the identity in the host structure.
  	 */
  	h_Lock_r(host);
  	if (!(host->hostFlags & ALTADDR)) {
  	    /* Another thread is doing initialization */
  	    h_Unlock_r(host);
  	    if (!held)
  		h_Release_r(host);
  	    ViceLog(125,
! 		    ("Host %s:%d starting h_Lookup again\n",
! 		     afs_inet_ntoa_r(host->host, hoststr),
  		     ntohs(host->port)));
  	    goto retry;
  	}
--- 1446,1464 ----
  	 * structure for this address. Verify that the identity
  	 * of the caller matches the identity in the host structure.
  	 */
+ 	if ((host->hostFlags & HWHO_INPROGRESS) && 
+ 	    h_threadquota(host->lock.num_waiting))
+ 	    return 0;
  	h_Lock_r(host);
  	if (!(host->hostFlags & ALTADDR)) {
+ 	    host->hostFlags &= ~HWHO_INPROGRESS;
  	    /* Another thread is doing initialization */
  	    h_Unlock_r(host);
  	    if (!held)
  		h_Release_r(host);
  	    ViceLog(125,
! 		    ("Host %x (%s:%d) starting h_Lookup again\n",
! 		     host, afs_inet_ntoa_r(host->host, hoststr),
  		     ntohs(host->port)));
  	    goto retry;
  	}
***************
*** 1356,1362 ****
  	rx_PutConnection(cb_conn);
  	cb_conn=NULL;
  	H_LOCK;
! 	if (code == RXGEN_OPCODE) {
  	    identP = (struct Identity *)malloc(sizeof(struct Identity));
  	    if (!identP) {
  		ViceLog(0, ("Failed malloc in h_GetHost_r\n"));
--- 1473,1480 ----
  	rx_PutConnection(cb_conn);
  	cb_conn=NULL;
  	H_LOCK;
! 	if ((code == RXGEN_OPCODE) || 
! 	    (afs_uuid_equal(&interf.uuid, &nulluuid))) {
  	    identP = (struct Identity *)malloc(sizeof(struct Identity));
  	    if (!identP) {
  		ViceLog(0, ("Failed malloc in h_GetHost_r\n"));
***************
*** 1370,1379 ****
  	     * that we maintain some extra callback state information */
  	    if (host->interface) {
  		ViceLog(0,
! 			("Host %s:%d used to support WhoAreYou, deleting.\n",
! 			 afs_inet_ntoa_r(host->host, hoststr),
  			 ntohs(host->port)));
  		host->hostFlags |= HOSTDELETED;
  		h_Unlock_r(host);
  		if (!held)
  		    h_Release_r(host);
--- 1488,1499 ----
  	     * that we maintain some extra callback state information */
  	    if (host->interface) {
  		ViceLog(0,
! 			("Host %x (%s:%d) used to support WhoAreYou, deleting.\n",
! 			 host, 
!                          afs_inet_ntoa_r(host->host, hoststr),
  			 ntohs(host->port)));
  		host->hostFlags |= HOSTDELETED;
+ 		host->hostFlags &= ~HWHO_INPROGRESS;
  		h_Unlock_r(host);
  		if (!held)
  		    h_Release_r(host);
***************
*** 1395,1404 ****
  	     * then this is not the same host as before. */
  	    if (!host->interface
  		|| !afs_uuid_equal(&interf.uuid, &host->interface->uuid)) {
! 		ViceLog(25,
! 			("Host %s:%d has changed its identity, deleting.\n",
! 			 afs_inet_ntoa_r(host->host, hoststr), host->port));
! 		host->hostFlags |= HOSTDELETED;
  		h_Unlock_r(host);
  		if (!held)
  		    h_Release_r(host);
--- 1515,1526 ----
  	     * then this is not the same host as before. */
  	    if (!host->interface
  		|| !afs_uuid_equal(&interf.uuid, &host->interface->uuid)) {
!                 ViceLog(25,
!                          ("Uuid doesn't match host %x (%s:%d).\n",
!                            host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
! 
!                 removeAddress_r(host, host->host, host->port);
! 		host->hostFlags &= ~HWHO_INPROGRESS;
  		h_Unlock_r(host);
  		if (!held)
  		    h_Release_r(host);
***************
*** 1406,1414 ****
  		goto retry;
  	    }
  	} else {
- 	    afs_inet_ntoa_r(host->host, hoststr);
  	    ViceLog(0,
! 		    ("CB: WhoAreYou failed for %s:%d, error %d\n", hoststr,
  		     ntohs(host->port), code));
  	    host->hostFlags |= VENUSDOWN;
  	}
--- 1528,1536 ----
  		goto retry;
  	    }
  	} else {
  	    ViceLog(0,
! 		    ("CB: WhoAreYou failed for host %x (%s:%d), error %d\n",
!                      host, afs_inet_ntoa_r(host->host, hoststr),
  		     ntohs(host->port), code));
  	    host->hostFlags |= VENUSDOWN;
  	}
***************
*** 1418,1438 ****
  	else
  	    host->hostFlags &= ~(HERRORTRANS);
  	host->hostFlags |= ALTADDR;
  	h_Unlock_r(host);
      } else if (host) {
  	if (!(host->hostFlags & ALTADDR)) {
  	    /* another thread is doing the initialisation */
  	    ViceLog(125,
! 		    ("Host %s:%d waiting for host-init to complete\n",
! 		     afs_inet_ntoa_r(host->host, hoststr),
  		     ntohs(host->port)));
  	    h_Lock_r(host);
  	    h_Unlock_r(host);
  	    if (!held)
  		h_Release_r(host);
  	    ViceLog(125,
! 		    ("Host %s:%d starting h_Lookup again\n",
! 		     afs_inet_ntoa_r(host->host, hoststr),
  		     ntohs(host->port)));
  	    goto retry;
  	}
--- 1540,1562 ----
  	else
  	    host->hostFlags &= ~(HERRORTRANS);
  	host->hostFlags |= ALTADDR;
+ 	host->hostFlags &= ~HWHO_INPROGRESS;
  	h_Unlock_r(host);
      } else if (host) {
  	if (!(host->hostFlags & ALTADDR)) {
  	    /* another thread is doing the initialisation */
  	    ViceLog(125,
! 		    ("Host %x (%s:%d) waiting for host-init to complete\n",
! 		     host, afs_inet_ntoa_r(host->host, hoststr),
  		     ntohs(host->port)));
  	    h_Lock_r(host);
+ 	    host->hostFlags &= ~HWHO_INPROGRESS;
  	    h_Unlock_r(host);
  	    if (!held)
  		h_Release_r(host);
  	    ViceLog(125,
! 		    ("Host %x (%s:%d) starting h_Lookup again\n",
! 		     host, afs_inet_ntoa_r(host->host, hoststr),
  		     ntohs(host->port)));
  	    goto retry;
  	}
***************
*** 1451,1464 ****
  	    if (host->interface)
  		afsUUID_to_string(&host->interface->uuid, uuid2, 127);
  	    ViceLog(0,
! 		    ("CB: new identity for host %s:%d, deleting(%x %x %s %s)\n",
! 		     afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port),
  		     identP->valid, host->interface,
! 		     identP->valid ? uuid1 : "",
! 		     host->interface ? uuid2 : ""));
  
  	    /* The host in the cache is not the host for this connection */
  	    host->hostFlags |= HOSTDELETED;
  	    h_Unlock_r(host);
  	    if (!held)
  		h_Release_r(host);
--- 1575,1589 ----
  	    if (host->interface)
  		afsUUID_to_string(&host->interface->uuid, uuid2, 127);
  	    ViceLog(0,
! 		    ("CB: new identity for host %x (%s:%d), deleting(%x %x %s %s)\n",
! 		     host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port),
  		     identP->valid, host->interface,
! 		     identP->valid ? uuid1 : "no_uuid",
! 		     host->interface ? uuid2 : "no_uuid"));
  
  	    /* The host in the cache is not the host for this connection */
  	    host->hostFlags |= HOSTDELETED;
+ 	    host->hostFlags &= ~HWHO_INPROGRESS;
  	    h_Unlock_r(host);
  	    if (!held)
  		h_Release_r(host);
***************
*** 1479,1485 ****
  	    rx_PutConnection(cb_conn);
  	    cb_conn=NULL;
  	    H_LOCK;
! 	    if (code == RXGEN_OPCODE) {
  		if (!identP)
  		    identP =
  			(struct Identity *)malloc(sizeof(struct Identity));
--- 1604,1611 ----
  	    rx_PutConnection(cb_conn);
  	    cb_conn=NULL;
  	    H_LOCK;
! 	    if ((code == RXGEN_OPCODE) || 
! 		afs_uuid_equal(&interf.uuid, &nulluuid)) {
  		if (!identP)
  		    identP =
  			(struct Identity *)malloc(sizeof(struct Identity));
***************
*** 1494,1501 ****
  		if (!pident)
  		    rx_SetSpecific(tcon, rxcon_ident_key, identP);
  		ViceLog(25,
! 			("Host %s:%d does not support WhoAreYou.\n",
! 			 afs_inet_ntoa_r(host->host, hoststr),
  			 ntohs(host->port)));
  		code = 0;
  	    } else if (code == 0) {
--- 1620,1627 ----
  		if (!pident)
  		    rx_SetSpecific(tcon, rxcon_ident_key, identP);
  		ViceLog(25,
! 			("Host %x (%s:%d) does not support WhoAreYou.\n",
! 			 host, afs_inet_ntoa_r(host->host, hoststr),
  			 ntohs(host->port)));
  		code = 0;
  	    } else if (code == 0) {
***************
*** 1515,1522 ****
  		if (!pident)
  		    rx_SetSpecific(tcon, rxcon_ident_key, identP);
  		ViceLog(25,
! 			("WhoAreYou success on %s:%d\n",
! 			 afs_inet_ntoa_r(host->host, hoststr),
  			 ntohs(host->port)));
  	    }
  	    if (code == 0 && !identP->valid) {
--- 1641,1648 ----
  		if (!pident)
  		    rx_SetSpecific(tcon, rxcon_ident_key, identP);
  		ViceLog(25,
! 			("WhoAreYou success on host %x (%s:%d)\n",
! 			 host, afs_inet_ntoa_r(host->host, hoststr),
  			 ntohs(host->port)));
  	    }
  	    if (code == 0 && !identP->valid) {
***************
*** 1532,1540 ****
                  if (oldHost) {
                      int probefail = 0;
  
! 		    if (!(oheld = h_Held_r(oldHost)))
  			h_Hold_r(oldHost);
  		    h_Lock_r(oldHost);
  
                      if (oldHost->interface) {
  			int code2;
--- 1658,1667 ----
                  if (oldHost) {
                      int probefail = 0;
  
! 		    if (!h_Held_r(oldHost))
  			h_Hold_r(oldHost);
  		    h_Lock_r(oldHost);
+ 		    oldHost->hostFlags |= HWHO_INPROGRESS;
  
                      if (oldHost->interface) {
  			int code2;
***************
*** 1556,1563 ****
  			     * MultiProbeAlternateAddress_r() will remove the
  			     * alternate interfaces that do not have the same
  			     * Uuid. */
! 			    ViceLog(0,("CB: ProbeUuid for %s:%d failed %d\n",
! 					 afs_inet_ntoa_r(oldHost->host, hoststr),
  					 ntohs(oldHost->port),code2));
  			    MultiProbeAlternateAddress_r(oldHost);
                              probefail = 1;
--- 1683,1691 ----
  			     * MultiProbeAlternateAddress_r() will remove the
  			     * alternate interfaces that do not have the same
  			     * Uuid. */
! 			    ViceLog(0,("CB: ProbeUuid for host %x (%s:%d) failed %d\n",
! 					 oldHost, 
!                                          afs_inet_ntoa_r(oldHost->host, hoststr),
  					 ntohs(oldHost->port),code2));
  			    MultiProbeAlternateAddress_r(oldHost);
                              probefail = 1;
***************
*** 1569,1583 ****
  		    /* This is a new address for an existing host. Update
  		     * the list of interfaces for the existing host and
  		     * delete the host structure we just allocated. */
  		    if (oldHost->host != haddr || oldHost->port != hport) {
  			struct rx_connection *rxconn;
  
  			ViceLog(25,
! 				("CB: new addr %s:%d for old host %s:%d\n",
! 				  afs_inet_ntoa_r(haddr, hoststr),
! 				  ntohs(hport), 
! 				  afs_inet_ntoa_r(oldHost->host, hoststr2),
! 				  ntohs(oldHost->port)));
  			if (probefail || oldHost->host == haddr) {
  			    /* The probe failed which means that the old address is 
  			     * either unreachable or is not the same host we were just
--- 1697,1716 ----
  		    /* This is a new address for an existing host. Update
  		     * the list of interfaces for the existing host and
  		     * delete the host structure we just allocated. */
+ 
+                     /* prevent warnings while manipulating interface lists */
+ 		    host->hostFlags |= HOSTDELETED;
+ 
  		    if (oldHost->host != haddr || oldHost->port != hport) {
  			struct rx_connection *rxconn;
  
  			ViceLog(25,
!                                  ("CB: Host %x (%s:%d) has new addr %s:%d\n",
!                                    oldHost, 
!                                    afs_inet_ntoa_r(oldHost->host, hoststr2),
!                                    ntohs(oldHost->port),
!                                    afs_inet_ntoa_r(haddr, hoststr),
!                                    ntohs(hport)));
  			if (probefail || oldHost->host == haddr) {
  			    /* The probe failed which means that the old address is 
  			     * either unreachable or is not the same host we were just
***************
*** 1624,1630 ****
  			    rx_DestroyConnection(rxconn);
  			}
  		    }
! 		    host->hostFlags |= HOSTDELETED;
  		    h_Unlock_r(host);
  		    /* release host because it was allocated by h_Alloc_r */
  		    h_Release_r(host);
--- 1757,1763 ----
  			    rx_DestroyConnection(rxconn);
  			}
  		    }
! 		    host->hostFlags &= ~HWHO_INPROGRESS;
  		    h_Unlock_r(host);
  		    /* release host because it was allocated by h_Alloc_r */
  		    h_Release_r(host);
***************
*** 1641,1651 ****
  						   &FS_HostUUID);
  		    rx_PutConnection(cb_conn);
  		    cb_conn=NULL;
- 		    H_LOCK;
  		    if (code == 0) {
  			ViceLog(25,
! 				("InitCallBackState3 success on %s:%d\n",
! 				 afs_inet_ntoa_r(host->host, hoststr),
  				 ntohs(host->port)));
  			assert(interfValid == 1);
  			initInterfaceAddr_r(host, &interf);
--- 1774,1783 ----
  						   &FS_HostUUID);
  		    rx_PutConnection(cb_conn);
  		    cb_conn=NULL;
  		    if (code == 0) {
  			ViceLog(25,
! 				("InitCallBackState3 success on host %x (%s:%d)\n",
! 				 host, afs_inet_ntoa_r(host->host, hoststr),
  				 ntohs(host->port)));
  			assert(interfValid == 1);
  			initInterfaceAddr_r(host, &interf);
***************
*** 1653,1667 ****
  		}
  	    }
  	    if (code) {
- 		afs_inet_ntoa_r(host->host, hoststr);
  		ViceLog(0,
! 			("CB: RCallBackConnectBack failed for %s:%d\n",
! 			 hoststr, ntohs(host->port)));
  		host->hostFlags |= VENUSDOWN;
  	    } else {
  		ViceLog(125,
! 			("CB: RCallBackConnectBack succeeded for %s:%d\n",
! 			 hoststr, ntohs(host->port)));
  		host->hostFlags |= RESETDONE;
  	    }
  	}
--- 1785,1798 ----
  		}
  	    }
  	    if (code) {
  		ViceLog(0,
! 			("CB: RCallBackConnectBack failed for %x (%s:%d)\n",
! 			 host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
  		host->hostFlags |= VENUSDOWN;
  	    } else {
  		ViceLog(125,
! 			("CB: RCallBackConnectBack succeeded for %x (%s:%d)\n",
! 			 host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
  		host->hostFlags |= RESETDONE;
  	    }
  	}
***************
*** 1671,1676 ****
--- 1802,1808 ----
  	else
  	    host->hostFlags &= ~(HERRORTRANS);
  	host->hostFlags |= ALTADDR;	/* host structure initialization complete */
+ 	host->hostFlags &= ~HWHO_INPROGRESS;
  	h_Unlock_r(host);
      }
      if (caps.Capabilities_val)
***************
*** 1690,1695 ****
--- 1822,1828 ----
  void
  h_InitHostPackage()
  {
+     memset(&nulluuid, 0, sizeof(afsUUID));
      afsconf_GetLocalCell(confDir, localcellname, PR_MAXNAMELEN);
      if (num_lrealms == -1) {
  	int i;
***************
*** 1920,1925 ****
--- 2053,2061 ----
      if (!client) { /* loop */
  	host = h_GetHost_r(tcon);	/* Returns it h_Held */
  
+ 	if (!host) 
+ 	    return 0;
+ 
      retryfirstclient:
  	/* First try to find the client structure */
  	for (client = host->FirstClient; client; client = client->next) {
***************
*** 1982,1990 ****
  	    if (code) {
  		char hoststr[16];
  		ViceLog(0,
! 			("pr_GetCPS failed(%d) for user %d, host %s:%d\n",
! 			 code, viceid, afs_inet_ntoa_r(client->host->host,
! 						       hoststr),
  			 ntohs(client->host->port)));
  
  		/* Although ubik_Call (called by pr_GetCPS) traverses thru
--- 2118,2126 ----
  	    if (code) {
  		char hoststr[16];
  		ViceLog(0,
! 			("pr_GetCPS failed(%d) for user %d, host %x (%s:%d)\n",
! 			 code, viceid, client->host, 
!                          afs_inet_ntoa_r(client->host->host,hoststr),
  			 ntohs(client->host->port)));
  
  		/* Although ubik_Call (called by pr_GetCPS) traverses thru
***************
*** 2089,2102 ****
  GetClient(struct rx_connection *tcon, struct client **cp)
  {
      register struct client *client;
  
      H_LOCK;
      *cp = NULL;
      client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
      if (client == NULL) {
  	ViceLog(0,
! 		("GetClient: no client in conn %x (host %x:%d), VBUSYING\n",
! 		 tcon, rxr_HostOf(tcon),ntohs(rxr_PortOf(tcon))));
  	H_UNLOCK;
  	return VBUSY;
      }
--- 2225,2240 ----
  GetClient(struct rx_connection *tcon, struct client **cp)
  {
      register struct client *client;
+     char hoststr[16];
  
      H_LOCK;
      *cp = NULL;
      client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
      if (client == NULL) {
  	ViceLog(0,
! 		("GetClient: no client in conn %x (host %s:%d), VBUSYING\n",
! 		 tcon, afs_inet_ntoa_r(rxr_HostOf(tcon), hoststr),
!                  ntohs(rxr_PortOf(tcon))));
  	H_UNLOCK;
  	return VBUSY;
      }
***************
*** 2108,2114 ****
  	return VBUSY;
      }
      if (client && client->LastCall > client->expTime && client->expTime) {
- 	char hoststr[16];
  	ViceLog(1,
  		("Token for %s at %s:%d expired %d\n", h_UserName(client),
  		 afs_inet_ntoa_r(client->host->host, hoststr),
--- 2246,2251 ----
***************
*** 2144,2150 ****
      static char User[PR_MAXNAMELEN + 1];
      namelist lnames;
      idlist lids;
-     afs_int32 code;
  
      lids.idlist_len = 1;
      lids.idlist_val = (afs_int32 *) malloc(1 * sizeof(afs_int32));
--- 2281,2286 ----
***************
*** 2164,2170 ****
      free(lids.idlist_val);
      free(lnames.namelist_val);
      return User;
- 
  }				/*h_UserName */
  
  
--- 2300,2305 ----
***************
*** 2495,2506 ****
  {
      int ret = 0, found = 0;
      struct host *host = NULL;
!     struct h_hashChain *chain;
      int index = h_HashIndex(addr);
      char tmp[16];
      int chain_len = 0;
  
!     for (chain = hostHashTable[index]; chain; chain = chain->next) {
  	host = chain->hostPtr;
  	if (host == NULL) {
  	    afs_inet_ntoa_r(addr, tmp);
--- 2630,2641 ----
  {
      int ret = 0, found = 0;
      struct host *host = NULL;
!     struct h_AddrHashChain *chain;
      int index = h_HashIndex(addr);
      char tmp[16];
      int chain_len = 0;
  
!     for (chain = hostAddrHashTable[index]; chain; chain = chain->next) {
  	host = chain->hostPtr;
  	if (host == NULL) {
  	    afs_inet_ntoa_r(addr, tmp);
***************
*** 2547,2553 ****
  {
      int ret = 0, found = 0;
      struct host *host = NULL;
!     struct h_hashChain *chain;
      afsUUID * uuidp = &h->interface->uuid;
      int index = h_UuidHashIndex(uuidp);
      char tmp[40];
--- 2682,2688 ----
  {
      int ret = 0, found = 0;
      struct host *host = NULL;
!     struct h_UuidHashChain *chain;
      afsUUID * uuidp = &h->interface->uuid;
      int index = h_UuidHashIndex(uuidp);
      char tmp[40];
***************
*** 2787,2799 ****
      if (ifp) {
  	int i;
  	for (i = ifp->numberOfInterfaces-1; i >= 0; i--) {
- 	    h_AddHostToHashTable_r(ifp->interface[i].addr, 
- 				   ifp->interface[i].port, host);
  	}
  	h_AddHostToUuidHashTable_r(&ifp->uuid, host);
-     } else {
- 	h_AddHostToHashTable_r(host->host, host->port, host);
      }
      h_InsertList_r(host);
  
      /* setup host id map entry */
--- 2922,2931 ----
      if (ifp) {
  	int i;
  	for (i = ifp->numberOfInterfaces-1; i >= 0; i--) {
  	}
  	h_AddHostToUuidHashTable_r(&ifp->uuid, host);
      }
+     h_AddHostToAddrHashTable_r(host->host, host->port, host);
      h_InsertList_r(host);
  
      /* setup host id map entry */
***************
*** 3115,3120 ****
--- 3247,3253 ----
      }
      if (host->LastCall < checktime) {
  	h_Lock_r(host);
+ 	host->hostFlags |= HWHO_INPROGRESS;
  	if (!(host->hostFlags & HOSTDELETED)) {
  	    cb_conn = host->callback_rxcon;
  	    rx_GetConnection(cb_conn);
***************
*** 3184,3189 ****
--- 3317,3323 ----
  	    cb_conn=NULL;
  	    H_LOCK;
  	}
+ 	host->hostFlags &= ~HWHO_INPROGRESS;
  	h_Unlock_r(host);
      }
      H_UNLOCK;
***************
*** 3219,3227 ****
  
  /*
   * This is called with host locked and held. At this point, the
!  * hostHashTable should not have any entries for the alternate
   * interfaces. This function has to insert these entries in the
!  * hostHashTable.
   *
   * The addresses in the interfaceAddr list are in host byte order.
   */
--- 3353,3361 ----
  
  /*
   * This is called with host locked and held. At this point, the
!  * hostAddrHashTable should not have any entries for the alternate
   * interfaces. This function has to insert these entries in the
!  * hostAddrHashTable.
   *
   * The addresses in the interfaceAddr list are in host byte order.
   */
***************
*** 3235,3240 ****
--- 3369,3376 ----
      int found;
      struct Interface *interface;
      char hoststr[16];
+     char uuidstr[128];
+     afs_uint16 port7001 = htons(7001);
  
      assert(host);
      assert(interf);
***************
*** 3255,3262 ****
      }
  
      /*
!      * Convert IP addresses to network byte order, and remove for
!      * duplicate IP addresses from the interface list.
       */
      for (i = 0, count = 0, found = 0; i < number; i++) {
  	interf->addr_in[i] = htonl(interf->addr_in[i]);
--- 3391,3429 ----
      }
  
      /*
!      * The client's notion of its own IP addresses is not reliable.  
!      *
!      * 1. The client list might contain private address ranges which
!      *    are likely to be re-used by many clients allocated addresses
!      *    by a NAT.
!      *
!      * 2. The client list will not include any public addresses that
!      *    are hidden by a NAT.
!      *
!      * 3. Private address ranges that are exposed to the server will
!      *    be obtained from the rx connections that use them.
!      *
!      * 4. Lists provided by the client are not necessarily truthful.
!      *    Many existing clients (UNIX) do not refresh the IP address
!      *    list as the actual assigned addresses change.  The end result
!      *    is that they report the initial address list for the lifetime
!      *    of the process.  In other words, a client can report addresses
!      *    that they are in fact not using.  Adding these addresses to
!      *    the host interface list without verification is not only
!      *    pointless, it is downright dangerous.
!      *
!      * We therefore do not add alternate addresses to the addr hash table.
!      * We only use them for multi-rx callback breaks.
!      */
! 
!     /*
!      * Convert IP addresses to network byte order, and remove
!      * duplicate IP addresses from the interface list, and 
!      * determine whether or not the incoming addr/port is 
!      * listed.  Note that if the address matches it is not
!      * truly a match because the port number for the entries
!      * in the interface list are port 7001 and the port number
!      * for this connection might not be 7001.
       */
      for (i = 0, count = 0, found = 0; i < number; i++) {
  	interf->addr_in[i] = htonl(interf->addr_in[i]);
***************
*** 3266,3272 ****
  	}
  	if (j == count) {
  	    interf->addr_in[count] = interf->addr_in[i];
! 	    if (interf->addr_in[count] == myAddr)
  		found = 1;
  	    count++;
  	}
--- 3433,3440 ----
  	}
  	if (j == count) {
  	    interf->addr_in[count] = interf->addr_in[i];
! 	    if (interf->addr_in[count] == myAddr &&
!                 port7001 == myPort)
  		found = 1;
  	    count++;
  	}
***************
*** 3280,3310 ****
  	    malloc(sizeof(struct Interface) +
  		   (sizeof(struct AddrPort) * (count - 1)));
  	if (!interface) {
! 	    ViceLog(0, ("Failed malloc in initInterfaceAddr_r\n"));
  	    assert(0);
  	}
  	interface->numberOfInterfaces = count;
      } else {
  	interface = (struct Interface *)
  	    malloc(sizeof(struct Interface) + (sizeof(struct AddrPort) * count));
! 	assert(interface);
  	interface->numberOfInterfaces = count + 1;
  	interface->interface[count].addr = myAddr;
  	interface->interface[count].port = myPort;
      }
!     interface->uuid = interf->uuid;
      for (i = 0; i < count; i++) {
! 	interface->interface[i].addr = interf->addr_in[i];
  	/* We store the port as 7001 because the addresses reported by 
  	 * TellMeAboutYourself and WhoAreYou RPCs are only valid if they
  	 * are coming from fully connected hosts (no NAT/PATs)
  	 */
! 	interface->interface[i].port = htons(7001);
      }
  
      assert(!host->interface);
      host->interface = interface;
  
      for (i = 0; i < host->interface->numberOfInterfaces; i++) {
  	ViceLog(125, ("--- alt address %s:%d\n", 
  		       afs_inet_ntoa_r(host->interface->interface[i].addr, hoststr),
--- 3448,3489 ----
  	    malloc(sizeof(struct Interface) +
  		   (sizeof(struct AddrPort) * (count - 1)));
  	if (!interface) {
! 	    ViceLog(0, ("Failed malloc in initInterfaceAddr_r 1\n"));
  	    assert(0);
  	}
  	interface->numberOfInterfaces = count;
      } else {
  	interface = (struct Interface *)
  	    malloc(sizeof(struct Interface) + (sizeof(struct AddrPort) * count));
! 	if (!interface) {
! 	    ViceLog(0, ("Failed malloc in initInterfaceAddr_r 2\n"));
! 	    assert(0);
! 	}
  	interface->numberOfInterfaces = count + 1;
  	interface->interface[count].addr = myAddr;
  	interface->interface[count].port = myPort;
+         interface->interface[count].valid = 1;
      }
! 
      for (i = 0; i < count; i++) {
! 
!         interface->interface[i].addr = interf->addr_in[i];
  	/* We store the port as 7001 because the addresses reported by 
  	 * TellMeAboutYourself and WhoAreYou RPCs are only valid if they
  	 * are coming from fully connected hosts (no NAT/PATs)
  	 */
! 	interface->interface[i].port = port7001;
!         interface->interface[i].valid = 1;      /* valid until a conflict is found */
      }
  
+     interface->uuid = interf->uuid;
+ 
      assert(!host->interface);
      host->interface = interface;
  
+     afsUUID_to_string(&interface->uuid, uuidstr, 127);
+ 
+     ViceLog(125, ("--- uuid %s\n", uuidstr));
      for (i = 0; i < host->interface->numberOfInterfaces; i++) {
  	ViceLog(125, ("--- alt address %s:%d\n", 
  		       afs_inet_ntoa_r(host->interface->interface[i].addr, hoststr),
***************
*** 3316,3328 ****
  
  /* deleted a HashChain structure for this address and host */
  /* returns 1 on success */
! static int
! h_DeleteHostFromHashTableByAddr_r(afs_uint32 addr, afs_uint16 port, struct host *host)
  {
      int flag;
!     register struct h_hashChain **hp, *th;
  
!     for (hp = &hostHashTable[h_HashIndex(addr)]; (th = *hp);) {
  	assert(th->hostPtr);
  	if (th->hostPtr == host && th->addr == addr && th->port == port) {
  	    *hp = th->next;
--- 3495,3507 ----
  
  /* deleted a HashChain structure for this address and host */
  /* returns 1 on success */
! int
! h_DeleteHostFromAddrHashTable_r(afs_uint32 addr, afs_uint16 port, struct host *host)
  {
      int flag;
!     register struct h_AddrHashChain **hp, *th;
  
!     for (hp = &hostAddrHashTable[h_HashIndex(addr)]; (th = *hp);) {
  	assert(th->hostPtr);
  	if (th->hostPtr == host && th->addr == addr && th->port == port) {
  	    *hp = th->next;
***************
*** 3350,3359 ****
      if (host->interface) {
  	/* check alternate addresses */
  	number = host->interface->numberOfInterfaces;
! 	assert(number > 0);
! 	for (i = 0; i < number; i++)
! 	    ViceLog(level, ("%s:%d ", afs_inet_ntoa_r(host->interface->interface[i].addr, hoststr),
! 			     ntohs(host->interface->interface[i].port)));
      }
      ViceLog(level, ("\n"));
  }
--- 3529,3541 ----
      if (host->interface) {
  	/* check alternate addresses */
  	number = host->interface->numberOfInterfaces;
!         if (number == 0)
!             ViceLog(level, ("no-addresses "));
!         else {
!             for (i = 0; i < number; i++)
!                 ViceLog(level, ("%s:%d ", afs_inet_ntoa_r(host->interface->interface[i].addr, hoststr),
!                                 ntohs(host->interface->interface[i].port)));
!         }
      }
      ViceLog(level, ("\n"));
  }
Index: openafs/src/viced/host.h
diff -c openafs/src/viced/host.h:1.21.2.2 openafs/src/viced/host.h:1.21.2.4
*** openafs/src/viced/host.h:1.21.2.2	Mon Jul  3 14:46:06 2006
--- openafs/src/viced/host.h	Wed Aug  8 12:31:25 2007
***************
*** 57,62 ****
--- 57,63 ----
  struct AddrPort  {
      afs_uint32 addr;		/* in network byte order */
      afs_uint16 port;		/* in network byte order */
+     afs_int16  valid;
  };
  
  struct Interface {
***************
*** 109,121 ****
  /* * Don't zero the index, lock or condition varialbles */
  #define HOST_TO_ZERO(H) (int)(((char *)(&((H)->index))-(char *)(H)))
  
! struct h_hashChain {
      struct host *hostPtr;
!     struct h_hashChain *next;
      afs_uint32 addr;
      afs_uint16 port;
  };
  
  struct client {
      struct client *next;	/* next client entry for host */
      struct host *host;		/* ptr to parent host entry */
--- 110,127 ----
  /* * Don't zero the index, lock or condition varialbles */
  #define HOST_TO_ZERO(H) (int)(((char *)(&((H)->index))-(char *)(H)))
  
! struct h_AddrHashChain {
      struct host *hostPtr;
!     struct h_AddrHashChain *next;
      afs_uint32 addr;
      afs_uint16 port;
  };
  
+ struct h_UuidHashChain {
+     struct host *hostPtr;
+     struct h_UuidHashChain *next;
+ };
+ 
  struct client {
      struct client *next;	/* next client entry for host */
      struct host *host;		/* ptr to parent host entry */
***************
*** 249,254 ****
--- 255,267 ----
  extern void h_CheckHosts();
  struct Interface *MultiVerifyInterface_r();
  extern int initInterfaceAddr_r(struct host *host, struct interfaceAddr *interf);
+ extern void h_AddHostToAddrHashTable_r(afs_uint32 addr, afs_uint16 port, struct host * host);
+ extern void h_AddHostToUuidHashTable_r(afsUUID * uuid, struct host * host);
+ extern int h_DeleteHostFromAddrHashTable_r(afs_uint32 addr, afs_uint16 port, struct host *host);
+ extern int initInterfaceAddr_r(struct host *host, struct interfaceAddr *interf);
+ extern int addInterfaceAddr_r(struct host *host, afs_uint32 addr, afs_uint16 port);
+ extern int removeInterfaceAddr_r(struct host *host, afs_uint32 addr, afs_uint16 port);
+ 
  
  #ifdef AFS_DEMAND_ATTACH_FS
  /*
***************
*** 286,290 ****
  #define RESETDONE			0x40	/* callback reset done */
  #define HFE_LATER                       0x80	/* host has FE_LATER callbacks */
  #define HERRORTRANS                    0x100	/* do error translation */
! 
  #endif /* _AFS_VICED_HOST_H */
--- 299,303 ----
  #define RESETDONE			0x40	/* callback reset done */
  #define HFE_LATER                       0x80	/* host has FE_LATER callbacks */
  #define HERRORTRANS                    0x100	/* do error translation */
! #define HWHO_INPROGRESS                0x200    /* set when WhoAreYou running */
  #endif /* _AFS_VICED_HOST_H */
Index: openafs/src/viced/viced.c
diff -c openafs/src/viced/viced.c:1.75.2.10 openafs/src/viced/viced.c:1.75.2.13
*** openafs/src/viced/viced.c:1.75.2.10	Thu Feb  8 20:00:22 2007
--- openafs/src/viced/viced.c	Fri Aug 10 00:13:04 2007
***************
*** 22,28 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/viced.c,v 1.75.2.10 2007/02/09 01:00:22 shadow Exp $");
  
  #include <stdio.h>
  #include <stdlib.h>
--- 22,28 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/viced.c,v 1.75.2.13 2007/08/10 04:13:04 shadow Exp $");
  
  #include <stdio.h>
  #include <stdlib.h>
***************
*** 229,234 ****
--- 229,239 ----
   * certain background threads before we are allowed to dump state to
   * disk
   */
+ 
+ #if !defined(PTHREAD_RWLOCK_INITIALIZER) && defined(AFS_DARWIN80_ENV)
+ #define PTHREAD_RWLOCK_INITIALIZER {0x2DA8B3B4, {0}}
+ #endif
+ 
  struct fs_state fs_state = 
      { FS_MODE_NORMAL, 
        0, 
***************
*** 2185,2190 ****
--- 2190,2198 ----
  
  #ifdef AFS_PTHREAD_ENV
      ViceLog(5, ("Starting pthreads\n"));
+ #ifdef AFS_DEMAND_ATTACH_FS
+     FS_STATE_INIT;
+ #endif
      assert(pthread_attr_init(&tattr) == 0);
      assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
  
Index: openafs/src/viced/viced.h
diff -c openafs/src/viced/viced.h:1.8.2.1 openafs/src/viced/viced.h:1.8.2.2
*** openafs/src/viced/viced.h:1.8.2.1	Wed Aug  2 14:21:16 2006
--- openafs/src/viced/viced.h	Thu Jul 12 04:29:34 2007
***************
*** 246,251 ****
--- 246,252 ----
  extern struct fs_state fs_state;
  
  /* this lock is defined to be directly above FS_LOCK in the locking hierarchy */
+ #define FS_STATE_INIT    assert(pthread_rwlock_init(&fs_state.state_lock, NULL) == 0)
  #define FS_STATE_RDLOCK  assert(pthread_rwlock_rdlock(&fs_state.state_lock) == 0)
  #define FS_STATE_WRLOCK  assert(pthread_rwlock_wrlock(&fs_state.state_lock) == 0)
  #define FS_STATE_UNLOCK  assert(pthread_rwlock_unlock(&fs_state.state_lock) == 0)
Index: openafs/src/vol/volume.c
diff -c openafs/src/vol/volume.c:1.43.2.5 openafs/src/vol/volume.c:1.43.2.6
*** openafs/src/vol/volume.c:1.43.2.5	Sat Oct 21 22:00:12 2006
--- openafs/src/vol/volume.c	Fri Aug 10 00:13:05 2007
***************
*** 22,28 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/volume.c,v 1.43.2.5 2006/10/22 02:00:12 jaltman Exp $");
  
  #include <rx/xdr.h>
  #include <afs/afsint.h>
--- 22,28 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/volume.c,v 1.43.2.6 2007/08/10 04:13:05 shadow Exp $");
  
  #include <rx/xdr.h>
  #include <afs/afsint.h>
***************
*** 5997,6003 ****
      return buf;
  }
  
! static void
  VPrintExtendedCacheStats_r(int flags)
  {
      int i, j;
--- 5997,6003 ----
      return buf;
  }
  
! void
  VPrintExtendedCacheStats_r(int flags)
  {
      int i, j;
Index: openafs/src/volser/volint.xg
diff -c openafs/src/volser/volint.xg:1.5 openafs/src/volser/volint.xg:1.5.4.1
*** openafs/src/volser/volint.xg:1.5	Sat Oct 15 11:36:57 2005
--- openafs/src/volser/volint.xg	Thu Jul 19 14:52:14 2007
***************
*** 49,54 ****
--- 49,58 ----
  #define	    VOLFORWARDMULTIPLE  128
  #define     VOLCONVERTRO        65536
  #define     VOLGETSIZE          65537
+ #define     VOLDUMPV2           65538
+ 
+ /* Bits for flags for DumpV2 */
+ %#define     VOLDUMPV2_OMITDIRS 1
  
  const SIZE = 1024;
  
***************
*** 408,410 ****
--- 412,421 ----
    IN afs_int32 fromDate,
    OUT struct volintSize *size
  ) = VOLGETSIZE;
+ 
+ proc DumpV2(
+   IN afs_int32 fromTrans,
+   IN afs_int32 fromDate,
+   IN afs_int32 flags
+ ) split = VOLDUMPV2;
+ 
Index: openafs/src/volser/volprocs.c
diff -c openafs/src/volser/volprocs.c:1.42.2.3 openafs/src/volser/volprocs.c:1.42.2.4
*** openafs/src/volser/volprocs.c:1.42.2.3	Thu Feb  8 20:00:23 2007
--- openafs/src/volser/volprocs.c	Thu Jul 19 14:52:14 2007
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/volprocs.c,v 1.42.2.3 2007/02/09 01:00:23 shadow Exp $");
  
  #include <stdio.h>
  #include <sys/types.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/volprocs.c,v 1.42.2.4 2007/07/19 18:52:14 shadow Exp $");
  
  #include <stdio.h>
  #include <sys/types.h>
***************
*** 1279,1291 ****
  {
      afs_int32 code;
  
!     code = VolDump(acid, fromTrans, fromDate);
      osi_auditU(acid, VS_DumpEvent, code, AUD_LONG, fromTrans, AUD_END);
      return code;
  }
  
  afs_int32
! VolDump(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate)
  {
      int code = 0;
      register struct volser_trans *tt;
--- 1279,1301 ----
  {
      afs_int32 code;
  
!     code = VolDump(acid, fromTrans, fromDate, 0);
      osi_auditU(acid, VS_DumpEvent, code, AUD_LONG, fromTrans, AUD_END);
      return code;
  }
  
  afs_int32
! SAFSVolDumpV2(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate, afs_int32 flags)
! {
!     afs_int32 code;
! 
!     code = VolDump(acid, fromTrans, fromDate, flags);
!     osi_auditU(acid, VS_DumpEvent, code, AUD_LONG, fromTrans, AUD_END);
!     return code;
! }
! 
! afs_int32
! VolDump(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate, afs_int32 flags)
  {
      int code = 0;
      register struct volser_trans *tt;
***************
*** 1303,1309 ****
      }
      strcpy(tt->lastProcName, "Dump");
      tt->rxCallPtr = acid;
!     code = DumpVolume(acid, tt->volume, fromDate, 1);	/* squirt out the volume's data, too */
      if (code) {
  	tt->rxCallPtr = (struct rx_call *)0;
  	TRELE(tt);
--- 1313,1320 ----
      }
      strcpy(tt->lastProcName, "Dump");
      tt->rxCallPtr = acid;
!     code = DumpVolume(acid, tt->volume, fromDate, (flags & VOLDUMPV2_OMITDIRS)
! 		      ? 0 : 1);	/* squirt out the volume's data, too */
      if (code) {
  	tt->rxCallPtr = (struct rx_call *)0;
  	TRELE(tt);
Index: openafs/src/volser/volser_prototypes.h
diff -c openafs/src/volser/volser_prototypes.h:1.5 openafs/src/volser/volser_prototypes.h:1.5.8.1
*** openafs/src/volser/volser_prototypes.h:1.5	Sat Nov  6 02:02:44 2004
--- openafs/src/volser/volser_prototypes.h	Thu Jul 19 14:52:14 2007
***************
*** 47,53 ****
  extern void dump_sig_handler(int x);
  extern int UV_DumpVolume(afs_int32 afromvol, afs_int32 afromserver,
  			 afs_int32 afrompart, afs_int32 fromdate,
! 			 afs_int32(*DumpFunction) (), char *rock);
  extern int UV_RestoreVolume(afs_int32 toserver, afs_int32 topart,
  			    afs_int32 tovolid, char tovolname[], int flags,
  			    afs_int32(*WriteData) (), char *rock);
--- 47,53 ----
  extern void dump_sig_handler(int x);
  extern int UV_DumpVolume(afs_int32 afromvol, afs_int32 afromserver,
  			 afs_int32 afrompart, afs_int32 fromdate,
! 			 afs_int32(*DumpFunction) (), char *rock, afs_int32 flags);
  extern int UV_RestoreVolume(afs_int32 toserver, afs_int32 topart,
  			    afs_int32 tovolid, char tovolname[], int flags,
  			    afs_int32(*WriteData) (), char *rock);
Index: openafs/src/volser/vos.c
diff -c openafs/src/volser/vos.c:1.55.2.3 openafs/src/volser/vos.c:1.55.2.6
*** openafs/src/volser/vos.c:1.55.2.3	Wed May  9 20:16:57 2007
--- openafs/src/volser/vos.c	Thu Jul 19 14:52:14 2007
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/vos.c,v 1.55.2.3 2007/05/10 00:16:57 shadow Exp $");
  
  #include <sys/types.h>
  #ifdef AFS_NT40_ENV
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/vos.c,v 1.55.2.6 2007/07/19 18:52:14 shadow Exp $");
  
  #include <sys/types.h>
  #ifdef AFS_NT40_ENV
***************
*** 55,61 ****
--- 55,66 ----
  #include <afs/usd.h>
  #include "volser.h"
  #include "volint.h"
+ #include <afs/ihandle.h>
+ #include <afs/vnode.h>
+ #include <afs/volume.h>
+ #include "dump.h"
  #include "lockdata.h"
+ 
  #ifdef	AFS_AIX32_ENV
  #include <signal.h>
  #endif
***************
*** 313,318 ****
--- 318,326 ----
      long blksize;
      afs_int32 error, code;
      int ufdIsOpen = 0;
+     afs_hyper_t filesize, currOffset; 
+     afs_uint32 buffer;		
+     afs_uint32 got; 		
  
      error = 0;
  
***************
*** 333,338 ****
--- 341,360 ----
  	    goto wfail;
  	}
      }
+     /* test if we have a valid dump */
+     hset64(filesize, 0, 0);
+     USD_SEEK(ufd, filesize, SEEK_END, &currOffset);
+     hset64(filesize, hgethi(currOffset), hgetlo(currOffset)-sizeof(afs_uint32));
+     USD_SEEK(ufd, filesize, SEEK_SET, &currOffset);
+     USD_READ(ufd, &buffer, sizeof(afs_uint32), &got);
+     if ((got != sizeof(afs_uint32)) || (ntohl(buffer) != DUMPENDMAGIC)) {
+ 	fprintf(STDERR, "Signature missing from end of file '%s'\n", filename);
+         error = VOLSERBADOP;
+         goto wfail;
+     }
+     hset64(filesize, 0, 0);
+     USD_SEEK(ufd, filesize, SEEK_SET, &currOffset);
+     /* rewind, we are done */
      code = SendFile(ufd, call, blksize);
      if (code) {
  	error = code;
***************
*** 2784,2790 ****
       register struct cmd_syndesc *as;
  
  {
!     afs_int32 avolid, aserver, apart, voltype, fromdate = 0, code, err, i;
      char filename[MAXPATHLEN];
      struct nvldbentry entry;
  
--- 2806,2812 ----
       register struct cmd_syndesc *as;
  
  {
!     afs_int32 avolid, aserver, apart, voltype, fromdate = 0, code, err, i, flags;
      char filename[MAXPATHLEN];
      struct nvldbentry entry;
  
***************
*** 2844,2857 ****
  	strcpy(filename, "");
      }
  
      if (as->parms[5].items) {
  	code =
  	    UV_DumpClonedVolume(avolid, aserver, apart, fromdate,
! 				DumpFunction, filename);
      } else {
  	code =
  	    UV_DumpVolume(avolid, aserver, apart, fromdate, DumpFunction,
! 			  filename);
      }
      if (code) {
  	PrintDiagnostics("dump", code);
--- 2866,2885 ----
  	strcpy(filename, "");
      }
  
+     flags = as->parms[6].items ? VOLDUMPV2_OMITDIRS : 0;
+ retry_dump:
      if (as->parms[5].items) {
  	code =
  	    UV_DumpClonedVolume(avolid, aserver, apart, fromdate,
! 				DumpFunction, filename, flags);
      } else {
  	code =
  	    UV_DumpVolume(avolid, aserver, apart, fromdate, DumpFunction,
! 			  filename, flags);
!     }
!     if ((code == RXGEN_OPCODE) && (as->parms[6].items)) {
! 	flags &= ~VOLDUMPV2_OMITDIRS;
! 	goto retry_dump;
      }
      if (code) {
  	PrintDiagnostics("dump", code);
***************
*** 4166,4172 ****
  		fflush(STDOUT);
  		continue;
  	    }
! 	    vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, RWVOL);
  	    if (vcode) {
  		fprintf(STDERR, "Could not delete entry for volume %s\n",
  			itp->data);
--- 4194,4200 ----
  		fflush(STDOUT);
  		continue;
  	    }
! 	    vcode = ubik_VL_DeleteEntry(cstruct, 0, avolid, RWVOL);
  	    if (vcode) {
  		fprintf(STDERR, "Could not delete entry for volume %s\n",
  			itp->data);
***************
*** 4279,4285 ****
  
  	/* Only matches the RW volume name */
  	avolid = vllist->volumeId[RWVOL];
! 	vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, RWVOL);
  	if (vcode) {
  	    fprintf(STDOUT, "Could not delete VDLB entry for  %s\n",
  		    vllist->name);
--- 4307,4313 ----
  
  	/* Only matches the RW volume name */
  	avolid = vllist->volumeId[RWVOL];
! 	vcode = ubik_VL_DeleteEntry(cstruct, 0, avolid, RWVOL);
  	if (vcode) {
  	    fprintf(STDOUT, "Could not delete VDLB entry for  %s\n",
  		    vllist->name);
***************
*** 4914,4921 ****
  	vllist = &arrayEntries.nbulkentries_val[j];
  	volid = vllist->volumeId[RWVOL];
  	vcode =
! 	    ubik_Call(VL_ReleaseLock, cstruct, 0, volid, -1,
! 		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (vcode) {
  	    fprintf(STDERR, "Could not unlock entry for volume %s\n",
  		    vllist->name);
--- 4942,4950 ----
  	vllist = &arrayEntries.nbulkentries_val[j];
  	volid = vllist->volumeId[RWVOL];
  	vcode =
! 	    ubik_VL_ReleaseLock(cstruct, 0, volid, -1,
! 				LOCKREL_OPCODE | LOCKREL_AFSID | 
! 				LOCKREL_TIMESTAMP);
  	if (vcode) {
  	    fprintf(STDERR, "Could not unlock entry for volume %s\n",
  		    vllist->name);
***************
*** 5169,5176 ****
  		m_addrs.bulkaddrs_val = 0;
  		m_addrs.bulkaddrs_len = 0;
  		vcode =
! 		    ubik_Call(VL_GetAddrsU, cstruct, 0, &m_attrs, &m_uuid,
! 			      &vlcb, &m_nentries, &m_addrs);
  		if (vcode) {
  		    fprintf(STDERR,
  			    "vos: could not list the multi-homed server addresses\n");
--- 5198,5205 ----
  		m_addrs.bulkaddrs_val = 0;
  		m_addrs.bulkaddrs_len = 0;
  		vcode =
! 		    ubik_VL_GetAddrsU(cstruct, 0, &m_attrs, &m_uuid,
! 				      &vlcb, &m_nentries, &m_addrs);
  		if (vcode) {
  		    fprintf(STDERR,
  			    "vos: could not list the multi-homed server addresses\n");
***************
*** 5340,5346 ****
  		    as->parms[0].items->data);
  	exit(1);
      }
!     vcode = ubik_Call(VL_SetLock, cstruct, 0, avolid, -1, VLOP_DELETE);
      if (vcode) {
  	fprintf(STDERR, "Could not lock VLDB entry for volume %s\n",
  		as->parms[0].items->data);
--- 5369,5375 ----
  		    as->parms[0].items->data);
  	exit(1);
      }
!     vcode = ubik_VL_SetLock(cstruct, 0, avolid, -1, VLOP_DELETE);
      if (vcode) {
  	fprintf(STDERR, "Could not lock VLDB entry for volume %s\n",
  		as->parms[0].items->data);
***************
*** 5468,5474 ****
      }
  
      vcode =
! 	ubik_Call(VL_SetLock, cstruct, 0, entry.volumeId[RWVOL], RWVOL,
  		  VLOP_MOVE);
      aconn = UV_Bind(server, AFSCONF_VOLUMEPORT);
      code = AFSVolConvertROtoRWvolume(aconn, partition, volid);
--- 5497,5503 ----
      }
  
      vcode =
! 	ubik_VL_SetLock(cstruct, 0, entry.volumeId[RWVOL], RWVOL,
  		  VLOP_MOVE);
      aconn = UV_Bind(server, AFSCONF_VOLUMEPORT);
      code = AFSVolConvertROtoRWvolume(aconn, partition, volid);
***************
*** 5799,5804 ****
--- 5828,5835 ----
      cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition");
      cmd_AddParm(ts, "-clone", CMD_FLAG, CMD_OPTIONAL,
  		"dump a clone of the volume");
+     cmd_AddParm(ts, "-omitdirs", CMD_FLAG, CMD_OPTIONAL,
+ 		"omit unchanged directories from an incremental dump");
      COMMONPARMS;
  
      ts = cmd_CreateSyntax("restore", RestoreVolume, 0, "restore a volume");
Index: openafs/src/volser/vsprocs.c
diff -c openafs/src/volser/vsprocs.c:1.38.2.4 openafs/src/volser/vsprocs.c:1.38.2.6
*** openafs/src/volser/vsprocs.c:1.38.2.4	Mon Jul  2 13:08:03 2007
--- openafs/src/volser/vsprocs.c	Thu Jul 19 14:52:14 2007
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/vsprocs.c,v 1.38.2.4 2007/07/02 17:08:03 jaltman Exp $");
  
  #include <stdio.h>
  #include <sys/types.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/vsprocs.c,v 1.38.2.6 2007/07/19 18:52:14 shadow Exp $");
  
  #include <stdio.h>
  #include <sys/types.h>
***************
*** 643,649 ****
  
      aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT);
      /* next the next 3 available ids from the VLDB */
!     vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 3, anewid);
      EGOTO1(cfail, vcode, "Could not get an Id for volume %s\n", aname);
  
      code =
--- 643,649 ----
  
      aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT);
      /* next the next 3 available ids from the VLDB */
!     vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 3, anewid);
      EGOTO1(cfail, vcode, "Could not get an Id for volume %s\n", aname);
  
      code =
***************
*** 787,793 ****
      int notondisk = 0, notinvldb = 0;
  
      /* Find and read bhe VLDB entry for this volume */
!     code = ubik_Call(VL_SetLock, cstruct, 0, avolid, avoltype, VLOP_DELETE);
      if (code) {
  	if (code != VL_NOENT) {
  	    EGOTO1(error_exit, code,
--- 787,793 ----
      int notondisk = 0, notinvldb = 0;
  
      /* Find and read bhe VLDB entry for this volume */
!     code = ubik_VL_SetLock(cstruct, 0, avolid, avoltype, VLOP_DELETE);
      if (code) {
  	if (code != VL_NOENT) {
  	    EGOTO1(error_exit, code,
***************
*** 937,943 ****
  	    fprintf(STDOUT,
  		    "Last reference to the VLDB entry for %lu - deleting entry\n",
  		    (unsigned long)avolid);
! 	code = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, vtype);
  	EGOTO1(error_exit, code,
  	       "Could not delete the VLDB entry for the volume %u \n",
  	       avolid);
--- 937,943 ----
  	    fprintf(STDOUT,
  		    "Last reference to the VLDB entry for %lu - deleting entry\n",
  		    (unsigned long)avolid);
! 	code = ubik_VL_DeleteEntry(cstruct, 0, avolid, vtype);
  	EGOTO1(error_exit, code,
  	       "Could not delete the VLDB entry for the volume %u \n",
  	       avolid);
***************
*** 986,993 ****
  
      if (islocked) {
  	code =
! 	    ubik_Call(VL_ReleaseLock, cstruct, 0, avolid, -1,
! 		      (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
  	if (code) {
  	    EPRINT1(code,
  		    "Could not release the lock on the VLDB entry for the volume %u \n",
--- 986,994 ----
  
      if (islocked) {
  	code =
! 	    ubik_VL_ReleaseLock(cstruct, 0, avolid, -1,
! 				(LOCKREL_OPCODE | LOCKREL_AFSID | 
! 				 LOCKREL_TIMESTAMP));
  	if (code) {
  	    EPRINT1(code,
  		    "Could not release the lock on the VLDB entry for the volume %u \n",
***************
*** 1108,1114 ****
  	exit(1);
      }
  
!     vcode = ubik_Call(VL_SetLock, cstruct, 0, afromvol, RWVOL, VLOP_MOVE);
      EGOTO1(mfail, vcode, "Could not lock entry for volume %u \n", afromvol);
      islocked = 1;
  
--- 1109,1115 ----
  	exit(1);
      }
  
!     vcode = ubik_VL_SetLock(cstruct, 0, afromvol, RWVOL, VLOP_MOVE);
      EGOTO1(mfail, vcode, "Could not lock entry for volume %u \n", afromvol);
      islocked = 1;
  
***************
*** 1137,1143 ****
  		}
  	    }
  	    vcode =
! 		ubik_Call(VL_ReleaseLock, cstruct, 0, afromvol, -1,
  			  (LOCKREL_OPCODE | LOCKREL_AFSID |
  			   LOCKREL_TIMESTAMP));
  	    EGOTO1(mfail, vcode,
--- 1138,1144 ----
  		}
  	    }
  	    vcode =
! 		ubik_VL_ReleaseLock(cstruct, 0, afromvol, -1,
  			  (LOCKREL_OPCODE | LOCKREL_AFSID |
  			   LOCKREL_TIMESTAMP));
  	    EGOTO1(mfail, vcode,
***************
*** 1265,1271 ****
  	VPRINT1("Allocating new volume id for clone of volume %u ...",
  		afromvol);
  	newVol = 0;
! 	vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &newVol);
  	EGOTO1(mfail, vcode,
  	       "Could not get an ID for the clone of volume %u from the VLDB\n",
  	       afromvol);
--- 1266,1272 ----
  	VPRINT1("Allocating new volume id for clone of volume %u ...",
  		afromvol);
  	newVol = 0;
! 	vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &newVol);
  	EGOTO1(mfail, vcode,
  	       "Could not get an ID for the clone of volume %u from the VLDB\n",
  	       afromvol);
***************
*** 1683,1689 ****
      if (islocked) {
  	VPRINT1("Cleanup: Releasing VLDB lock on volume %u ...", afromvol);
  	vcode =
! 	    ubik_Call(VL_ReleaseLock, cstruct, 0, afromvol, -1,
  		      (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
  	if (vcode) {
  	    VPRINT("\n");
--- 1684,1690 ----
      if (islocked) {
  	VPRINT1("Cleanup: Releasing VLDB lock on volume %u ...", afromvol);
  	vcode =
! 	    ubik_VL_ReleaseLock(cstruct, 0, afromvol, -1,
  		      (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
  	if (vcode) {
  	    VPRINT("\n");
***************
*** 1765,1771 ****
      /* unlock VLDB entry */
      if (islocked) {
  	VPRINT1("Recovery: Releasing VLDB lock on volume %u ...", afromvol);
! 	ubik_Call(VL_ReleaseLock, cstruct, 0, afromvol, -1,
  		  (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
  	VDONE;
      }
--- 1766,1772 ----
      /* unlock VLDB entry */
      if (islocked) {
  	VPRINT1("Recovery: Releasing VLDB lock on volume %u ...", afromvol);
! 	ubik_VL_ReleaseLock(cstruct, 0, afromvol, -1,
  		  (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
  	VDONE;
      }
***************
*** 1975,1981 ****
      /* unlock VLDB entry */
      VPRINT1("Recovery: Releasing lock on VLDB entry for volume %u ...",
  	    afromvol);
!     ubik_Call(VL_ReleaseLock, cstruct, 0, afromvol, -1,
  	      (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
      VDONE;
  
--- 1976,1982 ----
      /* unlock VLDB entry */
      VPRINT1("Recovery: Releasing lock on VLDB entry for volume %u ...",
  	    afromvol);
!     ubik_VL_ReleaseLock(cstruct, 0, afromvol, -1,
  	      (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
      VDONE;
  
***************
*** 2089,2095 ****
  	VPRINT1("Allocating new volume id for clone of volume %u ...",
  		afromvol);
  	cloneVol = 0;
! 	vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &cloneVol);
  	EGOTO1(mfail, vcode,
  	   "Could not get an ID for the clone of volume %u from the VLDB\n",
  	   afromvol);
--- 2090,2096 ----
  	VPRINT1("Allocating new volume id for clone of volume %u ...",
  		afromvol);
  	cloneVol = 0;
! 	vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &cloneVol);
  	EGOTO1(mfail, vcode,
  	   "Could not get an ID for the clone of volume %u from the VLDB\n",
  	   afromvol);
***************
*** 2102,2108 ****
  	/* Get a new volume id */
  	VPRINT1("Allocating new volume id for copy of volume %u ...", afromvol);
  	newVol = 0;
! 	vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &newVol);
  	EGOTO1(mfail, vcode,
  	       "Could not get an ID for the copy of volume %u from the VLDB\n",
  	       afromvol);
--- 2103,2109 ----
  	/* Get a new volume id */
  	VPRINT1("Allocating new volume id for copy of volume %u ...", afromvol);
  	newVol = 0;
! 	vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &newVol);
  	EGOTO1(mfail, vcode,
  	       "Could not get an ID for the copy of volume %u from the VLDB\n",
  	       afromvol);
***************
*** 2560,2566 ****
  	(entry.flags & VLOP_ALLOPERS) ||	/* vldb lock already held */
  	(entry.volumeId[BACKVOL] == INVALID_BID)) {	/* no assigned backup volume id */
  
! 	code = ubik_Call(VL_SetLock, cstruct, 0, avolid, RWVOL, VLOP_BACKUP);
  	if (code) {
  	    fprintf(STDERR,
  		    "Could not lock the VLDB entry for the volume %lu\n",
--- 2561,2567 ----
  	(entry.flags & VLOP_ALLOPERS) ||	/* vldb lock already held */
  	(entry.volumeId[BACKVOL] == INVALID_BID)) {	/* no assigned backup volume id */
  
! 	code = ubik_VL_SetLock(cstruct, 0, avolid, RWVOL, VLOP_BACKUP);
  	if (code) {
  	    fprintf(STDERR,
  		    "Could not lock the VLDB entry for the volume %lu\n",
***************
*** 2594,2600 ****
  	/* Get a backup volume id from the VLDB and update the vldb
  	 * entry with it. 
  	 */
! 	code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &backupID);
  	if (code) {
  	    fprintf(STDERR,
  		    "Could not allocate ID for the backup volume of  %lu from the VLDB\n",
--- 2595,2601 ----
  	/* Get a backup volume id from the VLDB and update the vldb
  	 * entry with it. 
  	 */
! 	code = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &backupID);
  	if (code) {
  	    fprintf(STDERR,
  		    "Could not allocate ID for the backup volume of  %lu from the VLDB\n",
***************
*** 2758,2764 ****
  	    }
  	} else {
  	    code =
! 		ubik_Call(VL_ReleaseLock, cstruct, 0, avolid, RWVOL,
  			  (LOCKREL_OPCODE | LOCKREL_AFSID |
  			   LOCKREL_TIMESTAMP));
  	    if (code) {
--- 2759,2765 ----
  	    }
  	} else {
  	    code =
! 		ubik_VL_ReleaseLock(cstruct, 0, avolid, RWVOL,
  			  (LOCKREL_OPCODE | LOCKREL_AFSID |
  			   LOCKREL_TIMESTAMP));
  	    if (code) {
***************
*** 2825,2831 ****
  	/* Get a clone id */
  	VPRINT1("Allocating new volume id for clone of volume %u ...",
  		avolid);
! 	code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &acloneid);
  	EGOTO1(bfail, code,
  	   "Could not get an ID for the clone of volume %u from the VLDB\n",
  	   avolid);
--- 2826,2832 ----
  	/* Get a clone id */
  	VPRINT1("Allocating new volume id for clone of volume %u ...",
  		avolid);
! 	code = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &acloneid);
  	EGOTO1(bfail, code,
  	   "Could not get an ID for the clone of volume %u from the VLDB\n",
  	   avolid);
***************
*** 3174,3180 ****
      memset((char *)remembertime, 0, sizeof(remembertime));
      memset((char *)&results, 0, sizeof(results));
  
!     vcode = ubik_Call(VL_SetLock, cstruct, 0, afromvol, RWVOL, VLOP_RELEASE);
      if (vcode != VL_RERELEASE)
  	ONERROR(vcode, afromvol,
  		"Could not lock the VLDB entry for the volume %u.\n");
--- 3175,3181 ----
      memset((char *)remembertime, 0, sizeof(remembertime));
      memset((char *)&results, 0, sizeof(results));
  
!     vcode = ubik_VL_SetLock(cstruct, 0, afromvol, RWVOL, VLOP_RELEASE);
      if (vcode != VL_RERELEASE)
  	ONERROR(vcode, afromvol,
  		"Could not lock the VLDB entry for the volume %u.\n");
***************
*** 3216,3222 ****
      /* Make sure we have a RO volume id to work with */
      if (entry.volumeId[ROVOL] == INVALID_BID) {
  	/* need to get a new RO volume id */
! 	vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &roVolId);
  	ONERROR(vcode, entry.name, "Cant allocate ID for RO volume of %s\n");
  
  	entry.volumeId[ROVOL] = roVolId;
--- 3217,3223 ----
      /* Make sure we have a RO volume id to work with */
      if (entry.volumeId[ROVOL] == INVALID_BID) {
  	/* need to get a new RO volume id */
! 	vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &roVolId);
  	ONERROR(vcode, entry.name, "Cant allocate ID for RO volume of %s\n");
  
  	entry.volumeId[ROVOL] = roVolId;
***************
*** 3793,3799 ****
      }
      if (islocked) {
  	vcode =
! 	    ubik_Call(VL_ReleaseLock, cstruct, 0, afromvol, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (vcode) {
  	    fprintf(STDERR,
--- 3794,3800 ----
      }
      if (islocked) {
  	vcode =
! 	    ubik_VL_ReleaseLock(cstruct, 0, afromvol, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (vcode) {
  	    fprintf(STDERR,
***************
*** 3834,3845 ****
   */
  int
  UV_DumpVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
! 	      afs_int32 fromdate, afs_int32(*DumpFunction) (), char *rock)
  {
      struct rx_connection *fromconn = (struct rx_connection *)0;
      struct rx_call *fromcall = (struct rx_call *)0;
      afs_int32 fromtid = 0, rxError = 0, rcode = 0;
!     afs_int32 code, error = 0;
      time_t tmv = fromdate;
  
      if (setjmp(env))
--- 3835,3847 ----
   */
  int
  UV_DumpVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
! 	      afs_int32 fromdate, afs_int32(*DumpFunction) (), char *rock,
! 	      afs_int32 flags)
  {
      struct rx_connection *fromconn = (struct rx_connection *)0;
      struct rx_call *fromcall = (struct rx_call *)0;
      afs_int32 fromtid = 0, rxError = 0, rcode = 0;
!     afs_int32 code, error = 0, retry = 0;
      time_t tmv = fromdate;
  
      if (setjmp(env))
***************
*** 3869,3891 ****
      fromcall = rx_NewCall(fromconn);
  
      VPRINT1("Starting volume dump on volume %u...", afromvol);
!     code = StartAFSVolDump(fromcall, fromtid, fromdate);
      EGOTO(error_exit, code, "Could not start the dump process \n");
      VDONE;
  
      VPRINT1("Dumping volume %u...", afromvol);
      code = DumpFunction(fromcall, rock);
      EGOTO(error_exit, code, "Error while dumping volume \n");
      VDONE;
  
    error_exit:
      if (fromcall) {
  	code = rx_EndCall(fromcall, rxError);
! 	if (code) {
  	    fprintf(STDERR, "Error in rx_EndCall\n");
! 	    if (!error)
! 		error = code;
! 	}
      }
      if (fromtid) {
  	VPRINT1("Ending transaction on volume %u...", afromvol);
--- 3871,3898 ----
      fromcall = rx_NewCall(fromconn);
  
      VPRINT1("Starting volume dump on volume %u...", afromvol);
!     if (flags & VOLDUMPV2_OMITDIRS) 
! 	code = StartAFSVolDumpV2(fromcall, fromtid, fromdate, flags);
!     else
!       retryold:
! 	code = StartAFSVolDump(fromcall, fromtid, fromdate);
      EGOTO(error_exit, code, "Could not start the dump process \n");
      VDONE;
  
      VPRINT1("Dumping volume %u...", afromvol);
      code = DumpFunction(fromcall, rock);
+     if (code == RXGEN_OPCODE) 
+ 	goto error_exit;
      EGOTO(error_exit, code, "Error while dumping volume \n");
      VDONE;
  
    error_exit:
      if (fromcall) {
  	code = rx_EndCall(fromcall, rxError);
! 	if (code && code != RXGEN_OPCODE) 
  	    fprintf(STDERR, "Error in rx_EndCall\n");
! 	if (code && !error)
! 	    error = code;
      }
      if (fromtid) {
  	VPRINT1("Ending transaction on volume %u...", afromvol);
***************
*** 3901,3907 ****
      if (fromconn)
  	rx_DestroyConnection(fromconn);
  
!     PrintError("", error);
      return (error);
  }
  
--- 3908,3917 ----
      if (fromconn)
  	rx_DestroyConnection(fromconn);
  
!     if (retry)
! 	goto retryold;
!     if (error != RXGEN_OPCODE)
! 	PrintError("", error);
      return (error);
  }
  
***************
*** 3914,3920 ****
  int
  UV_DumpClonedVolume(afs_int32 afromvol, afs_int32 afromserver,
  		    afs_int32 afrompart, afs_int32 fromdate,
! 		    afs_int32(*DumpFunction) (), char *rock)
  {
      struct rx_connection *fromconn = (struct rx_connection *)0;
      struct rx_call *fromcall = (struct rx_call *)0;
--- 3924,3930 ----
  int
  UV_DumpClonedVolume(afs_int32 afromvol, afs_int32 afromserver,
  		    afs_int32 afrompart, afs_int32 fromdate,
! 		    afs_int32(*DumpFunction) (), char *rock, afs_int32 flags)
  {
      struct rx_connection *fromconn = (struct rx_connection *)0;
      struct rx_call *fromcall = (struct rx_call *)0;
***************
*** 3951,3957 ****
  
      /* Get a clone id */
      VPRINT1("Allocating new volume id for clone of volume %u ...", afromvol);
!     code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &clonevol);
      EGOTO1(error_exit, code,
  	   "Could not get an ID for the clone of volume %u from the VLDB\n",
  	   afromvol);
--- 3961,3967 ----
  
      /* Get a clone id */
      VPRINT1("Allocating new volume id for clone of volume %u ...", afromvol);
!     code = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &clonevol);
      EGOTO1(error_exit, code,
  	   "Could not get an ID for the clone of volume %u from the VLDB\n",
  	   afromvol);
***************
*** 3997,4003 ****
      fromcall = rx_NewCall(fromconn);
  
      VPRINT1("Starting volume dump from cloned volume %u...", clonevol);
!     code = StartAFSVolDump(fromcall, clonetid, fromdate);
      EGOTO(error_exit, code, "Could not start the dump process \n");
      VDONE;
  
--- 4007,4016 ----
      fromcall = rx_NewCall(fromconn);
  
      VPRINT1("Starting volume dump from cloned volume %u...", clonevol);
!     if (flags & VOLDUMPV2_OMITDIRS) 
! 	code = StartAFSVolDumpV2(fromcall, clonetid, fromdate, flags);
!     else
! 	code = StartAFSVolDump(fromcall, clonetid, fromdate);
      EGOTO(error_exit, code, "Could not start the dump process \n");
      VDONE;
  
***************
*** 4102,4108 ****
      if (pvolid == 0) {		/*alot a new id if needed */
  	vcode = VLDB_GetEntryByName(tovolname, &entry);
  	if (vcode == VL_NOENT) {
! 	    vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &pvolid);
  	    if (vcode) {
  		fprintf(STDERR, "Could not get an Id for the volume %s\n",
  			tovolname);
--- 4115,4121 ----
      if (pvolid == 0) {		/*alot a new id if needed */
  	vcode = VLDB_GetEntryByName(tovolname, &entry);
  	if (vcode == VL_NOENT) {
! 	    vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &pvolid);
  	    if (vcode) {
  		fprintf(STDERR, "Could not get an Id for the volume %s\n",
  			tovolname);
***************
*** 4352,4358 ****
  		fprintf(STDOUT, "------- New entry -------\n");
  	    }
  	    vcode =
! 		ubik_Call(VL_SetLock, cstruct, 0, pvolid, voltype,
  			  VLOP_RESTORE);
  	    if (vcode) {
  		fprintf(STDERR,
--- 4365,4371 ----
  		fprintf(STDOUT, "------- New entry -------\n");
  	    }
  	    vcode =
! 		ubik_VL_SetLock(cstruct, 0, pvolid, voltype,
  			  VLOP_RESTORE);
  	    if (vcode) {
  		fprintf(STDERR,
***************
*** 4472,4478 ****
      }
      if (islocked) {
  	vcode =
! 	    ubik_Call(VL_ReleaseLock, cstruct, 0, pvolid, voltype,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (vcode) {
  	    fprintf(STDERR,
--- 4485,4491 ----
      }
      if (islocked) {
  	vcode =
! 	    ubik_VL_ReleaseLock(cstruct, 0, pvolid, voltype,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (vcode) {
  	    fprintf(STDERR,
***************
*** 4532,4538 ****
  
      VPRINT("Binding to the VLDB server\n");
      vcode =
! 	ubik_Call(VL_ReleaseLock, cstruct, 0, volid, -1,
  		  LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
      if (vcode) {
  	fprintf(STDERR,
--- 4545,4551 ----
  
      VPRINT("Binding to the VLDB server\n");
      vcode =
! 	ubik_VL_ReleaseLock(cstruct, 0, volid, -1,
  		  LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
      if (vcode) {
  	fprintf(STDERR,
***************
*** 4556,4562 ****
      afs_int32 vcode, error = 0;
      char apartName[10];
  
!     error = ubik_Call(VL_SetLock, cstruct, 0, volid, RWVOL, VLOP_ADDSITE);
      if (error) {
  	fprintf(STDERR,
  		" Could not lock the VLDB entry for the volume %lu \n",
--- 4569,4575 ----
      afs_int32 vcode, error = 0;
      char apartName[10];
  
!     error = ubik_VL_SetLock(cstruct, 0, volid, RWVOL, VLOP_ADDSITE);
      if (error) {
  	fprintf(STDERR,
  		" Could not lock the VLDB entry for the volume %lu \n",
***************
*** 4640,4646 ****
    asfail:
      if (islocked) {
  	vcode =
! 	    ubik_Call(VL_ReleaseLock, cstruct, 0, volid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (vcode) {
  	    fprintf(STDERR,
--- 4653,4659 ----
    asfail:
      if (islocked) {
  	vcode =
! 	    ubik_VL_ReleaseLock(cstruct, 0, volid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (vcode) {
  	    fprintf(STDERR,
***************
*** 4662,4668 ****
      struct nvldbentry entry, storeEntry;
      int islocked;
  
!     vcode = ubik_Call(VL_SetLock, cstruct, 0, volid, RWVOL, VLOP_ADDSITE);
      if (vcode) {
  	fprintf(STDERR, " Could not lock the VLDB entry for volume %lu \n",
  		(unsigned long)volid);
--- 4675,4681 ----
      struct nvldbentry entry, storeEntry;
      int islocked;
  
!     vcode = ubik_VL_SetLock(cstruct, 0, volid, RWVOL, VLOP_ADDSITE);
      if (vcode) {
  	fprintf(STDERR, " Could not lock the VLDB entry for volume %lu \n",
  		(unsigned long)volid);
***************
*** 4683,4695 ****
  	/*this site doesnot exist  */
  	fprintf(STDERR, "This site is not a replication site \n");
  	vcode =
! 	    ubik_Call(VL_ReleaseLock, cstruct, 0, volid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (vcode) {
  	    fprintf(STDERR, "Could not update entry for volume %lu \n",
  		    (unsigned long)volid);
  	    PrintError("", vcode);
! 	    ubik_Call(VL_ReleaseLock, cstruct, 0, volid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	    return (vcode);
  	}
--- 4696,4708 ----
  	/*this site doesnot exist  */
  	fprintf(STDERR, "This site is not a replication site \n");
  	vcode =
! 	    ubik_VL_ReleaseLock(cstruct, 0, volid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (vcode) {
  	    fprintf(STDERR, "Could not update entry for volume %lu \n",
  		    (unsigned long)volid);
  	    PrintError("", vcode);
! 	    ubik_VL_ReleaseLock(cstruct, 0, volid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	    return (vcode);
  	}
***************
*** 4702,4708 ****
  	if (entry.nServers < 1) {	/*this is the last ref */
  	    VPRINT1("Deleting the VLDB entry for %u ...", volid);
  	    fflush(STDOUT);
! 	    vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, volid, ROVOL);
  	    if (vcode) {
  		fprintf(STDERR,
  			"Could not delete VLDB entry for volume %lu \n",
--- 4715,4721 ----
  	if (entry.nServers < 1) {	/*this is the last ref */
  	    VPRINT1("Deleting the VLDB entry for %u ...", volid);
  	    fflush(STDOUT);
! 	    vcode = ubik_VL_DeleteEntry(cstruct, 0, volid, ROVOL);
  	    if (vcode) {
  		fprintf(STDERR,
  			"Could not delete VLDB entry for volume %lu \n",
***************
*** 4725,4731 ****
  		    "Could not release lock on volume entry for %lu \n",
  		    (unsigned long)volid);
  	    PrintError("", vcode);
! 	    ubik_Call(VL_ReleaseLock, cstruct, 0, volid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	    return (vcode);
  	}
--- 4738,4744 ----
  		    "Could not release lock on volume entry for %lu \n",
  		    (unsigned long)volid);
  	    PrintError("", vcode);
! 	    ubik_VL_ReleaseLock(cstruct, 0, volid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	    return (vcode);
  	}
***************
*** 4742,4748 ****
      struct nvldbentry entry, storeEntry;
      int index;
  
!     vcode = ubik_Call(VL_SetLock, cstruct, 0, volid, RWVOL, VLOP_ADDSITE);
      if (vcode) {
  	fprintf(STDERR, " Could not lock the VLDB entry for volume %lu \n",
  		(unsigned long)volid);
--- 4755,4761 ----
      struct nvldbentry entry, storeEntry;
      int index;
  
!     vcode = ubik_VL_SetLock(cstruct, 0, volid, RWVOL, VLOP_ADDSITE);
      if (vcode) {
  	fprintf(STDERR, " Could not lock the VLDB entry for volume %lu \n",
  		(unsigned long)volid);
***************
*** 4764,4770 ****
  	fprintf(STDERR, "No existing RW site for volume %lu",
  		(unsigned long)volid);
  	vcode =
! 	    ubik_Call(VL_ReleaseLock, cstruct, 0, volid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (vcode) {
  	    fprintf(STDERR,
--- 4777,4783 ----
  	fprintf(STDERR, "No existing RW site for volume %lu",
  		(unsigned long)volid);
  	vcode =
! 	    ubik_VL_ReleaseLock(cstruct, 0, volid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (vcode) {
  	    fprintf(STDERR,
***************
*** 4786,4792 ****
  	    fprintf(STDERR, "Could not update entry for volume %lu \n",
  		    (unsigned long)volid);
  	    PrintError("", vcode);
! 	    ubik_Call(VL_ReleaseLock, cstruct, 0, volid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	    return (vcode);
  	}
--- 4799,4805 ----
  	    fprintf(STDERR, "Could not update entry for volume %lu \n",
  		    (unsigned long)volid);
  	    PrintError("", vcode);
! 	    ubik_VL_ReleaseLock(cstruct, 0, volid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	    return (vcode);
  	}
***************
*** 4926,4932 ****
  	reuseCloneId = 1;
      else {			/*get a bunch of id's from vldb */
  	code =
! 	    ubik_Call(VL_GetNewVolumeId, cstruct, 0, arraySize, &curCloneId);
  	if (code) {
  	    fprintf(STDERR, "Could not get ID's for the clone from VLDB\n");
  	    PrintError("", code);
--- 4939,4945 ----
  	reuseCloneId = 1;
      else {			/*get a bunch of id's from vldb */
  	code =
! 	    ubik_VL_GetNewVolumeId(cstruct, 0, arraySize, &curCloneId);
  	if (code) {
  	    fprintf(STDERR, "Could not get ID's for the clone from VLDB\n");
  	    PrintError("", code);
***************
*** 5249,5255 ****
       * then make the changes to it (pass 2).
       */
      if (++pass == 2) {
! 	code = ubik_Call(VL_SetLock, cstruct, 0, rwvolid, RWVOL, VLOP_DELETE);
  	if (code) {
  	    fprintf(STDERR, "Could not lock VLDB entry for %lu\n",
  		    (unsigned long)rwvolid);
--- 5262,5268 ----
       * then make the changes to it (pass 2).
       */
      if (++pass == 2) {
! 	code = ubik_VL_SetLock(cstruct, 0, rwvolid, RWVOL, VLOP_DELETE);
  	if (code) {
  	    fprintf(STDERR, "Could not lock VLDB entry for %lu\n",
  		    (unsigned long)rwvolid);
***************
*** 5622,5628 ****
  	    *modentry = modified;
      } else if (pass == 2) {
  	code =
! 	    ubik_Call(VL_ReleaseLock, cstruct, 0, rwvolid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (code) {
  	    PrintError("Could not unlock VLDB entry ", code);
--- 5635,5641 ----
  	    *modentry = modified;
      } else if (pass == 2) {
  	code =
! 	    ubik_VL_ReleaseLock(cstruct, 0, rwvolid, RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (code) {
  	    PrintError("Could not unlock VLDB entry ", code);
***************
*** 5865,5880 ****
      /* Now check if the maxvolid is larger than that stored in the VLDB */
      if (maxvolid) {
  	afs_int32 maxvldbid = 0;
! 	code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 0, &maxvldbid);
  	if (code) {
  	    fprintf(STDERR,
  		    "Could not get the highest allocated volume id from the VLDB\n");
  	    if (!error)
  		error = code;
  	} else if (maxvolid > maxvldbid) {
! 	    afs_uint32 id, nid;
  	    id = maxvolid - maxvldbid + 1;
! 	    code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, id, &nid);
  	    if (code) {
  		fprintf(STDERR,
  			"Error in increasing highest allocated volume id in VLDB\n");
--- 5878,5893 ----
      /* Now check if the maxvolid is larger than that stored in the VLDB */
      if (maxvolid) {
  	afs_int32 maxvldbid = 0;
! 	code = ubik_VL_GetNewVolumeId(cstruct, 0, 0, &maxvldbid);
  	if (code) {
  	    fprintf(STDERR,
  		    "Could not get the highest allocated volume id from the VLDB\n");
  	    if (!error)
  		error = code;
  	} else if (maxvolid > maxvldbid) {
! 	    afs_int32 id, nid;
  	    id = maxvolid - maxvldbid + 1;
! 	    code = ubik_VL_GetNewVolumeId(cstruct, 0, id, &nid);
  	    if (code) {
  		fprintf(STDERR,
  			"Error in increasing highest allocated volume id in VLDB\n");
***************
*** 6009,6025 ****
    error_exit:
      /* Now check if the maxvolid is larger than that stored in the VLDB */
      if (maxvolid) {
! 	afs_uint32 maxvldbid = 0;
! 	code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 0, &maxvldbid);
  	if (code) {
  	    fprintf(STDERR,
  		    "Could not get the highest allocated volume id from the VLDB\n");
  	    if (!error)
  		error = code;
  	} else if (maxvolid > maxvldbid) {
! 	    afs_uint32 id, nid;
  	    id = maxvolid - maxvldbid + 1;
! 	    code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, id, &nid);
  	    if (code) {
  		fprintf(STDERR,
  			"Error in increasing highest allocated volume id in VLDB\n");
--- 6022,6038 ----
    error_exit:
      /* Now check if the maxvolid is larger than that stored in the VLDB */
      if (maxvolid) {
! 	afs_int32 maxvldbid = 0;
! 	code = ubik_VL_GetNewVolumeId(cstruct, 0, 0, &maxvldbid);
  	if (code) {
  	    fprintf(STDERR,
  		    "Could not get the highest allocated volume id from the VLDB\n");
  	    if (!error)
  		error = code;
  	} else if (maxvolid > maxvldbid) {
! 	    afs_int32 id, nid;
  	    id = maxvolid - maxvldbid + 1;
! 	    code = ubik_VL_GetNewVolumeId(cstruct, 0, id, &nid);
  	    if (code) {
  		fprintf(STDERR,
  			"Error in increasing highest allocated volume id in VLDB\n");
***************
*** 6262,6268 ****
       */
      if (++pass == 2) {
  	code =
! 	    ubik_Call(VL_SetLock, cstruct, 0, entry->volumeId[RWVOL], RWVOL,
  		      VLOP_DELETE);
  	if (code) {
  	    fprintf(STDERR, "Could not lock VLDB entry for %u \n",
--- 6275,6281 ----
       */
      if (++pass == 2) {
  	code =
! 	    ubik_VL_SetLock(cstruct, 0, entry->volumeId[RWVOL], RWVOL,
  		      VLOP_DELETE);
  	if (code) {
  	    fprintf(STDERR, "Could not lock VLDB entry for %u \n",
***************
*** 6312,6318 ****
  	    && !(entry->flags & RO_EXISTS)) {
  	    /* The RW, BK, nor RO volumes do not exist. Delete the VLDB entry */
  	    code =
! 		ubik_Call(VL_DeleteEntry, cstruct, 0, entry->volumeId[RWVOL],
  			  RWVOL);
  	    if (code) {
  		fprintf(STDERR,
--- 6325,6331 ----
  	    && !(entry->flags & RO_EXISTS)) {
  	    /* The RW, BK, nor RO volumes do not exist. Delete the VLDB entry */
  	    code =
! 		ubik_VL_DeleteEntry(cstruct, 0, entry->volumeId[RWVOL],
  			  RWVOL);
  	    if (code) {
  		fprintf(STDERR,
***************
*** 6354,6360 ****
  
      if (islocked) {
  	code =
! 	    ubik_Call(VL_ReleaseLock, cstruct, 0, entry->volumeId[RWVOL],
  		      RWVOL,
  		      (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
  	if (code) {
--- 6367,6373 ----
  
      if (islocked) {
  	code =
! 	    ubik_VL_ReleaseLock(cstruct, 0, entry->volumeId[RWVOL],
  		      RWVOL,
  		      (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
  	if (code) {
***************
*** 6479,6485 ****
      tid = 0;
      islocked = 0;
  
!     vcode = ubik_Call(VL_SetLock, cstruct, 0, entry->volumeId[RWVOL], RWVOL, VLOP_ADDSITE);	/*last param is dummy */
      if (vcode) {
  	fprintf(STDERR,
  		" Could not lock the VLDB entry for the  volume %u \n",
--- 6492,6498 ----
      tid = 0;
      islocked = 0;
  
!     vcode = ubik_VL_SetLock(cstruct, 0, entry->volumeId[RWVOL], RWVOL, VLOP_ADDSITE);	/*last param is dummy */
      if (vcode) {
  	fprintf(STDERR,
  		" Could not lock the VLDB entry for the  volume %u \n",
***************
*** 6665,6671 ****
    rvfail:
      if (islocked) {
  	vcode =
! 	    ubik_Call(VL_ReleaseLock, cstruct, 0, entry->volumeId[RWVOL],
  		      RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (vcode) {
--- 6678,6684 ----
    rvfail:
      if (islocked) {
  	vcode =
! 	    ubik_VL_ReleaseLock(cstruct, 0, entry->volumeId[RWVOL],
  		      RWVOL,
  		      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
  	if (vcode) {
