Index: openafs/src/WINNT/afsd/afsd.h
diff -c openafs/src/WINNT/afsd/afsd.h:1.18.2.13 openafs/src/WINNT/afsd/afsd.h:1.18.2.14
*** openafs/src/WINNT/afsd/afsd.h:1.18.2.13	Thu Jun 26 12:38:29 2008
--- openafs/src/WINNT/afsd/afsd.h	Mon Jan  5 11:20:20 2009
***************
*** 99,108 ****
  #ifdef AFS_FREELANCE_CLIENT
  extern char *cm_FakeRootDir;				// the fake root.afs directory
  
- extern int cm_noLocalMountPoints;			// no. of fake mountpoints
- 
- extern cm_localMountPoint_t* cm_localMountPoints;	// array of fake mountpoints
- 
  extern int cm_fakeDirSize;				// size (in bytes) of fake root.afs directory
  
  extern int cm_fakeDirCallback;				// state of the fake root.afs directory. indicates
--- 99,104 ----
Index: openafs/src/WINNT/afsd/cm_callback.c
diff -c openafs/src/WINNT/afsd/cm_callback.c:1.41.4.52 openafs/src/WINNT/afsd/cm_callback.c:1.41.4.53
*** openafs/src/WINNT/afsd/cm_callback.c:1.41.4.52	Tue Dec 23 15:42:56 2008
--- openafs/src/WINNT/afsd/cm_callback.c	Mon Jan  5 11:20:20 2009
***************
*** 1739,1748 ****
      // cm_MergeStatus and mark that cm_fakeDirCallback is 2
      if (cm_freelanceEnabled) {
          if (scp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
!              scp->fid.volume==AFS_FAKE_ROOT_VOL_ID &&
!              scp->fid.unique==0x1 &&
!              scp->fid.vnode==0x1) {
!             
              // Start by indicating that we're in the process
              // of fetching the callback
              lock_ObtainMutex(&cm_Freelance_Lock);
--- 1739,1745 ----
      // cm_MergeStatus and mark that cm_fakeDirCallback is 2
      if (cm_freelanceEnabled) {
          if (scp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
!             scp->fid.volume==AFS_FAKE_ROOT_VOL_ID) {
              // Start by indicating that we're in the process
              // of fetching the callback
              lock_ObtainMutex(&cm_Freelance_Lock);
***************
*** 1765,1774 ****
  
              return 0;
          }
- 
-         if (scp->fid.cell==AFS_FAKE_ROOT_CELL_ID && scp->fid.volume==AFS_FAKE_ROOT_VOL_ID) {
-             osi_Log0(afsd_logp,"cm_getcallback should NEVER EVER get here... ");
-         }
      }
  #endif /* AFS_FREELANCE_CLIENT */
  	
--- 1762,1767 ----
Index: openafs/src/WINNT/afsd/cm_freelance.c
diff -c openafs/src/WINNT/afsd/cm_freelance.c:1.33.2.17 openafs/src/WINNT/afsd/cm_freelance.c:1.33.2.18
*** openafs/src/WINNT/afsd/cm_freelance.c:1.33.2.17	Fri Aug 22 14:10:01 2008
--- openafs/src/WINNT/afsd/cm_freelance.c	Mon Jan  5 11:20:20 2009
***************
*** 18,31 ****
  
  extern void afsi_log(char *pattern, ...);
  
! int cm_noLocalMountPoints;
  char * cm_FakeRootDir = NULL;
  int cm_fakeDirSize = 0;
  int cm_fakeDirCallback=0;
  int cm_fakeGettingCallback=0;
! cm_localMountPoint_t* cm_localMountPoints;
  osi_mutex_t cm_Freelance_Lock;
! int cm_localMountPointChangeFlag = 0;
  int cm_freelanceEnabled = 1;
  time_t FakeFreelanceModTime = 0x3b49f6e2;
  
--- 18,31 ----
  
  extern void afsi_log(char *pattern, ...);
  
! static int cm_noLocalMountPoints;
  char * cm_FakeRootDir = NULL;
  int cm_fakeDirSize = 0;
  int cm_fakeDirCallback=0;
  int cm_fakeGettingCallback=0;
! static cm_localMountPoint_t* cm_localMountPoints;
  osi_mutex_t cm_Freelance_Lock;
! static int cm_localMountPointChangeFlag = 0;
  int cm_freelanceEnabled = 1;
  time_t FakeFreelanceModTime = 0x3b49f6e2;
  
***************
*** 274,280 ****
      {       
  
          noChunks = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0);
!         fakeEntry.fid.vnode = htonl(curDirEntry + 2);
          currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE;
  
          memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE);
--- 274,282 ----
      {       
  
          noChunks = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0);
!         /* enforce the rule that only directories have odd vnode values */
!         fakeEntry.fid.vnode = htonl((curDirEntry + 1) * 2);
!         fakeEntry.fid.unique = htonl(curDirEntry + 1);
          currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE;
  
          memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE);
***************
*** 316,322 ****
              // add an entry to this page
  
              noChunks = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0);
!             fakeEntry.fid.vnode=htonl(curDirEntry+2);
              currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE;
              memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE);
              strcpy(currentPos + 12, (cm_localMountPoints+curDirEntry)->namep);
--- 318,326 ----
              // add an entry to this page
  
              noChunks = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0);
!             /* enforce the rule that only directories have odd vnode values */
!             fakeEntry.fid.vnode = htonl((curDirEntry + 1) * 2);
!             fakeEntry.fid.unique = htonl(curDirEntry + 1);
              currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE;
              memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE);
              strcpy(currentPos + 12, (cm_localMountPoints+curDirEntry)->namep);
***************
*** 1336,1339 ****
--- 1340,1382 ----
      } else
          return CM_ERROR_NOSUCHFILE;
  }
+ 
+ long
+ cm_FreelanceFetchMountPointString(cm_scache_t *scp)
+ {
+     lock_ObtainMutex(&cm_Freelance_Lock);
+     if (!scp->mountPointStringp[0] && 
+         scp->fid.cell == AFS_FAKE_ROOT_CELL_ID &&
+         scp->fid.volume == AFS_FAKE_ROOT_VOL_ID && 
+         scp->fid.unique <= cm_noLocalMountPoints) {
+         strncpy(scp->mountPointStringp, cm_localMountPoints[scp->fid.unique-1].mountPointStringp, MOUNTPOINTLEN);
+         scp->mountPointStringp[MOUNTPOINTLEN-1] = 0;	/* null terminate */
+     }
+     lock_ReleaseMutex(&cm_Freelance_Lock);
+ 
+     return 0;
+ }
+ 
+ long 
+ cm_FreelanceFetchFileType(cm_scache_t *scp)
+ {
+     lock_ObtainMutex(&cm_Freelance_Lock);
+     if (scp->fid.cell == AFS_FAKE_ROOT_CELL_ID &&
+         scp->fid.volume == AFS_FAKE_ROOT_VOL_ID && 
+         scp->fid.unique <= cm_noLocalMountPoints) 
+     {
+         scp->fileType = cm_localMountPoints[scp->fid.unique-1].fileType;
+     
+         if ( scp->fileType == CM_SCACHETYPE_SYMLINK &&
+              !strnicmp(cm_localMountPoints[scp->fid.unique-1].mountPointStringp, "msdfs:", strlen("msdfs:")) )
+         {
+             scp->fileType = CM_SCACHETYPE_DFSLINK;
+         } 
+     } else {
+         scp->fileType = CM_SCACHETYPE_INVALID;
+     }
+     lock_ReleaseMutex(&cm_Freelance_Lock);
+ 
+     return 0;
+ }
  #endif /* AFS_FREELANCE_CLIENT */
Index: openafs/src/WINNT/afsd/cm_freelance.h
diff -c openafs/src/WINNT/afsd/cm_freelance.h:1.12.6.2 openafs/src/WINNT/afsd/cm_freelance.h:1.12.6.3
*** openafs/src/WINNT/afsd/cm_freelance.h:1.12.6.2	Mon Jan 28 02:23:35 2008
--- openafs/src/WINNT/afsd/cm_freelance.h	Mon Jan  5 11:20:20 2009
***************
*** 21,26 ****
--- 21,29 ----
  extern long cm_FreelanceAddSymlink(char *filename, char *destination, cm_fid_t *fidp);
  extern long cm_FreelanceMountPointExists(char * filename, int prefix_ok);
  extern long cm_FreelanceSymlinkExists(char * filename, int prefix_ok);
+ extern long cm_FreelanceFetchMountPointString(cm_scache_t *scp);
+ extern long cm_FreelanceFetchFileType(cm_scache_t *scp);
+ 
  extern int cm_clearLocalMountPointChange();
  extern int cm_FakeRootFid(cm_fid_t *fidp);
  
Index: openafs/src/WINNT/afsd/cm_scache.c
diff -c openafs/src/WINNT/afsd/cm_scache.c:1.35.2.89 openafs/src/WINNT/afsd/cm_scache.c:1.35.2.90
*** openafs/src/WINNT/afsd/cm_scache.c:1.35.2.89	Tue Sep 16 07:47:47 2008
--- openafs/src/WINNT/afsd/cm_scache.c	Mon Jan  5 11:20:20 2009
***************
*** 718,726 ****
      }
  	  
      if (cm_freelanceEnabled && special) {
-         char mp[MOUNTPOINTLEN] = "";
-         afs_uint32 fileType;
- 
          lock_ReleaseWrite(&cm_scacheLock);
          osi_Log0(afsd_logp,"cm_GetSCache Freelance and special");
  
--- 718,723 ----
***************
*** 729,747 ****
              cm_reInitLocalMountPoints();	// start reinit
          }
  
-         lock_ObtainMutex(&cm_Freelance_Lock);
-         if (fidp->vnode >= 2 && fidp->vnode - 2 < cm_noLocalMountPoints) {
-             strncpy(mp,(cm_localMountPoints+fidp->vnode-2)->mountPointStringp, MOUNTPOINTLEN);
-             mp[MOUNTPOINTLEN-1] = '\0';
-             if ( !strnicmp(mp, "msdfs:", strlen("msdfs:")) )
-                 fileType = CM_SCACHETYPE_DFSLINK;
-             else
-                 fileType = (cm_localMountPoints+fidp->vnode-2)->fileType;
-         } else {
-             fileType = CM_SCACHETYPE_INVALID;
- 
-         }
-         lock_ReleaseMutex(&cm_Freelance_Lock);
          lock_ObtainWrite(&cm_scacheLock);
          if (scp == NULL) {
              scp = cm_GetNewSCache();    /* returns scp->rw held */
--- 726,731 ----
***************
*** 768,777 ****
          }
          scp->refCount = 1;
  	osi_Log1(afsd_logp,"cm_GetSCache (freelance) sets refCount to 1 scp 0x%x", scp);
!         scp->fileType = fileType;
!         scp->length.LowPart = (DWORD)strlen(mp)+4;
          scp->length.HighPart = 0;
-         strncpy(scp->mountPointStringp,mp,MOUNTPOINTLEN);
          scp->owner=0x0;
          scp->unixModeBits=0777;
          scp->clientModTime=FakeFreelanceModTime;
--- 752,764 ----
          }
          scp->refCount = 1;
  	osi_Log1(afsd_logp,"cm_GetSCache (freelance) sets refCount to 1 scp 0x%x", scp);
! 
!         /* must be called after the scp->fid is set */
!         cm_FreelanceFetchMountPointString(scp);
!         cm_FreelanceFetchFileType(scp);
!         
!         scp->length.LowPart = (DWORD)strlen(scp->mountPointStringp)+4;
          scp->length.HighPart = 0;
          scp->owner=0x0;
          scp->unixModeBits=0777;
          scp->clientModTime=FakeFreelanceModTime;
Index: openafs/src/WINNT/afsd/cm_vnodeops.c
diff -c openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.94 openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.95
*** openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.94	Fri Dec 26 18:26:18 2008
--- openafs/src/WINNT/afsd/cm_vnodeops.c	Mon Jan  5 11:20:20 2009
***************
*** 808,875 ****
  long cm_ReadMountPoint(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
  {
      long code;
!     cm_buf_t *bufp;
      osi_hyper_t thyper;
      int tlen;
  
      if (scp->mountPointStringp[0]) 
          return 0;
          
!     /* otherwise, we have to read it in */
!     lock_ReleaseWrite(&scp->rw);
! 
!     thyper.LowPart = thyper.HighPart = 0;
!     code = buf_Get(scp, &thyper, &bufp);
  
!     lock_ObtainWrite(&scp->rw);
!     if (code)
!         return code;
  
!     while (1) {
!         code = cm_SyncOp(scp, bufp, userp, reqp, 0,
!                           CM_SCACHESYNC_READ | CM_SCACHESYNC_NEEDCALLBACK);
          if (code)
!             goto done;
  
! 	cm_SyncOpDone(scp, bufp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);
  
!         if (cm_HaveBuffer(scp, bufp, 0)) 
!             break;
  
!         /* otherwise load buffer */
!         code = cm_GetBuffer(scp, bufp, NULL, userp, reqp);
!         if (code)
              goto done;
!     }
!     /* locked, has callback, has valid data in buffer */
!     if ((tlen = scp->length.LowPart) > MOUNTPOINTLEN - 1) 
!         return CM_ERROR_TOOBIG;
!     if (tlen <= 0) {
!         code = CM_ERROR_INVAL;
!         goto done;
!     }
  
!     /* someone else did the work while we were out */
!     if (scp->mountPointStringp[0]) {
!         code = 0;
!         goto done;
!     }
  
!     /* otherwise, copy out the link */
!     memcpy(scp->mountPointStringp, bufp->datap, tlen);
  
!     /* now make it null-terminated.  Note that the original contents of a
!      * link that is a mount point is "#volname." where "." is there just to
!      * be turned into a null.  That is, we can trash the last char of the
!      * link without damaging the vol name.  This is a stupid convention,
!      * but that's the protocol.
!      */
!     scp->mountPointStringp[tlen-1] = 0;
!     code = 0;
  
!   done:
!     if (bufp) 
!         buf_Release(bufp);
      return code;
  }
  
--- 808,886 ----
  long cm_ReadMountPoint(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
  {
      long code;
!     cm_buf_t *bufp = NULL;
      osi_hyper_t thyper;
      int tlen;
  
      if (scp->mountPointStringp[0]) 
          return 0;
          
! #ifdef AFS_FREELANCE_CLIENT
!     /* File servers do not have data for freelance entries */
!     if (cm_freelanceEnabled &&
!         scp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
!         scp->fid.volume==AFS_FAKE_ROOT_VOL_ID )
!     {       
!         code = cm_FreelanceFetchMountPointString(scp);
!     } else 
! #endif /* AFS_FREELANCE_CLIENT */        
!     {
!         /* otherwise, we have to read it in */
!         lock_ReleaseWrite(&scp->rw);
  
!         thyper.LowPart = thyper.HighPart = 0;
!         code = buf_Get(scp, &thyper, &bufp);
  
!         lock_ObtainWrite(&scp->rw);
          if (code)
!             return code;
! 
!         while (1) {
!             code = cm_SyncOp(scp, bufp, userp, reqp, 0,
!                               CM_SCACHESYNC_READ | CM_SCACHESYNC_NEEDCALLBACK);
!             if (code)
!                 goto done;
  
!             cm_SyncOpDone(scp, bufp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);
  
!             if (cm_HaveBuffer(scp, bufp, 0)) 
!                 break;
  
!             /* otherwise load buffer */
!             code = cm_GetBuffer(scp, bufp, NULL, userp, reqp);
!             if (code)
!                 goto done;
!         }
!         /* locked, has callback, has valid data in buffer */
!         if ((tlen = scp->length.LowPart) > MOUNTPOINTLEN - 1) 
!             return CM_ERROR_TOOBIG;
!         if (tlen <= 0) {
!             code = CM_ERROR_INVAL;
              goto done;
!         }
  
!         /* someone else did the work while we were out */
!         if (scp->mountPointStringp[0]) {
!             code = 0;
!             goto done;
!         }
  
!         /* otherwise, copy out the link */
!         memcpy(scp->mountPointStringp, bufp->datap, tlen);
  
!         /* now make it null-terminated.  Note that the original contents of a
!          * link that is a mount point is "#volname." where "." is there just to
!          * be turned into a null.  That is, we can trash the last char of the
!          * link without damaging the vol name.  This is a stupid convention,
!          * but that's the protocol.
!          */
!         scp->mountPointStringp[tlen-1] = 0;
!         code = 0;
  
!       done:
!         if (bufp) 
!             buf_Release(bufp);
!     }
      return code;
  }
  
***************
*** 1628,1678 ****
  
      lock_AssertWrite(&linkScp->rw);
      if (!linkScp->mountPointStringp[0]) {
!         /* read the link data */
!         lock_ReleaseWrite(&linkScp->rw);
!         thyper.LowPart = thyper.HighPart = 0;
!         code = buf_Get(linkScp, &thyper, &bufp);
!         lock_ObtainWrite(&linkScp->rw);
!         if (code) 
!             return code;
!         while (1) {
!             code = cm_SyncOp(linkScp, bufp, userp, reqp, 0,
!                               CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);
!             if (code) {
!                 buf_Release(bufp);
                  return code;
!             }
! 	    cm_SyncOpDone(linkScp, bufp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);
  
!             if (cm_HaveBuffer(linkScp, bufp, 0)) 
!                 break;
  
!             code = cm_GetBuffer(linkScp, bufp, NULL, userp, reqp);
!             if (code) {
                  buf_Release(bufp);
!                 return code;
              }
-         } /* while loop to get the data */
-                 
-         /* now if we still have no link read in,
-          * copy the data from the buffer */
-         if ((temp = linkScp->length.LowPart) >= MOUNTPOINTLEN) {
              buf_Release(bufp);
-             return CM_ERROR_TOOBIG;
          }
  
-         /* otherwise, it fits; make sure it is still null (could have
-          * lost race with someone else referencing this link above),
-          * and if so, copy in the data.
-          */
-         if (!linkScp->mountPointStringp[0]) {
-             strncpy(linkScp->mountPointStringp, bufp->datap, temp);
-             linkScp->mountPointStringp[temp] = 0;	/* null terminate */
- 
-             if ( !strnicmp(linkScp->mountPointStringp, "msdfs:", strlen("msdfs:")) )
-                  linkScp->fileType = CM_SCACHETYPE_DFSLINK;
-         }
-         buf_Release(bufp);
      }	/* don't have sym link contents cached */
  
      return 0;
--- 1639,1702 ----
  
      lock_AssertWrite(&linkScp->rw);
      if (!linkScp->mountPointStringp[0]) {
!         
! #ifdef AFS_FREELANCE_CLIENT
! 	/* File servers do not have data for freelance entries */
!         if (cm_freelanceEnabled &&
!             linkScp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
!             linkScp->fid.volume==AFS_FAKE_ROOT_VOL_ID )
!         {
!             code = cm_FreelanceFetchMountPointString(linkScp);
!         } else 
! #endif /* AFS_FREELANCE_CLIENT */        
!         {
!             /* read the link data from the file server*/
!             lock_ReleaseWrite(&linkScp->rw);
!             thyper.LowPart = thyper.HighPart = 0;
!             code = buf_Get(linkScp, &thyper, &bufp);
!             lock_ObtainWrite(&linkScp->rw);
!             if (code) 
                  return code;
!             while (1) {
!                 code = cm_SyncOp(linkScp, bufp, userp, reqp, 0,
!                                   CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);
!                 if (code) {
!                     buf_Release(bufp);
!                     return code;
!                 }
!                 cm_SyncOpDone(linkScp, bufp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);
  
!                 if (cm_HaveBuffer(linkScp, bufp, 0)) 
!                     break;
  
!                 code = cm_GetBuffer(linkScp, bufp, NULL, userp, reqp);
!                 if (code) {
!                     buf_Release(bufp);
!                     return code;
!                 }
!             } /* while loop to get the data */
! 
!             /* now if we still have no link read in,
!              * copy the data from the buffer */
!             if ((temp = linkScp->length.LowPart) >= MOUNTPOINTLEN) {
                  buf_Release(bufp);
!                 return CM_ERROR_TOOBIG;
!             }       
! 
!             /* otherwise, it fits; make sure it is still null (could have
!              * lost race with someone else referencing this link above),
!              * and if so, copy in the data.
!              */
!             if (!linkScp->mountPointStringp[0]) {
!                 strncpy(linkScp->mountPointStringp, bufp->datap, temp);
!                 linkScp->mountPointStringp[temp] = 0;	/* null terminate */
              }
              buf_Release(bufp);
          }
+         
+         if ( !strnicmp(linkScp->mountPointStringp, "msdfs:", strlen("msdfs:")) )
+             linkScp->fileType = CM_SCACHETYPE_DFSLINK;
  
      }	/* don't have sym link contents cached */
  
      return 0;
Index: openafs/src/WINNT/afsd/smb.c
diff -c openafs/src/WINNT/afsd/smb.c:1.118.2.111 openafs/src/WINNT/afsd/smb.c:1.118.2.114
*** openafs/src/WINNT/afsd/smb.c:1.118.2.111	Wed Dec 17 11:19:42 2008
--- openafs/src/WINNT/afsd/smb.c	Wed Jan 21 16:04:42 2009
***************
*** 2613,2634 ****
                                    char **chainpp, int flags)
  {
      size_t cb;
  
!     if (*inp++ != 0x4) 
!         return NULL;
  
  #ifdef SMB_UNICODE
!     if (!WANTS_UNICODE(pktp))
          flags |= SMB_STRF_FORCEASCII;
  #endif
  
-     cb = sizeof(pktp->data) - (inp - pktp->data);
-     if (inp < pktp->data || inp >= pktp->data + sizeof(pktp->data)) {
- #ifdef DEBUG_UNICODE
-         DebugBreak();
- #endif
-         cb = sizeof(pktp->data);
-     }
      return smb_ParseStringBuf(pktp->data, &pktp->stringsp, inp, &cb, chainpp, flags);
  }
  
--- 2613,2654 ----
                                    char **chainpp, int flags)
  {
      size_t cb;
+     afs_uint32 type = *inp++;
  
!     /* 
!      * The first byte specifies the type of the input string.
!      * CIFS TR 1.0 3.2.10.  This function only parses null terminated
!      * strings.
!      */
!     switch (type) {
!     /* Length Counted */
!     case 0x1: /* Data Block */
!     case 0x5: /* Variable Block */
!         cb = *inp++ << 16 | *inp++;
!         break;
! 
!     /* Null-terminated string */
!     case 0x4: /* ASCII */
!     case 0x3: /* Pathname */
!     case 0x2: /* Dialect */
!         cb = sizeof(pktp->data) - (inp - pktp->data);
!         if (inp < pktp->data || inp >= pktp->data + sizeof(pktp->data)) {
! #ifdef DEBUG_UNICODE
!             DebugBreak();
! #endif
!             cb = sizeof(pktp->data);
!         }
!         break;
! 
!     default:
!         return NULL;            /* invalid input */
!     }
  
  #ifdef SMB_UNICODE
!     if (type == 0x2 /* Dialect */ || !WANTS_UNICODE(pktp))
          flags |= SMB_STRF_FORCEASCII;
  #endif
  
      return smb_ParseStringBuf(pktp->data, &pktp->stringsp, inp, &cb, chainpp, flags);
  }
  
***************
*** 4076,4081 ****
--- 4096,4103 ----
          char *tbp;
          tbp = smb_GetSMBData(inp, NULL);
          pathp = smb_ParseASCIIBlock(inp, tbp, &tbp, SMB_STRF_ANSIPATH);
+         if (!pathp)
+             return CM_ERROR_BADSMB;
      }
      tp = cm_ClientStrRChr(pathp, '\\');
      if (!tp)
***************
*** 4247,4253 ****
      tp = smb_GetSMBData(inp, NULL);
      pathp = smb_ParseASCIIBlock(inp, tp, &tp,
                                  SMB_STRF_ANSIPATH|SMB_STRF_FORCEASCII);
!     osi_assertx(pathp != NULL, "null path");
      statBlockp = smb_ParseVblBlock(tp, &tp, &statLen);
      osi_assertx(statBlockp != NULL, "null statBlock");
      if (statLen == 0) {
--- 4269,4276 ----
      tp = smb_GetSMBData(inp, NULL);
      pathp = smb_ParseASCIIBlock(inp, tp, &tp,
                                  SMB_STRF_ANSIPATH|SMB_STRF_FORCEASCII);
!     if (!pathp)
!         return CM_ERROR_BADSMB;
      statBlockp = smb_ParseVblBlock(tp, &tp, &statLen);
      osi_assertx(statBlockp != NULL, "null statBlock");
      if (statLen == 0) {
***************
*** 4544,4555 ****
      tp = smb_GetSMBData(inp, NULL);
      pathp = smb_ParseASCIIBlock(inp, tp, &tp,
                                  SMB_STRF_ANSIPATH|SMB_STRF_FORCEASCII);
!     inCookiep = smb_ParseVblBlock(tp, &tp, &dataLength);
  
!     /* bail out if request looks bad */
!     if (!tp || !pathp) {
          return CM_ERROR_BADSMB;
-     }
  
      /* We can handle long names */
      if (vcp->flags & SMB_VCFLAG_USENT)
--- 4567,4578 ----
      tp = smb_GetSMBData(inp, NULL);
      pathp = smb_ParseASCIIBlock(inp, tp, &tp,
                                  SMB_STRF_ANSIPATH|SMB_STRF_FORCEASCII);
!     if (!pathp)
!         return CM_ERROR_BADSMB;
  
!     inCookiep = smb_ParseVblBlock(tp, &tp, &dataLength);
!     if (!tp)
          return CM_ERROR_BADSMB;
  
      /* We can handle long names */
      if (vcp->flags & SMB_VCFLAG_USENT)
***************
*** 5057,5063 ****
      pdata = smb_GetSMBData(inp, NULL);
      pathp = smb_ParseASCIIBlock(inp, pdata, NULL, SMB_STRF_ANSIPATH);
      if (!pathp)
!         return CM_ERROR_BADFD;
      osi_Log1(smb_logp, "SMB receive check path %S",
               osi_LogSaveClientString(smb_logp, pathp));
          
--- 5080,5086 ----
      pdata = smb_GetSMBData(inp, NULL);
      pathp = smb_ParseASCIIBlock(inp, pdata, NULL, SMB_STRF_ANSIPATH);
      if (!pathp)
!         return CM_ERROR_BADSMB;
      osi_Log1(smb_logp, "SMB receive check path %S",
               osi_LogSaveClientString(smb_logp, pathp));
          
***************
*** 5428,5433 ****
--- 5451,5458 ----
  
      datap = smb_GetSMBData(inp, NULL);
      pathp = smb_ParseASCIIBlock(inp, datap, NULL, SMB_STRF_ANSIPATH);
+     if (!pathp)
+         return CM_ERROR_BADSMB;
  
      osi_Log1(smb_logp, "SMB receive open file [%S]", osi_LogSaveClientString(smb_logp, pathp));
  
***************
*** 5655,5660 ****
--- 5680,5687 ----
          
      tp = smb_GetSMBData(inp, NULL);
      pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
+     if (!pathp)
+         return CM_ERROR_BADSMB;
  
      osi_Log1(smb_logp, "SMB receive unlink %S",
               osi_LogSaveClientString(smb_logp, pathp));
***************
*** 6207,6213 ****
--- 6234,6244 ----
  
      tp = smb_GetSMBData(inp, NULL);
      oldPathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
+     if (!oldPathp)
+         return CM_ERROR_BADSMB;
      newPathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
+     if (!newPathp)
+         return CM_ERROR_BADSMB;
  
      osi_Log2(smb_logp, "smb rename [%S] to [%S]",
               osi_LogSaveClientString(smb_logp, oldPathp),
***************
*** 6301,6306 ****
--- 6332,6339 ----
  
      tp = smb_GetSMBData(inp, NULL);
      pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
+     if (!pathp)
+         return CM_ERROR_BADSMB;
  
      spacep = inp->spacep;
      smb_StripLastComponent(spacep->wdata, &lastNamep, pathp);
***************
*** 7693,7705 ****
          
      tp = smb_GetSMBData(inp, NULL);
      pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
! 
!     if (cm_ClientStrCmp(pathp, _C("\\")) == 0)
!         return CM_ERROR_EXISTS;
  
      spacep = inp->spacep;
      smb_StripLastComponent(spacep->wdata, &lastNamep, pathp);
  
      userp = smb_GetUserFromVCP(vcp, inp);
  
      caseFold = CM_FLAG_CASEFOLD;
--- 7726,7740 ----
          
      tp = smb_GetSMBData(inp, NULL);
      pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
!     if (!pathp)
!         return CM_ERROR_BADSMB;
  
      spacep = inp->spacep;
      smb_StripLastComponent(spacep->wdata, &lastNamep, pathp);
  
+     if (cm_ClientStrCmp(pathp, _C("\\")) == 0)
+         return CM_ERROR_EXISTS;
+ 
      userp = smb_GetUserFromVCP(vcp, inp);
  
      caseFold = CM_FLAG_CASEFOLD;
***************
*** 7822,7827 ****
--- 7857,7864 ----
          
      tp = smb_GetSMBData(inp, NULL);
      pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
+     if (!pathp)
+         return CM_ERROR_BADSMB;
  
      if (!cm_IsValidClientString(pathp)) {
  #ifdef DEBUG
***************
*** 8761,8774 ****
              if (smbp->com == 0x1d) {
                  /* Special handling for Write Raw */
                  raw_write_cont_t rwc;
-                 EVENT_HANDLE rwevent;
-                 char eventName[MAX_PATH];
              
                  smb_DispatchPacket(vcp, bufp, outbufp, ncbp, &rwc);
                  if (rwc.code == 0) {
!                     rwevent = thrd_CreateEvent(NULL, FALSE, FALSE, TEXT("smb_Server() rwevent"));
                      if ( GetLastError() == ERROR_ALREADY_EXISTS )
                          osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName));
                      ncbp->ncb_command = NCBRECV | ASYNCH;
                      ncbp->ncb_lsn = (unsigned char) vcp->lsn;
                      ncbp->ncb_lana_num = vcp->lana;
--- 8798,8814 ----
              if (smbp->com == 0x1d) {
                  /* Special handling for Write Raw */
                  raw_write_cont_t rwc;
              
                  smb_DispatchPacket(vcp, bufp, outbufp, ncbp, &rwc);
                  if (rwc.code == 0) {
!                     EVENT_HANDLE rwevent;
!                     char eventName[MAX_PATH];
! 
!                     snprintf(eventName, MAX_PATH, "smb_Server() rwevent %d", myIdx);
!                     rwevent = thrd_CreateEvent(NULL, FALSE, FALSE, eventName);
                      if ( GetLastError() == ERROR_ALREADY_EXISTS )
                          osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName));
+ 
                      ncbp->ncb_command = NCBRECV | ASYNCH;
                      ncbp->ncb_lsn = (unsigned char) vcp->lsn;
                      ncbp->ncb_lana_num = vcp->lana;
Index: openafs/src/WINNT/afsd/smb3.c
diff -c openafs/src/WINNT/afsd/smb3.c:1.95.2.85 openafs/src/WINNT/afsd/smb3.c:1.95.2.86
*** openafs/src/WINNT/afsd/smb3.c:1.95.2.85	Sat Dec 27 23:41:48 2008
--- openafs/src/WINNT/afsd/smb3.c	Mon Jan 19 23:36:07 2009
***************
*** 5673,5678 ****
--- 5673,5680 ----
          
      pathp = smb_ParseASCIIBlock(inp, smb_GetSMBData(inp, NULL), NULL,
                                  SMB_STRF_ANSIPATH);
+     if (!pathp)
+         return CM_ERROR_BADSMB;
  
      spacep = inp->spacep;
      smb_StripLastComponent(spacep->wdata, &lastNamep, pathp);
***************
*** 8890,8896 ****
--- 8892,8902 ----
  
      tp = smb_GetSMBData(inp, NULL);
      oldPathp = smb_ParseASCIIBlock(inp, tp, &tp, 0);
+     if (!oldPathp)
+         return CM_ERROR_BADSMB;
      newPathp = smb_ParseASCIIBlock(inp, tp, &tp, 0);
+     if (!newPathp)
+         return CM_ERROR_BADSMB;
  
      osi_Log3(smb_logp, "NTRename for [%S]->[%S] type [%s]",
               osi_LogSaveClientString(smb_logp, oldPathp),
Index: openafs/src/WINNT/client_config/NTMakefile
diff -c openafs/src/WINNT/client_config/NTMakefile:1.11.4.7 openafs/src/WINNT/client_config/NTMakefile:1.11.4.8
*** openafs/src/WINNT/client_config/NTMakefile:1.11.4.7	Fri Dec 26 21:27:56 2008
--- openafs/src/WINNT/client_config/NTMakefile	Sun Jan  4 14:19:49 2009
***************
*** 110,116 ****
  $(EXEFILE) : $(EXEOBJS) $(EXEOBJSc) $(EXERES) $(AFSDOBJS) $(EXELIBS)
  	$(EXEGUILINK) $(VCLIBS)
  !IF ("$(AFSVER_CL)" == "1400")
!         if exist $@.manifest mt.exe -manifest afs_config.exe.manifest -out:$(MANIFEST)
  !ELSE
          $(COPY) afs_config.exe.manifest $(MANIFEST)
  !ENDIF
--- 110,116 ----
  $(EXEFILE) : $(EXEOBJS) $(EXEOBJSc) $(EXERES) $(AFSDOBJS) $(EXELIBS)
  	$(EXEGUILINK) $(VCLIBS)
  !IF ("$(AFSVER_CL)" == "1400")
!         if exist $@.manifest mt.exe -manifest afs_config.exe.manifest $@.manifest -out:$(MANIFEST)
  !ELSE
          $(COPY) afs_config.exe.manifest $(MANIFEST)
  !ENDIF
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.41 openafs/src/WINNT/doc/install/Documentation/en_US/html/index.htm:1.5.4.42
*** openafs/src/WINNT/doc/install/Documentation/en_US/html/index.htm:1.5.4.41	Mon Dec 29 17:51:32 2008
--- openafs/src/WINNT/doc/install/Documentation/en_US/html/index.htm	Thu Jan 22 11:05:20 2009
***************
*** 57,63 ****
  
  <h1>OpenAFS for Windows</h1>
  
! <h2>Version 1.5.56</h2>
  
  <p class=MsoNormal>&nbsp; </p>
  
--- 57,63 ----
  
  <h1>OpenAFS for Windows</h1>
  
! <h2>Version 1.5.57</h2>
  
  <p class=MsoNormal>&nbsp; </p>
  
***************
*** 78,84 ****
  <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.56
  Release Notes</a></p>
  
  <p style='margin-left:36.0pt;text-indent:-18.0pt;'>
--- 78,84 ----
  <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.57
  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.39 openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/logo.htm:1.1.6.40
*** openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/logo.htm:1.1.6.39	Mon Dec 29 17:51:37 2008
--- openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/logo.htm	Thu Jan 22 11:05:25 2009
***************
*** 18,24 ****
  .shape {behavior:url(#default#VML);}
  </style>
  <![endif]-->
! <title>OpenAFS for Windows 1.5.56 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.57 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.41 openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/relnotes-frames.htm:1.1.4.42
*** openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/relnotes-frames.htm:1.1.4.41	Mon Dec 29 17:51:37 2008
--- openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/relnotes-frames.htm	Thu Jan 22 11:05:25 2009
***************
*** 10,16 ****
  <meta name=Originator content="Microsoft Word 12">
  <link rel=File-List href="relnotes-frames_files/filelist.xml">
  <link rel=Preview href="relnotes-frames_files/preview.wmf">
! <title>OpenAFS for Windows 1.5.56 Release Notes</title>
  <!--[if gte mso 9]><xml>
   <o:DocumentProperties>
    <o:LastAuthor>Jeffrey Eric Altman</o:LastAuthor>
--- 10,16 ----
  <meta name=Originator content="Microsoft Word 12">
  <link rel=File-List href="relnotes-frames_files/filelist.xml">
  <link rel=Preview href="relnotes-frames_files/preview.wmf">
! <title>OpenAFS for Windows 1.5.57 Release Notes</title>
  <!--[if gte mso 9]><xml>
   <o:DocumentProperties>
    <o:LastAuthor>Jeffrey Eric Altman</o:LastAuthor>
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.47 openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/relnotes.htm:1.6.4.48
*** openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/relnotes.htm:1.6.4.47	Mon Dec 29 17:51:37 2008
--- openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/relnotes.htm	Thu Jan 22 11:05:25 2009
***************
*** 22,28 ****
  .shape {behavior:url(#default#VML);}
  </style>
  <![endif]-->
! <title>OpenAFS for Windows 1.5.56 Release Notes</title>
  <o:SmartTagType namespaceuri="urn:schemas-microsoft-com:office:smarttags"
   name="PostalCode"/>
  <o:SmartTagType namespaceuri="urn:schemas-microsoft-com:office:smarttags"
--- 22,28 ----
  .shape {behavior:url(#default#VML);}
  </style>
  <![endif]-->
! <title>OpenAFS for Windows 1.5.57 Release Notes</title>
  <o:SmartTagType namespaceuri="urn:schemas-microsoft-com:office:smarttags"
   name="PostalCode"/>
  <o:SmartTagType namespaceuri="urn:schemas-microsoft-com:office:smarttags"
***************
*** 1226,1232 ****
  
  <div class=Section1>
  
! <p class=MsoTitle>OpenAFS for Windows 1.5.56 (with Unicode Support)<br>
  Release Notes</p>
  
  <p class=MsoBodyText>The Andrew File System (AFS) is a location-independent
--- 1226,1232 ----
  
  <div class=Section1>
  
! <p class=MsoTitle>OpenAFS for Windows 1.5.57 (with Unicode Support)<br>
  Release Notes</p>
  
  <p class=MsoBodyText>The Andrew File System (AFS) is a location-independent
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.40 openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/toc.htm:1.2.6.41
*** openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/toc.htm:1.2.6.40	Mon Dec 29 17:51:37 2008
--- openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/toc.htm	Thu Jan 22 11:05:26 2009
***************
*** 12,18 ****
  <base target=body>
  <link rel=File-List href="toc_files/filelist.xml">
  <link rel=Preview href="toc_files/preview.wmf">
! <title>OpenAFS for Windows 1.5.56 Table of Contents</title>
  <!--[if gte mso 9]><xml>
   <o:DocumentProperties>
    <o:Author>Jeffrey Altman</o:Author>
--- 12,18 ----
  <base target=body>
  <link rel=File-List href="toc_files/filelist.xml">
  <link rel=Preview href="toc_files/preview.wmf">
! <title>OpenAFS for Windows 1.5.57 Table of Contents</title>
  <!--[if gte mso 9]><xml>
   <o:DocumentProperties>
    <o:Author>Jeffrey Altman</o:Author>
Index: openafs/src/WINNT/license/main.cpp
diff -c openafs/src/WINNT/license/main.cpp:1.3.4.1 openafs/src/WINNT/license/main.cpp:1.3.4.2
*** openafs/src/WINNT/license/main.cpp:1.3.4.1	Thu Jul  5 11:55:42 2007
--- openafs/src/WINNT/license/main.cpp	Mon Jan  5 13:17:01 2009
***************
*** 216,223 ****
     DWORD cbSource;
     if ((cbSource = GetFileSize (hFile, NULL)) != 0)
        {
!       LPTSTR abSource = (LPTSTR)malloc(cbSource + 1);
! 	  memset(abSource, 0x00, cbSource + 1);
  
        DWORD dwRead;
        if (!ReadFile (hFile, abSource, cbSource, &dwRead, NULL) || cbSource != dwRead)
--- 216,223 ----
     DWORD cbSource;
     if ((cbSource = GetFileSize (hFile, NULL)) != 0)
        {
!       LPTSTR abSource = (LPTSTR)malloc(cbSource + 4);
! 	  memset(abSource, 0x00, cbSource + 4);
  
        DWORD dwRead;
        if (!ReadFile (hFile, abSource, cbSource, &dwRead, NULL) || cbSource != dwRead)
***************
*** 232,238 ****
           memset (abTarget, 0x00, cbTarget);
  
           BOOL fDefault = FALSE;
!          WideCharToMultiByte (g::CodePage, 0, (LPCWSTR)abSource, cbSource, abTarget, cbTarget, TEXT(" "), &fDefault);
  
           rc = FormatFile (psz, abTarget);
  
--- 232,238 ----
           memset (abTarget, 0x00, cbTarget);
  
           BOOL fDefault = FALSE;
!          WideCharToMultiByte (g::CodePage, 0, (LPCWSTR)abSource, -1, abTarget, cbTarget, TEXT(" "), &fDefault);
  
           rc = FormatFile (psz, abTarget);
  
Index: openafs/src/afs/afs.h
diff -c openafs/src/afs/afs.h:1.85.2.14 openafs/src/afs/afs.h:1.85.2.17
*** openafs/src/afs/afs.h:1.85.2.14	Sat Nov  8 11:34:42 2008
--- openafs/src/afs/afs.h	Wed Jan 21 16:15:03 2009
***************
*** 174,188 ****
  /* The actual number of bytes in the SmallFid, not the sizeof struct. */
  #define SIZEOF_SMALLFID 10
  
  
- /*
-   * Queues implemented with both pointers and short offsets into a disk file.
-   */
  struct afs_q {
      struct afs_q *next;
      struct afs_q *prev;
  };
  
  struct vrequest {
      afs_int32 uid;		/* user id making the request */
      afs_int32 busyCount;	/* how many busies we've seen so far */
--- 174,217 ----
  /* The actual number of bytes in the SmallFid, not the sizeof struct. */
  #define SIZEOF_SMALLFID 10
  
+ /* Queues 
+  * ------
+  *
+  *  Circular queues, implemented with pointers. Structures may contain as many
+  *  queues as required, which may be located at any point within the structure,
+  *  providing the QEntry macro is used to translate between a queue pointer, and
+  *  the address of its containing structure
+  */
  
  struct afs_q {
      struct afs_q *next;
      struct afs_q *prev;
  };
  
+ #define	QInit(q)    ((q)->prev = (q)->next = (q))
+ #define	QAdd(q,e)   ((e)->next = (q)->next, (e)->prev = (q), \
+ 			(q)->next->prev = (e), (q)->next = (e))
+ #define	QRemove(e)  ((e)->next->prev = (e)->prev, (e)->prev->next = (e)->next, (e)->prev = NULL, (e)->next = NULL)
+ #define	QNext(e)    ((e)->next)
+ #define QPrev(e)    ((e)->prev)
+ #define QEmpty(q)   ((q)->prev == (q))
+ /* this one takes q1 and sticks it on the end of q2 - that is, the other end, not the end
+  * that things are added onto.  q1 shouldn't be empty, it's silly */
+ #define QCat(q1,q2) ((q2)->prev->next = (q1)->next, (q1)->next->prev=(q2)->prev, (q1)->prev->next=(q2), (q2)->prev=(q1)->prev, (q1)->prev=(q1)->next=(q1))
+ 
+ /* Given a pointer to an afs_q within a structure, go back to the address of
+  * the parent structure
+  */
+ 
+ #define QEntry(queue, structure, member) \
+ 	((structure *)((char *)(queue)-(char *)(&((structure *)NULL)->member)))
+ 
+ /* And implement operations for individual lists in terms of the above macro */
+ 
+ #define QTOV(e)	    QEntry(e, struct vcache, vlruq)
+ #define QTOC(e)	    QEntry(e, struct cell, lruq)
+ #define QTOVH(e)    QEntry(e, struct vcache, vhashq)
+ 
  struct vrequest {
      afs_int32 uid;		/* user id making the request */
      afs_int32 busyCount;	/* how many busies we've seen so far */
***************
*** 298,306 ****
      void *cellinfo;             /* pointer to cell info (PAG manager only) */
  };
  
! struct conn {
      /* Per-connection block. */
!     struct conn *next;		/* Next dude same server. */
      struct unixuser *user;	/* user validated with respect to. */
      struct rx_connection *id;	/* RPC connid. */
      struct srvAddr *srvr;	/* server associated with this conn */
--- 327,335 ----
      void *cellinfo;             /* pointer to cell info (PAG manager only) */
  };
  
! struct afs_conn {
      /* Per-connection block. */
!     struct afs_conn *next;		/* Next dude same server. */
      struct unixuser *user;	/* user validated with respect to. */
      struct rx_connection *id;	/* RPC connid. */
      struct srvAddr *srvr;	/* server associated with this conn */
***************
*** 325,353 ****
  	 (!(afid)->Fid.Unique && ((tvc)->states & CUnique))))
  
  
- /*
-   * Operations on circular queues implemented with pointers.  Note: these queue
-   * objects are always located at the beginning of the structures they are linking.
-   */
- #define	QInit(q)    ((q)->prev = (q)->next = (q))
- #define	QAdd(q,e)   ((e)->next = (q)->next, (e)->prev = (q), \
- 			(q)->next->prev = (e), (q)->next = (e))
- #define	QRemove(e)  ((e)->next->prev = (e)->prev, (e)->prev->next = (e)->next, (e)->prev = NULL, (e)->next = NULL)
- #define	QNext(e)    ((e)->next)
- #define QPrev(e)    ((e)->prev)
- #define QEmpty(q)   ((q)->prev == (q))
- /* this one takes q1 and sticks it on the end of q2 - that is, the other end, not the end
-  * that things are added onto.  q1 shouldn't be empty, it's silly */
- #define QCat(q1,q2) ((q2)->prev->next = (q1)->next, (q1)->next->prev=(q2)->prev, (q1)->prev->next=(q2), (q2)->prev=(q1)->prev, (q1)->prev=(q1)->next=(q1))
- /*
-  * Do lots of address arithmetic to go from vlruq to the base of the vcache
-  * structure.  Don't move struct vnode, since we think of a struct vcache as
-  * a specialization of a struct vnode
-  */
- #define	QTOV(e)	    ((struct vcache *)(((char *) (e)) - (((char *)(&(((struct vcache *)(e))->vlruq))) - ((char *)(e)))))
- #define	QTOC(e)	    ((struct cell *)((char *) (e)))
- #define	QTOVH(e)   ((struct vcache *)(((char *) (e)) - (((char *)(&(((struct vcache *)(e))->vhashq))) - ((char *)(e)))))
- 
  #define	SRVADDR_MH	1
  #define	SRVADDR_ISDOWN	0x20	/* same as SRVR_ISDOWN */
  #define  SRVADDR_NOUSE    0x40	/* Don't use this srvAddr */
--- 354,359 ----
***************
*** 355,361 ****
      struct srvAddr *next_bkt;	/* next item in hash bucket */
      struct srvAddr *next_sa;	/* another interface on same host */
      struct server *server;	/* back to parent */
!     struct conn *conns;		/* All user connections to this server */
      afs_int32 sa_ip;		/* Host addr in network byte order */
      u_short sa_iprank;		/* indiv ip address priority */
      u_short sa_portal;		/* port addr in network byte order */
--- 361,367 ----
      struct srvAddr *next_bkt;	/* next item in hash bucket */
      struct srvAddr *next_sa;	/* another interface on same host */
      struct server *server;	/* back to parent */
!     struct afs_conn *conns;		/* All user connections to this server */
      afs_int32 sa_ip;		/* Host addr in network byte order */
      u_short sa_iprank;		/* indiv ip address priority */
      u_short sa_portal;		/* port addr in network byte order */
***************
*** 590,598 ****
  #define VDisconWriteFlush	0x00000800	/* Write op on normal fsync/flush. */
  #define VDisconWriteOsiFlush	0x00001000	/* Write op on osi flush. */
  
! #define VDisconShadowed		0x00002000	/* Shadowed dir. */
! #define VDisconRemove		0x00004000	/* Remove vnop. */
! #define VDisconCreate		0x00008000	/* Create vnop. */
  #define VDisconRename		0x00010000	/* Rename vnop. */
  #define VDisconRenameSameDir	0x00020000	/* Rename in same dir. */
  
--- 596,605 ----
  #define VDisconWriteFlush	0x00000800	/* Write op on normal fsync/flush. */
  #define VDisconWriteOsiFlush	0x00001000	/* Write op on osi flush. */
  
! #define VDisconRemove		0x00002000	/* Remove vnop. */
! #define VDisconCreate		0x00004000	/* Create vnop. */
! #define VDisconCreated		0x00008000	/* A file that was created during
! 						   this resync operation */
  #define VDisconRename		0x00010000	/* Rename vnop. */
  #define VDisconRenameSameDir	0x00020000	/* Rename in same dir. */
  
***************
*** 679,688 ****
  #endif
      struct vcache *hnext;	/* Hash next */
      struct afs_q vhashq;	/* Hashed per-volume list */
- 
  #if defined(AFS_DISCON_ENV)
!     /*! Next element in afs_DDirtyVCList. Lock it with afs_DDirtyVCListLock. */
!     struct vcache *ddirty_next;
      /*! Disconnected flags for this vcache element. */
      uint32_t ddirty_flags;
      /*! Shadow vnode + unique keep the shadow dir location. */
--- 686,696 ----
  #endif
      struct vcache *hnext;	/* Hash next */
      struct afs_q vhashq;	/* Hashed per-volume list */
  #if defined(AFS_DISCON_ENV)
!     /*! Queue of dirty vcaches. Lock with afs_disconDirtyLock */
!     struct afs_q dirtyq;
!     /*! Queue of vcaches with shadow entries. Lock with afs_disconDirtyLock */
!     struct afs_q shadowq;
      /*! Disconnected flags for this vcache element. */
      uint32_t ddirty_flags;
      /*! Shadow vnode + unique keep the shadow dir location. */
Index: openafs/src/afs/afs_analyze.c
diff -c openafs/src/afs/afs_analyze.c:1.22.14.12 openafs/src/afs/afs_analyze.c:1.22.14.14
*** openafs/src/afs/afs_analyze.c:1.22.14.12	Mon Oct 27 19:53:44 2008
--- openafs/src/afs/afs_analyze.c	Wed Jan 21 16:15:03 2009
***************
*** 14,20 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_analyze.c,v 1.22.14.12 2008/10/27 23:53:44 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
--- 14,20 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_analyze.c,v 1.22.14.14 2009/01/21 21:15:03 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 93,99 ****
  VLDB_Same(struct VenusFid *afid, struct vrequest *areq)
  {
      struct vrequest treq;
!     struct conn *tconn;
      int i, type = 0;
      union {
  	struct vldbentry tve;
--- 93,99 ----
  VLDB_Same(struct VenusFid *afid, struct vrequest *areq)
  {
      struct vrequest treq;
!     struct afs_conn *tconn;
      int i, type = 0;
      union {
  	struct vldbentry tve;
***************
*** 307,313 ****
   *	if this is a temporary or permanent error.
   *------------------------------------------------------------------------*/
  int
! afs_Analyze(register struct conn *aconn, afs_int32 acode,
  	    struct VenusFid *afid, register struct vrequest *areq, int op,
  	    afs_int32 locktype, struct cell *cellp)
  {
--- 307,313 ----
   *	if this is a temporary or permanent error.
   *------------------------------------------------------------------------*/
  int
! afs_Analyze(register struct afs_conn *aconn, afs_int32 acode,
  	    struct VenusFid *afid, register struct vrequest *areq, int op,
  	    afs_int32 locktype, struct cell *cellp)
  {
***************
*** 321,330 ****
      afs_int32 markeddown;
  
   
!     if (AFS_IS_DISCONNECTED) {
  	/* SXW - This may get very tired after a while. We should try and
  	 *       intercept all RPCs before they get here ... */
! 	/*printf("afs_Analyze: disconnected\n");*/
  	afs_FinalizeReq(areq);
  	if (aconn) {
  	    /* SXW - I suspect that this will _never_ happen - we shouldn't
--- 321,330 ----
      afs_int32 markeddown;
  
   
!     if (AFS_IS_DISCONNECTED && !AFS_IN_SYNC) {
  	/* SXW - This may get very tired after a while. We should try and
  	 *       intercept all RPCs before they get here ... */
! 	/* printf("afs_Analyze: disconnected\n"); */
  	afs_FinalizeReq(areq);
  	if (aconn) {
  	    /* SXW - I suspect that this will _never_ happen - we shouldn't
Index: openafs/src/afs/afs_buffer.c
diff -c openafs/src/afs/afs_buffer.c:1.22.4.3 openafs/src/afs/afs_buffer.c:1.22.4.5
*** openafs/src/afs/afs_buffer.c:1.22.4.3	Sat Nov  8 11:34:42 2008
--- openafs/src/afs/afs_buffer.c	Wed Jan 21 16:15:03 2009
***************
*** 11,17 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_buffer.c,v 1.22.4.3 2008/11/08 16:34:42 shadow Exp $");
  
  #include "afs/sysincludes.h"
  #include "afsincludes.h"
--- 11,17 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_buffer.c,v 1.22.4.5 2009/01/21 21:15:03 shadow Exp $");
  
  #include "afs/sysincludes.h"
  #include "afsincludes.h"
***************
*** 476,488 ****
      MReleaseReadLock(&afs_bufferLock);
  }
  
  void
  DFlush(void)
  {
      /* Flush all the modified buffers. */
      register int i;
      register struct buffer *tb;
-     struct osi_file *tfile;
  
      AFS_STATCNT(DFlush);
      tb = Buffers;
--- 476,527 ----
      MReleaseReadLock(&afs_bufferLock);
  }
  
+ static void
+ DFlushBuffer(struct buffer *ab) {
+     struct osi_file *tfile;
+     
+ #if defined(LINUX_USE_FH)
+     tfile = afs_CFileOpen(&ab->fh, ab->fh_type);
+ #else
+     tfile = afs_CFileOpen(ab->inode);
+ #endif
+     afs_CFileWrite(tfile, ab->page * AFS_BUFFER_PAGESIZE,
+ 		   ab->data, AFS_BUFFER_PAGESIZE);
+     ab->dirty = 0;	/* Clear the dirty flag */
+     afs_CFileClose(tfile);
+ }
+ 
+ void
+ DFlushDCache(struct dcache *adc) 
+ {
+     int i;
+     struct buffer *tb;
+ 
+     ObtainReadLock(&afs_bufferLock);
+ 
+     for (i = 0; i <= PHPAGEMASK; i++)
+         for (tb = phTable[pHash(adc->index, i)]; tb; tb = tb->hashNext)
+ 	    if (tb->fid == adc->index) {
+ 		ObtainWriteLock(&tb->lock, 701);
+ 		tb->lockers++;
+ 		ReleaseReadLock(&afs_bufferLock);
+ 		if (tb->dirty) {
+ 		    DFlushBuffer(tb);
+ 		}
+ 		tb->lockers--;
+ 		ReleaseWriteLock(&tb->lock);
+ 		ObtainReadLock(&afs_bufferLock);
+ 	    }
+ 
+     ReleaseReadLock(&afs_bufferLock);
+ }
+ 
  void
  DFlush(void)
  {
      /* Flush all the modified buffers. */
      register int i;
      register struct buffer *tb;
  
      AFS_STATCNT(DFlush);
      tb = Buffers;
***************
*** 504,518 ****
  		 * we cannot lock afs_xdcache). In addition, we cannot obtain
  		 * a dcache lock while holding the tb->lock of the same file
  		 * since that can deadlock with DRead/DNew */
! #if defined(LINUX_USE_FH)
! 		tfile = afs_CFileOpen(&tb->fh, tb->fh_type);
! #else
! 		tfile = afs_CFileOpen(tb->inode);
! #endif
! 		afs_CFileWrite(tfile, tb->page * AFS_BUFFER_PAGESIZE,
! 			       tb->data, AFS_BUFFER_PAGESIZE);
! 		tb->dirty = 0;	/* Clear the dirty flag */
! 		afs_CFileClose(tfile);
  	    }
  	    tb->lockers--;
  	    MReleaseWriteLock(&tb->lock);
--- 543,549 ----
  		 * we cannot lock afs_xdcache). In addition, we cannot obtain
  		 * a dcache lock while holding the tb->lock of the same file
  		 * since that can deadlock with DRead/DNew */
! 		DFlushBuffer(tb);
  	    }
  	    tb->lockers--;
  	    MReleaseWriteLock(&tb->lock);
Index: openafs/src/afs/afs_bypasscache.c
diff -c openafs/src/afs/afs_bypasscache.c:1.1.2.2 openafs/src/afs/afs_bypasscache.c:1.1.2.3
*** openafs/src/afs/afs_bypasscache.c:1.1.2.2	Mon Sep 22 15:35:26 2008
--- openafs/src/afs/afs_bypasscache.c	Wed Jan 21 15:07:47 2009
***************
*** 533,539 ****
      struct vrequest *areq;
      afs_int32 code, length_hi, bytes, locked;    
  	
!     register struct conn *tc;
      afs_int32 i;
      struct rx_call *tcall;
      struct tlocal1 {
--- 533,539 ----
      struct vrequest *areq;
      afs_int32 code, length_hi, bytes, locked;    
  	
!     register struct afs_conn *tc;
      afs_int32 i;
      struct rx_call *tcall;
      struct tlocal1 {
Index: openafs/src/afs/afs_callback.c
diff -c openafs/src/afs/afs_callback.c:1.39.2.5 openafs/src/afs/afs_callback.c:1.39.2.6
*** openafs/src/afs/afs_callback.c:1.39.2.5	Mon Sep 22 15:29:53 2008
--- openafs/src/afs/afs_callback.c	Wed Jan 21 16:15:03 2009
***************
*** 17,23 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_callback.c,v 1.39.2.5 2008/09/22 19:29:53 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
--- 17,23 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_callback.c,v 1.39.2.6 2009/01/21 21:15:03 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
***************
*** 68,74 ****
  #endif
  #ifdef AFS_DISCON_ENV
      { "afs_discon_lock", (char *)&afs_discon_lock},
!     { "afs_DDirtyVCListLock", (char *)&afs_DDirtyVCListLock},
  #endif
  };
  unsigned long lastCallBack_vnode;
--- 68,74 ----
  #endif
  #ifdef AFS_DISCON_ENV
      { "afs_discon_lock", (char *)&afs_discon_lock},
!     { "afs_disconDirtyLock", (char *)&afs_disconDirtyLock},
  #endif
  };
  unsigned long lastCallBack_vnode;
Index: openafs/src/afs/afs_conn.c
diff -c openafs/src/afs/afs_conn.c:1.14.8.7 openafs/src/afs/afs_conn.c:1.14.8.8
*** openafs/src/afs/afs_conn.c:1.14.8.7	Mon Oct 20 12:40:48 2008
--- openafs/src/afs/afs_conn.c	Wed Jan 21 15:07:47 2009
***************
*** 14,20 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_conn.c,v 1.14.8.7 2008/10/20 16:40:48 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
--- 14,20 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_conn.c,v 1.14.8.8 2009/01/21 20:07:47 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 63,75 ****
   *
   * @return The conn struct, or NULL.
   */
! struct conn *
  afs_Conn(register struct VenusFid *afid, register struct vrequest *areq,
  	 afs_int32 locktype)
  {
      u_short fsport = AFS_FSPORT;
      struct volume *tv;
!     struct conn *tconn = NULL;
      struct srvAddr *lowp = NULL;
      struct unixuser *tu;
      int notbusy;
--- 63,75 ----
   *
   * @return The conn struct, or NULL.
   */
! struct afs_conn *
  afs_Conn(register struct VenusFid *afid, register struct vrequest *areq,
  	 afs_int32 locktype)
  {
      u_short fsport = AFS_FSPORT;
      struct volume *tv;
!     struct afs_conn *tconn = NULL;
      struct srvAddr *lowp = NULL;
      struct unixuser *tu;
      int notbusy;
***************
*** 157,168 ****
   *
   * @return The new connection.
   */
! struct conn *
  afs_ConnBySA(struct srvAddr *sap, unsigned short aport, afs_int32 acell,
  	     struct unixuser *tu, int force_if_down, afs_int32 create,
  	     afs_int32 locktype)
  {
!     struct conn *tc = 0;
      struct rx_securityClass *csec;	/*Security class object */
      int isec;			/*Security index */
      int service;
--- 157,168 ----
   *
   * @return The new connection.
   */
! struct afs_conn *
  afs_ConnBySA(struct srvAddr *sap, unsigned short aport, afs_int32 acell,
  	     struct unixuser *tu, int force_if_down, afs_int32 create,
  	     afs_int32 locktype)
  {
!     struct afs_conn *tc = 0;
      struct rx_securityClass *csec;	/*Security class object */
      int isec;			/*Security index */
      int service;
***************
*** 200,207 ****
  	 * gets set, marking the time of its ``birth''.
  	 */
  	UpgradeSToWLock(&afs_xconn, 37);
! 	tc = (struct conn *)afs_osi_Alloc(sizeof(struct conn));
! 	memset((char *)tc, 0, sizeof(struct conn));
  
  	tc->user = tu;
  	tc->port = aport;
--- 200,207 ----
  	 * gets set, marking the time of its ``birth''.
  	 */
  	UpgradeSToWLock(&afs_xconn, 37);
! 	tc = (struct afs_conn *)afs_osi_Alloc(sizeof(struct afs_conn));
! 	memset((char *)tc, 0, sizeof(struct afs_conn));
  
  	tc->user = tu;
  	tc->port = aport;
***************
*** 300,311 ****
   *
   * @return The established connection.
   */
! struct conn *
  afs_ConnByHost(struct server *aserver, unsigned short aport, afs_int32 acell,
  	       struct vrequest *areq, int aforce, afs_int32 locktype)
  {
      struct unixuser *tu;
!     struct conn *tc = 0;
      struct srvAddr *sa = 0;
  
      AFS_STATCNT(afs_ConnByHost);
--- 300,311 ----
   *
   * @return The established connection.
   */
! struct afs_conn *
  afs_ConnByHost(struct server *aserver, unsigned short aport, afs_int32 acell,
  	       struct vrequest *areq, int aforce, afs_int32 locktype)
  {
      struct unixuser *tu;
!     struct afs_conn *tc = 0;
      struct srvAddr *sa = 0;
  
      AFS_STATCNT(afs_ConnByHost);
***************
*** 359,371 ****
   *
   * @return The established connection or NULL.
   */
! struct conn *
  afs_ConnByMHosts(struct server *ahosts[], unsigned short aport,
  		 afs_int32 acell, register struct vrequest *areq,
  		 afs_int32 locktype)
  {
      register afs_int32 i;
!     register struct conn *tconn;
      register struct server *ts;
  
      /* try to find any connection from the set */
--- 359,371 ----
   *
   * @return The established connection or NULL.
   */
! struct afs_conn *
  afs_ConnByMHosts(struct server *ahosts[], unsigned short aport,
  		 afs_int32 acell, register struct vrequest *areq,
  		 afs_int32 locktype)
  {
      register afs_int32 i;
!     register struct afs_conn *tconn;
      register struct server *ts;
  
      /* try to find any connection from the set */
***************
*** 389,395 ****
   * @param locktype
   */
  void
! afs_PutConn(register struct conn *ac, afs_int32 locktype)
  {
      AFS_STATCNT(afs_PutConn);
      ac->refCount--;
--- 389,395 ----
   * @param locktype
   */
  void
! afs_PutConn(register struct afs_conn *ac, afs_int32 locktype)
  {
      AFS_STATCNT(afs_PutConn);
      ac->refCount--;
***************
*** 406,412 ****
  void
  ForceNewConnections(struct srvAddr *sap)
  {
!     struct conn *tc = 0;
  
      if (!sap)
  	return;			/* defensive check */
--- 406,412 ----
  void
  ForceNewConnections(struct srvAddr *sap)
  {
!     struct afs_conn *tc = 0;
  
      if (!sap)
  	return;			/* defensive check */
Index: openafs/src/afs/afs_dcache.c
diff -c openafs/src/afs/afs_dcache.c:1.64.4.16 openafs/src/afs/afs_dcache.c:1.64.4.21
*** openafs/src/afs/afs_dcache.c:1.64.4.16	Sun Nov 30 15:17:24 2008
--- openafs/src/afs/afs_dcache.c	Wed Jan 21 16:17:47 2009
***************
*** 14,20 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_dcache.c,v 1.64.4.16 2008/11/30 20:17:24 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
--- 14,20 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_dcache.c,v 1.64.4.21 2009/01/21 21:17:47 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
***************
*** 1862,1868 ****
      struct tlocal1 *tsmall = 0;
      register struct dcache *tdc;
      register struct osi_file *file;
!     register struct conn *tc;
      int downDCount = 0;
      struct server *newCallback = NULL;
      char setNewCallback;
--- 1862,1868 ----
      struct tlocal1 *tsmall = 0;
      register struct dcache *tdc;
      register struct osi_file *file;
!     register struct afs_conn *tc;
      int downDCount = 0;
      struct server *newCallback = NULL;
      char setNewCallback;
***************
*** 3664,3689 ****
  
  }
  
  #if defined(AFS_DISCON_ENV)
  
  /*!
!  * Make a shadow copy of a dir's dcaches. It's used for disconnected
   * operations like remove/create/rename to keep the original directory data.
   * On reconnection, we can diff the original data with the server and get the
   * server changes and with the local data to get the local changes.
   *
   * \param avc The dir vnode.
   *
   * \return 0 for success.
   *
-  * \note The only lock allowed to be set is the dir's vcache entry, and it
-  * must be set in write mode.
   * \note The vcache entry must be write locked.
   */
! int afs_MakeShadowDir(struct vcache *avc)
  {
!     int j, i, index, code, ret_code = 0, offset, trans_size, block;
!     struct dcache *tdc, *new_dc = NULL;
      struct osi_file *tfile_src, *tfile_dst;
      struct VenusFid shadow_fid;
      char *data;
--- 3664,3773 ----
  
  }
  
+ /*!
+  * Get a dcache ready for writing, respecting the current cache size limits
+  *
+  * len is required because afs_GetDCache with flag == 4 expects the length 
+  * field to be filled. It decides from this whether it's necessary to fetch 
+  * data into the chunk before writing or not (when the whole chunk is 
+  * overwritten!).
+  *
+  * \param avc 		The vcache to fetch a dcache for
+  * \param filePos 	The start of the section to be written
+  * \param len		The length of the section to be written
+  * \param areq
+  * \param noLock
+  *
+  * \return If successful, a reference counted dcache with tdc->lock held. Lock
+  *         must be released and afs_PutDCache() called to free dcache. 
+  *         NULL on  failure
+  *
+  * \note avc->lock must be held on entry. Function may release and reobtain 
+  *       avc->lock and GLOCK.
+  */
+ 
+ struct dcache *
+ afs_ObtainDCacheForWriting(struct vcache *avc, afs_size_t filePos, 
+ 			   afs_size_t len, struct vrequest *areq,
+ 			   int noLock) {
+     struct dcache *tdc = NULL;
+     afs_size_t offset;
+ 
+     /* read the cached info */
+     if (noLock) {
+ 	tdc = afs_FindDCache(avc, filePos);
+ 	if (tdc)
+ 	    ObtainWriteLock(&tdc->lock, 657);
+     } else if (afs_blocksUsed >
+     	       PERCENT(CM_WAITFORDRAINPCT, afs_cacheBlocks)) {
+ 	tdc = afs_FindDCache(avc, filePos);
+ 	if (tdc) {
+ 	    ObtainWriteLock(&tdc->lock, 658);
+ 	    if (!hsame(tdc->f.versionNo, avc->m.DataVersion)
+ 		|| (tdc->dflags & DFFetching)) {
+ 		ReleaseWriteLock(&tdc->lock);
+ 		afs_PutDCache(tdc);
+ 		tdc = NULL;
+ 	    }
+ 	}
+ 	if (!tdc) {
+ 	    afs_MaybeWakeupTruncateDaemon();
+ 	    while (afs_blocksUsed >
+ 		   PERCENT(CM_WAITFORDRAINPCT, afs_cacheBlocks)) {
+ 		ReleaseWriteLock(&avc->lock);
+ 		if (afs_blocksUsed - afs_blocksDiscarded >
+ 		    PERCENT(CM_WAITFORDRAINPCT, afs_cacheBlocks)) {
+ 		    afs_WaitForCacheDrain = 1;
+ 		    afs_osi_Sleep(&afs_WaitForCacheDrain);
+ 		}
+ 		afs_MaybeFreeDiscardedDCache();
+ 		afs_MaybeWakeupTruncateDaemon();
+ 		ObtainWriteLock(&avc->lock, 509);
+ 	    }
+ 	    avc->states |= CDirty;
+ 	    tdc = afs_GetDCache(avc, filePos, areq, &offset, &len, 4);
+ 	    if (tdc)
+ 		ObtainWriteLock(&tdc->lock, 659);
+ 	}
+     } else {
+ 	tdc = afs_GetDCache(avc, filePos, areq, &offset, &len, 4);
+ 	if (tdc)
+ 	    ObtainWriteLock(&tdc->lock, 660);
+     }
+     if (tdc) {
+ 	if (!(afs_indexFlags[tdc->index] & IFDataMod)) {
+ 	    afs_stats_cmperf.cacheCurrDirtyChunks++;
+ 	    afs_indexFlags[tdc->index] |= IFDataMod;	/* so it doesn't disappear */
+ 	}
+ 	if (!(tdc->f.states & DWriting)) {
+ 	    /* don't mark entry as mod if we don't have to */
+ 	    tdc->f.states |= DWriting;
+ 	    tdc->dflags |= DFEntryMod;
+ 	}
+     }
+     return tdc;
+ }
+ 
  #if defined(AFS_DISCON_ENV)
  
  /*!
!  * Make a shadow copy of a dir's dcache. It's used for disconnected
   * operations like remove/create/rename to keep the original directory data.
   * On reconnection, we can diff the original data with the server and get the
   * server changes and with the local data to get the local changes.
   *
   * \param avc The dir vnode.
+  * \param adc The dir dcache.
   *
   * \return 0 for success.
   *
   * \note The vcache entry must be write locked.
+  * \note The dcache entry must be read locked.
   */
! int afs_MakeShadowDir(struct vcache *avc, struct dcache *adc)
  {
!     int i, code, ret_code = 0, written, trans_size;
!     struct dcache *new_dc = NULL;
      struct osi_file *tfile_src, *tfile_dst;
      struct VenusFid shadow_fid;
      char *data;
***************
*** 3693,3846 ****
      if (vType(avc) != VDIR)
      	return ENOTDIR;
  
      /* Generate a fid for the shadow dir. */
      shadow_fid.Cell = avc->fid.Cell;
      shadow_fid.Fid.Volume = avc->fid.Fid.Volume;
      afs_GenShadowFid(&shadow_fid);
  
!     /* For each dcache, do copy it into a new fresh one. */
!     i = DVHash(&avc->fid);
!     for (index = afs_dvhashTbl[i]; index != NULLIDX; index = i) {
!     	/* Making sure that this isn't going to get locked twice. */
! 	if (!lock_held) {
! 	    /* XXX: Moved it from outside of the loop.
! 	     * Maybe it's not quite okay because of the use of
! 	     * dvhashTbl (once) in the for statement.
! 	     */
! 	    ObtainWriteLock(&afs_xdcache, 716);
! 	    lock_held = 1;
! 	}
  
!         i = afs_dvnextTbl[index];
!         if (afs_indexUnique[index] == avc->fid.Fid.Unique) {
!             tdc = afs_GetDSlot(index, NULL);
  
! 	    ReleaseReadLock(&tdc->tlock);
  
! 	    if (!FidCmp(&tdc->f.fid, &avc->fid)) {
! 
! 		/* Got a dir's dcache. */
! 		lock_held = 0;
! 
! 		/* Get a fresh dcache. */
! 		new_dc = afs_AllocDCache(avc, 0, 0, &shadow_fid);
! 
! 		/* Unlock hash for now. Don't need it during operations on the
! 		 * dcache. Oh, and we can't use it because of the locking
! 		 * hierarchy...
! 		 */
! 		/* XXX: So much for lock ierarchy, the afs_AllocDCache doesn't
! 		 * respect it.
! 		 */
! 		//ReleaseWriteLock(&afs_xdcache);
! 
! 		ObtainReadLock(&tdc->lock);
! 
! 		/* Set up the new fid. */
! 		/* Copy interesting data from original dir dcache. */
! 		new_dc->mflags = tdc->mflags;
! 		new_dc->dflags = tdc->dflags;
! 		new_dc->f.modTime = tdc->f.modTime;
! 		new_dc->f.versionNo = tdc->f.versionNo;
! 		new_dc->f.states = tdc->f.states;
! 		new_dc->f.chunk= tdc->f.chunk;
! 		new_dc->f.chunkBytes = tdc->f.chunkBytes;
! 
! 		/*
! 		 * Now add to the two hash chains - note that i is still set
! 		 * from the above DCHash call.
! 		 */
! 		//ObtainWriteLock(&afs_xdcache, 713);
! 
! 		j = DCHash(&shadow_fid, 0);
! 		afs_dcnextTbl[new_dc->index] = afs_dchashTbl[j];
! 		afs_dchashTbl[j] = new_dc->index;
! 
! 		j = DVHash(&shadow_fid);
! 		afs_dvnextTbl[new_dc->index] = afs_dvhashTbl[j];
! 		afs_dvhashTbl[j] = new_dc->index;
! 		afs_MaybeWakeupTruncateDaemon();
! 
! 		ReleaseWriteLock(&afs_xdcache);
! 
! 		/* Alloc a 4k block. */
! 		data = (char *) afs_osi_Alloc(4096);
! 		if (!data) {
! 		    printf("afs_MakeShadowDir: could not alloc data\n");
! 		    ret_code = ENOMEM;
! 		    goto done;
! 		}
! 
! 		/* Open the files. */
! 		tfile_src = afs_CFileOpen(tdc->f.inode);
! 		tfile_dst = afs_CFileOpen(new_dc->f.inode);
! 
! 		/* Init no of blocks to be read and offset. */
! 		block = (tdc->f.chunkBytes / 4096);
! 		offset = 0;
! 
! 		/* And now copy dir dcache data into this dcache,
! 		 * 4k at a time.
! 		 */
! 		while (block >= 0) {
  
! 		    /* Last chunk might have less bytes to transfer. */
! 		    if (!block) {
! 		    	/* Last block. */
! 		    	trans_size = (tdc->f.chunkBytes % 4096);
! 			if (!trans_size)
! 			    /* An exact no of 4k blocks. */
! 			    break;
! 		    } else
! 		    	trans_size = 4096;
  
! 		    /* Read a chunk from the dcache. */
! 		    code = afs_CFileRead(tfile_src, offset, data, trans_size);
! 		    if (code < trans_size) {
! 		    	/* Can't access file, stop doing stuff and return error. */
! 		    	ret_code = EIO;
! 		    	break;
! 		    }
  
! 		    /* Write it to the new dcache. */
! 		    code = afs_CFileWrite(tfile_dst, offset, data, trans_size);
! 		    if (code < trans_size) {
! 		    	ret_code = EIO;
! 		    	break;
! 		    }
  
! 		    block--;
! 		    offset += 4096;
! 		}		/* while (block) */
  
! 		afs_CFileClose(tfile_dst);
! 		afs_CFileClose(tfile_src);
  
! 		afs_osi_Free(data, 4096);
  
! 		ReleaseWriteLock(&new_dc->lock);
! 		ReleaseReadLock(&tdc->lock);
  
! 		afs_PutDCache(new_dc);
! 	    }			/* if dcache fid match */
!             afs_PutDCache(tdc);
!         }			/* if unuiquifier match */
!     }
! done:
!     if (lock_held)
! 	ReleaseWriteLock(&afs_xdcache);
  
      if (!ret_code) {
!     	if (!avc->ddirty_flags) {
! 	    ObtainWriteLock(&afs_DDirtyVCListLock, 763);
! 	    AFS_DISCON_ADD_DIRTY(avc, 1);
! 	    ReleaseWriteLock(&afs_DDirtyVCListLock);
! 	}
  	avc->shVnode = shadow_fid.Fid.Vnode;
  	avc->shUnique = shadow_fid.Fid.Unique;
- 	avc->ddirty_flags |= VDisconShadowed;
      }
  
      return ret_code;
  }
  
--- 3777,3879 ----
      if (vType(avc) != VDIR)
      	return ENOTDIR;
  
+     if (avc->shVnode || avc->shUnique)
+ 	return EEXIST;
+ 
      /* Generate a fid for the shadow dir. */
      shadow_fid.Cell = avc->fid.Cell;
      shadow_fid.Fid.Volume = avc->fid.Fid.Volume;
      afs_GenShadowFid(&shadow_fid);
  
!     ObtainWriteLock(&afs_xdcache, 716);
  
!     /* Get a fresh dcache. */
!     new_dc = afs_AllocDCache(avc, 0, 0, &shadow_fid);
  
!     ObtainReadLock(&adc->mflock);
  
!     /* Set up the new fid. */
!     /* Copy interesting data from original dir dcache. */
!     new_dc->mflags = adc->mflags;
!     new_dc->dflags = adc->dflags;
!     new_dc->f.modTime = adc->f.modTime;
!     new_dc->f.versionNo = adc->f.versionNo;
!     new_dc->f.states = adc->f.states;
!     new_dc->f.chunk= adc->f.chunk;
!     new_dc->f.chunkBytes = adc->f.chunkBytes;
  
!     ReleaseReadLock(&adc->mflock);
!     
!     /* Now add to the two hash chains */
!     i = DCHash(&shadow_fid, 0);
!     afs_dcnextTbl[new_dc->index] = afs_dchashTbl[i];
!     afs_dchashTbl[i] = new_dc->index;
! 
!     i = DVHash(&shadow_fid);
!     afs_dvnextTbl[new_dc->index] = afs_dvhashTbl[i];
!     afs_dvhashTbl[i] = new_dc->index;
  
!     ReleaseWriteLock(&afs_xdcache);
  
!     /* Alloc a 4k block. */
!     data = (char *) afs_osi_Alloc(4096);
!     if (!data) {
! 	printf("afs_MakeShadowDir: could not alloc data\n");
! 	ret_code = ENOMEM;
! 	goto done;
!     }
! 
!     /* Open the files. */
!     tfile_src = afs_CFileOpen(adc->f.inode);
!     tfile_dst = afs_CFileOpen(new_dc->f.inode);
! 
!     /* And now copy dir dcache data into this dcache,
!      * 4k at a time.
!      */
!     written = 0;
!     while (written < adc->f.chunkBytes) {
! 	trans_size = adc->f.chunkBytes - written;
! 	if (trans_size > 4096)
! 	    trans_size = 4096;
! 
! 	/* Read a chunk from the dcache. */
! 	code = afs_CFileRead(tfile_src, written, data, trans_size);
! 	if (code < trans_size) {
! 	    ret_code = EIO;
! 	    break;
! 	}
  
! 	/* Write it to the new dcache. */
! 	code = afs_CFileWrite(tfile_dst, written, data, trans_size);
! 	if (code < trans_size) {
! 	    ret_code = EIO;
! 	    break;
! 	}
  
! 	written+=trans_size;
!     }
  
!     afs_CFileClose(tfile_dst);
!     afs_CFileClose(tfile_src);
  
!     afs_osi_Free(data, 4096);
  
!     ReleaseWriteLock(&new_dc->lock);
!     afs_PutDCache(new_dc);
  
      if (!ret_code) {
! 	ObtainWriteLock(&afs_xvcache, 763);
! 	ObtainWriteLock(&afs_disconDirtyLock, 765);
! 	QAdd(&afs_disconShadow, &avc->shadowq);
! 	osi_vnhold(avc, 0);
! 	ReleaseWriteLock(&afs_disconDirtyLock);
! 	ReleaseWriteLock(&afs_xvcache);
! 
  	avc->shVnode = shadow_fid.Fid.Vnode;
  	avc->shUnique = shadow_fid.Fid.Unique;
      }
  
+ done:
      return ret_code;
  }
  
***************
*** 3867,3873 ****
  	afs_DiscardDCache(tdc);
      	afs_PutDCache(tdc);
      }
!     /* Remove shadowed dir flag. */
!     avc->ddirty_flags &= ~VDisconShadowed;
  }
  #endif
--- 3900,3908 ----
  	afs_DiscardDCache(tdc);
      	afs_PutDCache(tdc);
      }
!     avc->shVnode = avc->shUnique = 0;
!     ObtainWriteLock(&afs_disconDirtyLock, 708);
!     QRemove(&avc->shadowq);
!     ReleaseWriteLock(&afs_disconDirtyLock);
  }
  #endif
Index: openafs/src/afs/afs_disconnected.c
diff -c openafs/src/afs/afs_disconnected.c:1.2.2.5 openafs/src/afs/afs_disconnected.c:1.2.2.9
*** openafs/src/afs/afs_disconnected.c:1.2.2.5	Sun Nov 30 15:11:17 2008
--- openafs/src/afs/afs_disconnected.c	Wed Jan 21 16:15:04 2009
***************
*** 7,13 ****
  #include <afsconfig.h>
  #include "afs/param.h"
   
! RCSID("$Header: /cvs/openafs/src/afs/afs_disconnected.c,v 1.2.2.5 2008/11/30 20:11:17 shadow Exp $");
   
  #include "afs/sysincludes.h"
  #include "afsincludes.h"
--- 7,13 ----
  #include <afsconfig.h>
  #include "afs/param.h"
   
! RCSID("$Header: /cvs/openafs/src/afs/afs_disconnected.c,v 1.2.2.9 2009/01/21 21:15:04 shadow Exp $");
   
  #include "afs/sysincludes.h"
  #include "afsincludes.h"
***************
*** 21,36 ****
  	((vc->m.DataVersion.low == fstat.DataVersion) && \
       	(vc->m.DataVersion.high == fstat.dataVersionHigh))
  
! /*! Global list of dirty vcaches. */
! /*! Last added element. */
! struct vcache *afs_DDirtyVCList = NULL;
! /*! Head of list. */
! struct vcache *afs_DDirtyVCListStart = NULL;
! /*! Previous element in the list. */
! struct vcache *afs_DDirtyVCListPrev = NULL;
  
! /*! Locks list of dirty vcaches. */
! afs_rwlock_t afs_DDirtyVCListLock;
  
  extern afs_int32 *afs_dvhashTbl;	/*Data cache hash table */
  extern afs_int32 *afs_dchashTbl;	/*Data cache hash table */
--- 21,35 ----
  	((vc->m.DataVersion.low == fstat.DataVersion) && \
       	(vc->m.DataVersion.high == fstat.dataVersionHigh))
  
! /*! Circular queue of dirty vcaches */
! struct afs_q afs_disconDirty;
  
! /*! Circular queue of vcaches with shadow directories */
! struct afs_q afs_disconShadow;
! 
! /*! Locks both of these lists. Must be write locked for anything other than
!  *  list traversal */
! afs_rwlock_t afs_disconDirtyLock;
  
  extern afs_int32 *afs_dvhashTbl;	/*Data cache hash table */
  extern afs_int32 *afs_dchashTbl;	/*Data cache hash table */
***************
*** 38,45 ****
  extern afs_int32 *afs_dcnextTbl;	/*Dcache hash table links */
  extern struct dcache **afs_indexTable;	/*Pointers to dcache entries */
  
! /*! Vnode number. On file creation, use the current
!  *  value and increment it.
   */
  afs_uint32 afs_DisconVnode = 2;
  
--- 37,43 ----
  extern afs_int32 *afs_dcnextTbl;	/*Dcache hash table links */
  extern struct dcache **afs_indexTable;	/*Pointers to dcache entries */
  
! /*! Vnode number. On file creation, use the current value and increment it.
   */
  afs_uint32 afs_DisconVnode = 2;
  
***************
*** 53,58 ****
--- 51,59 ----
  
  afs_int32 afs_ConflictPolicy = SERVER_WINS;
  
+ static void afs_DisconResetVCache(struct vcache *, struct AFS_UCRED *);
+ static void afs_DisconDiscardAllShadows(int, struct AFS_UCRED *);
+ 
  /*!
   * Find the first dcache of a file that has the specified fid.
   * Similar to afs_FindDCache, only that it takes a fid instead
***************
*** 62,71 ****
   *
   * \return The found dcache or NULL.
   */
! struct dcache *afs_FindDCacheByFid(register struct VenusFid *afid)
  {
!     register afs_int32 i, index;
!     register struct dcache *tdc = NULL;
  
      i = DVHash(afid);
      ObtainWriteLock(&afs_xdcache, 758);
--- 63,72 ----
   *
   * \return The found dcache or NULL.
   */
! struct dcache *afs_FindDCacheByFid(struct VenusFid *afid)
  {
!     afs_int32 i, index;
!     struct dcache *tdc = NULL;
  
      i = DVHash(afid);
      ObtainWriteLock(&afs_xdcache, 758);
***************
*** 150,155 ****
--- 151,158 ----
   *
   * \param avc The file's vhash entry.
   * \param afid Put the fid here.
+  *
+  * \return 0 on success, -1 on failure
   */
  int afs_GetParentDirFid(struct vcache *avc, struct VenusFid *afid)
  {
***************
*** 170,175 ****
--- 173,180 ----
  	    /* Lookup each entry for the fid. It should be the first. */
      	    afs_dir_EnumerateDir(tdc, &get_parent_dir_fid_hook, afid);
      	    afs_PutDCache(tdc);
+ 	} else {
+ 	    return -1;
  	}
      }
  
***************
*** 271,280 ****
  
      if (tdc) {
  	tnf.fid = &avc->fid;
!    	tnf.name_len = 0;
      	tnf.name = aname;
      	afs_dir_EnumerateDir(tdc, &get_vnode_name_hook, &tnf);
  	afs_PutDCache(tdc);
      } else {
          code = ENOENT;
      }
--- 276,287 ----
  
      if (tdc) {
  	tnf.fid = &avc->fid;
!    	tnf.name_len = -1;
      	tnf.name = aname;
      	afs_dir_EnumerateDir(tdc, &get_vnode_name_hook, &tnf);
  	afs_PutDCache(tdc);
+ 	if (tnf.name_len == -1)
+ 	    code = ENOENT;
      } else {
          code = ENOENT;
      }
***************
*** 319,330 ****
      tvc = afs_FindVCache(&tfid, 0, 1);
      ReleaseSharedLock(&afs_xvcache);
  
!     /* Count unfinished dirty children. VDisconShadowed can still be set,
!      * because we need it to remove the shadow dir.
!      */
      if (tvc) {
! 	if (tvc->ddirty_flags)
  	    v->count++;
  
  	afs_PutVCache(tvc);
      }
--- 326,337 ----
      tvc = afs_FindVCache(&tfid, 0, 1);
      ReleaseSharedLock(&afs_xvcache);
  
!     /* Count unfinished dirty children. */
      if (tvc) {
! 	ObtainReadLock(&tvc->lock);
! 	if (tvc->ddirty_flags || tvc->shVnode)
  	    v->count++;
+ 	ReleaseReadLock(&tvc->lock);
  
  	afs_PutVCache(tvc);
      }
***************
*** 346,352 ****
      struct DirtyChildrenCount dcc;
      struct VenusFid shadow_fid;
  
!     if (!(avc->ddirty_flags & VDisconShadowed))
      	/* Empty dir. */
      	return 0;
  
--- 353,359 ----
      struct DirtyChildrenCount dcc;
      struct VenusFid shadow_fid;
  
!     if (!avc->shVnode)
      	/* Empty dir. */
      	return 0;
  
***************
*** 474,483 ****
  int afs_ProcessOpRename(struct vcache *avc, struct vrequest *areq)
  {
      struct VenusFid old_pdir_fid, new_pdir_fid;
!     char *old_name, *new_name;
      struct AFSFetchStatus OutOldDirStatus, OutNewDirStatus;
      struct AFSVolSync tsync;
!     struct conn *tc;
      afs_uint32 code = 0;
      XSTATS_DECLS;
  
--- 481,490 ----
  int afs_ProcessOpRename(struct vcache *avc, struct vrequest *areq)
  {
      struct VenusFid old_pdir_fid, new_pdir_fid;
!     char *old_name = NULL, *new_name = NULL;
      struct AFSFetchStatus OutOldDirStatus, OutNewDirStatus;
      struct AFSVolSync tsync;
!     struct afs_conn *tc;
      afs_uint32 code = 0;
      XSTATS_DECLS;
  
***************
*** 496,503 ****
      code = afs_GetVnodeName(avc, &old_pdir_fid, old_name, 1);
      if (code) {
  	printf("afs_ProcessOpRename: Couldn't find old name.\n");
! 	code = ENOENT;
! 	goto end2;
      }
  
      /* Alloc data first. */
--- 503,509 ----
      code = afs_GetVnodeName(avc, &old_pdir_fid, old_name, 1);
      if (code) {
  	printf("afs_ProcessOpRename: Couldn't find old name.\n");
! 	goto done;
      }
  
      /* Alloc data first. */
***************
*** 505,511 ****
      if (!new_name) {
  	printf("afs_ProcessOpRename: Couldn't alloc space for new name.\n");
  	code = ENOMEM;
! 	goto end2;
      }
  
      if (avc->ddirty_flags & VDisconRenameSameDir) {
--- 511,517 ----
      if (!new_name) {
  	printf("afs_ProcessOpRename: Couldn't alloc space for new name.\n");
  	code = ENOMEM;
! 	goto done;
      }
  
      if (avc->ddirty_flags & VDisconRenameSameDir) {
***************
*** 520,526 ****
      	if (!new_pdir_fid.Fid.Unique) {
  	    printf("afs_ProcessOpRename: Couldn't find new parent dir FID.\n");
  	    code = ENOENT;
! 	    goto end1;
          }
      }
  
--- 526,532 ----
      	if (!new_pdir_fid.Fid.Unique) {
  	    printf("afs_ProcessOpRename: Couldn't find new parent dir FID.\n");
  	    code = ENOENT;
! 	    goto done;
          }
      }
  
***************
*** 528,535 ****
      code = afs_GetVnodeName(avc, &new_pdir_fid, new_name, 0);
      if (code) {
  	printf("afs_ProcessOpRename: Couldn't find new name.\n");
! 	code = ENOENT;
! 	goto end1;
      }
  
      /* Send to data to server. */
--- 534,540 ----
      code = afs_GetVnodeName(avc, &new_pdir_fid, new_name, 0);
      if (code) {
  	printf("afs_ProcessOpRename: Couldn't find new name.\n");
! 	goto done;
      }
  
      /* Send to data to server. */
***************
*** 561,570 ****
  
      if (code)
      	printf("afs_ProcessOpRename: server code=%u\n", code);
! end1:
!     afs_osi_Free(new_name, AFSNAMEMAX);
! end2:
!     afs_osi_Free(old_name, AFSNAMEMAX);
      return code;
  }
  
--- 566,576 ----
  
      if (code)
      	printf("afs_ProcessOpRename: server code=%u\n", code);
! done:
!     if (new_name)
! 	afs_osi_Free(new_name, AFSNAMEMAX);
!     if (old_name)
! 	afs_osi_Free(old_name, AFSNAMEMAX);
      return code;
  }
  
***************
*** 588,594 ****
      struct AFSVolSync tsync;
      struct vcache *tdp = NULL, *tvc = NULL;
      struct dcache *tdc = NULL;
!     struct conn *tc;
      afs_int32 now, hash, new_hash, index;
      int code = 0;
      XSTATS_DECLS;
--- 594,600 ----
      struct AFSVolSync tsync;
      struct vcache *tdp = NULL, *tvc = NULL;
      struct dcache *tdc = NULL;
!     struct afs_conn *tc;
      afs_int32 now, hash, new_hash, index;
      int code = 0;
      XSTATS_DECLS;
***************
*** 597,609 ****
      pdir_fid.Fid.Unique = 0;
      afs_GetParentDirFid(avc, &pdir_fid);
      if (!pdir_fid.Fid.Unique) {
! 	printf("afs_ProcessOpCreate: Couldn't find parent dir'sFID.\n");
  	return ENOENT;
      }
  
      tname = afs_osi_Alloc(AFSNAMEMAX);
      if (!tname) {
! 	printf("afs_ProcessOpCreate: Couldn't find file name\n");
  	return ENOMEM;
      }
  
--- 603,615 ----
      pdir_fid.Fid.Unique = 0;
      afs_GetParentDirFid(avc, &pdir_fid);
      if (!pdir_fid.Fid.Unique) {
! 	printf("afs_ProcessOpCreate: Couldn't find parent dir's FID.\n");
  	return ENOENT;
      }
  
      tname = afs_osi_Alloc(AFSNAMEMAX);
      if (!tname) {
! 	printf("afs_ProcessOpCreate: Couldn't alloc space for file name\n");
  	return ENOMEM;
      }
  
***************
*** 611,617 ****
      code = afs_GetVnodeName(avc, &pdir_fid, tname, 0);
      if (code) {
  	printf("afs_ProcessOpCreate: Couldn't find file name\n");
- 	code = ENOENT;
  	goto end;
      }
  
--- 617,622 ----
***************
*** 627,638 ****
  
      if (tdp->ddirty_flags & VDisconCreate) {
      	/* If the parent dir has been created locally, defer
! 	 * this vnode for later by moving it to the end.
! 	 */
! 	afs_DDirtyVCList->ddirty_next = avc;
! 	afs_DDirtyVCList = avc;
! 	printf("afs_ProcessOpRemove: deferring this vcache\n");
!     	code = ENOTEMPTY;
  	goto end;
      }
  
--- 632,640 ----
  
      if (tdp->ddirty_flags & VDisconCreate) {
      	/* If the parent dir has been created locally, defer
! 	 * this vnode for later */
! 	printf("afs_ProcessOpCreate: deferring this vcache\n");
!     	code = EAGAIN;
  	goto end;
      }
  
***************
*** 712,718 ****
      /* TODO: Handle errors. */
      if (code) {
  	printf("afs_ProcessOpCreate: error while creating vnode on server, code=%d .\n", code);
- 	code = EIO;
  	goto end;
      }
  
--- 714,719 ----
***************
*** 770,776 ****
  	afs_vhashT[hash] = avc->hnext;
      } else {
          /* More elements in hash chain. */
-  	//for (tvc = afs_vhashT[hash]; tdp; tdp = tdp->hnext) {
   	for (tvc = afs_vhashT[hash]; tvc; tvc = tvc->hnext) {
  	    if (tvc->hnext == avc) {
  		tvc->hnext = avc->hnext;
--- 771,776 ----
***************
*** 778,789 ****
  	    }
          }
      }                           /* if (!afs_vhashT[i]->hnext) */
!     QRemove(&afs_vhashTV[hash]);
  
      /* Insert hash in new position. */
      avc->hnext = afs_vhashT[new_hash];
      afs_vhashT[new_hash] = avc;
!     QAdd(&afs_vhashTV[new_hash], &avc->vhashq);
  
      ReleaseWriteLock(&afs_xvcache);
  
--- 778,789 ----
  	    }
          }
      }                           /* if (!afs_vhashT[i]->hnext) */
!     QRemove(&avc->vhashq);
  
      /* Insert hash in new position. */
      avc->hnext = afs_vhashT[new_hash];
      afs_vhashT[new_hash] = avc;
!     QAdd(&afs_vhashTV[VCHashV(&newFid)], &avc->vhashq);
  
      ReleaseWriteLock(&afs_xvcache);
  
***************
*** 811,817 ****
  
   		afs_indexUnique[tdc->index] = newFid.Fid.Unique;
  		memcpy(&tdc->f.fid, &newFid, sizeof(struct VenusFid));
-                 //afs_MaybeWakeupTruncateDaemon();
             }                   /* if fid match */
  	}                       /* if uniquifier match */
      	if (tdc)
--- 811,816 ----
***************
*** 840,846 ****
  /*!
   * Remove a vnode on the server, be it file or directory.
   * Not much to do here only get the parent dir's fid and call the
!  * removel rpc.
   *
   * \param avc The deleted vcache
   * \param areq
--- 839,845 ----
  /*!
   * Remove a vnode on the server, be it file or directory.
   * Not much to do here only get the parent dir's fid and call the
!  * removal rpc.
   *
   * \param avc The deleted vcache
   * \param areq
***************
*** 857,863 ****
      struct AFSFetchStatus OutDirStatus;
      struct VenusFid pdir_fid;
      struct AFSVolSync tsync;
!     struct conn *tc;
      struct vcache *tdp = NULL;
      int code = 0;
      XSTATS_DECLS;
--- 856,862 ----
      struct AFSFetchStatus OutDirStatus;
      struct VenusFid pdir_fid;
      struct AFSVolSync tsync;
!     struct afs_conn *tc;
      struct vcache *tdp = NULL;
      int code = 0;
      XSTATS_DECLS;
***************
*** 872,878 ****
  
      tname = afs_osi_Alloc(AFSNAMEMAX);
      if (!tname) {
! 	printf("afs_ProcessOpRemove: Couldn't find file name\n");
  	return ENOMEM;
      }
  
--- 871,877 ----
  
      tname = afs_osi_Alloc(AFSNAMEMAX);
      if (!tname) {
! 	printf("afs_ProcessOpRemove: Couldn't alloc space for file name\n");
  	return ENOMEM;
      }
  
***************
*** 880,886 ****
      code = afs_GetVnodeName(avc, &pdir_fid, tname, 1);
      if (code) {
  	printf("afs_ProcessOpRemove: Couldn't find file name\n");
- 	code = ENOENT;
  	goto end;
      }
  
--- 879,884 ----
***************
*** 888,896 ****
  	/* Deleted children of this dir remain unsynchronized.
  	 * Defer this vcache.
  	 */
! 	afs_DDirtyVCList->ddirty_next = avc;
! 	afs_DDirtyVCList = avc;
!     	code = ENOTEMPTY;
  	goto end;
      }
  
--- 886,892 ----
  	/* Deleted children of this dir remain unsynchronized.
  	 * Defer this vcache.
  	 */
!     	code = EAGAIN;
  	goto end;
      }
  
***************
*** 975,981 ****
   */
  int afs_SendChanges(struct vcache *avc, struct vrequest *areq)
  {
!     struct conn *tc;
      struct AFSStoreStatus sstat;
      struct AFSFetchStatus fstat;
      struct AFSVolSync tsync;
--- 971,977 ----
   */
  int afs_SendChanges(struct vcache *avc, struct vrequest *areq)
  {
!     struct afs_conn *tc;
      struct AFSStoreStatus sstat;
      struct AFSFetchStatus fstat;
      struct AFSVolSync tsync;
***************
*** 1064,1126 ****
   * \param acred User credentials.
   *
   * \return If all files synchronized succesfully, return 0, otherwise
!  * return 1.
   *
   * \note For now, it's the request from the PDiscon pioctl.
   *
   */
  int afs_ResyncDisconFiles(struct vrequest *areq, struct AFS_UCRED *acred)
  {
!     struct conn *tc;
      struct vcache *tvc, *tmp;
      struct AFSFetchStatus fstat;
      struct AFSCallBack callback;
      struct AFSVolSync tsync;
!     struct vcache *shList, *shListStart;
!     int code;
!     int sync_failed = 0;
!     int ret_code = 0;
!     int defered = 0;
      afs_int32 start = 0;
      XSTATS_DECLS;
      //AFS_STATCNT(afs_ResyncDisconFiles);
  
!     shList = shListStart = NULL;
  
!     ObtainReadLock(&afs_DDirtyVCListLock);
  
!     tvc = afs_DDirtyVCListStart;
!     while (tvc) {
  
  	/* Get local write lock. */
! 	ObtainWriteLock(&tvc->lock, 704);
!   	sync_failed = 0;
  
! 	if ((tvc->ddirty_flags & VDisconRemove) &&
! 	    (tvc->ddirty_flags & VDisconCreate)) {
! 	   /* Data created and deleted locally. The server doesn't
! 	    * need to know about this, so we'll just skip this file
! 	    * from the dirty list.
! 	    */
! 	    goto skip_file;
! 
! 	} else if (tvc->ddirty_flags & VDisconRemove) {
  	    /* Delete the file on the server and just move on
  	     * to the next file. After all, it has been deleted
  	     * we can't replay any other operation it.
  	     */
  	    code = afs_ProcessOpRemove(tvc, areq);
! 	    if (code == ENOTEMPTY)
! 	    	defered = 1;
! 	    goto skip_file;
  
  	} else if (tvc->ddirty_flags & VDisconCreate) {
  	    /* For newly created files, we don't need a server lock. */
  	    code = afs_ProcessOpCreate(tvc, areq, acred);
- 	    if (code == ENOTEMPTY)
- 	    	defered = 1;
  	    if (code)
! 	    	goto skip_file;
  	}
  
    	/* Get server write lock. */
--- 1060,1110 ----
   * \param acred User credentials.
   *
   * \return If all files synchronized succesfully, return 0, otherwise
!  * return error code
   *
   * \note For now, it's the request from the PDiscon pioctl.
   *
   */
  int afs_ResyncDisconFiles(struct vrequest *areq, struct AFS_UCRED *acred)
  {
!     struct afs_conn *tc;
      struct vcache *tvc, *tmp;
      struct AFSFetchStatus fstat;
      struct AFSCallBack callback;
      struct AFSVolSync tsync;
!     int code = 0;
!     int ucode;
      afs_int32 start = 0;
      XSTATS_DECLS;
      //AFS_STATCNT(afs_ResyncDisconFiles);
  
!     ObtainWriteLock(&afs_disconDirtyLock, 707);
  
!     while (!QEmpty(&afs_disconDirty)) {
! 	tvc = QEntry(QPrev(&afs_disconDirty), struct vcache, dirtyq);
  
! 	/* Can't lock tvc whilst holding the discon dirty lock */
! 	ReleaseWriteLock(&afs_disconDirtyLock);
  
  	/* Get local write lock. */
! 	ObtainWriteLock(&tvc->lock, 705);
  
! 	if (tvc->ddirty_flags & VDisconRemove) {
  	    /* Delete the file on the server and just move on
  	     * to the next file. After all, it has been deleted
  	     * we can't replay any other operation it.
  	     */
  	    code = afs_ProcessOpRemove(tvc, areq);
! 	    goto next_file;
  
  	} else if (tvc->ddirty_flags & VDisconCreate) {
  	    /* For newly created files, we don't need a server lock. */
  	    code = afs_ProcessOpCreate(tvc, areq, acred);
  	    if (code)
! 	    	goto next_file;
! 
! 	    tvc->ddirty_flags &= ~VDisconCreate;
! 	    tvc->ddirty_flags |= VDisconCreated;
  	}
  
    	/* Get server write lock. */
***************
*** 1146,1162 ****
  			SHARED_LOCK,
  			NULL));
  
! 	if (code) {
! 	    sync_failed = 1;
! 	    goto skip_file;
! 	}
  
! 	if ((tvc->ddirty_flags & VDisconRename) &&
! 		!(tvc->ddirty_flags & VDisconCreate)) {
! 	    /* Rename file only if it hasn't been created locally. */
  	    code = afs_ProcessOpRename(tvc, areq);
  	    if (code)
! 	    	goto skip_file;
  	}
  
  	/* Issue a FetchStatus to get info about DV and callbacks. */
--- 1130,1143 ----
  			SHARED_LOCK,
  			NULL));
  
! 	if (code)
! 	    goto next_file;
  
! 	if (tvc->ddirty_flags & VDisconRename) {
! 	    /* If we're renaming the file, do so now */
  	    code = afs_ProcessOpRename(tvc, areq);
  	    if (code)
! 	    	goto unlock_srv_file;
  	}
  
  	/* Issue a FetchStatus to get info about DV and callbacks. */
***************
*** 1186,1198 ****
  			NULL));
  
  	if (code) {
- 	    sync_failed = 1;
  	    goto unlock_srv_file;
  	}
  
  	if ((dv_match(tvc, fstat) && (tvc->m.Date == fstat.ServerModTime)) ||
  	    	(afs_ConflictPolicy == CLIENT_WINS) ||
! 		(tvc->ddirty_flags & VDisconCreate)) {
  	    /*
  	     * Send changes to the server if there's data version match, or
  	     * client wins policy has been selected or file has been created
--- 1167,1178 ----
  			NULL));
  
  	if (code) {
  	    goto unlock_srv_file;
  	}
  
  	if ((dv_match(tvc, fstat) && (tvc->m.Date == fstat.ServerModTime)) ||
  	    	(afs_ConflictPolicy == CLIENT_WINS) ||
! 		(tvc->ddirty_flags & VDisconCreated)) {
  	    /*
  	     * Send changes to the server if there's data version match, or
  	     * client wins policy has been selected or file has been created
***************
*** 1207,1245 ****
  
  	} else if (afs_ConflictPolicy == SERVER_WINS) {
  	    /* DV mismatch, apply collision resolution policy. */
- 	    /* Dequeue whatever callback is on top (XXX: propably none). */
-       	    ObtainWriteLock(&afs_xcbhash, 706);
- 	    afs_DequeueCallback(tvc);
- 	    tvc->callback = NULL;
- 	    tvc->states &= ~(CStatd | CDirty | CUnique);
- 	    ReleaseWriteLock(&afs_xcbhash);
- 
- 	    /* Save metadata. File length gets updated as well because we
- 	     * just removed CDirty from the avc.
- 	     */
- 	    //afs_ProcessFS(tvc, &fstat, areq);
- 
  	    /* Discard this files chunks and remove from current dir. */
! 	    afs_TryToSmush(tvc, acred, 1);
! 	    osi_dnlc_purgedp(tvc);
! 	    if (tvc->linkData && !(tvc->states & CCore)) {
! 		/* Take care of symlinks. */
! 		afs_osi_Free(tvc->linkData, strlen(tvc->linkData) + 1);
! 		tvc->linkData = NULL;
! 	    }
! 
! 	    /* Otherwise file content's won't be synchronized. */
  	    tvc->truncPos = AFS_NOTRUNC;
- 
  	} else {
  	    printf("afs_ResyncDisconFiles: no resolution policy selected.\n");
  	}		/* if DV match or client wins policy */
  
- 	if (code) {
- 	    sync_failed = 1;
- 	    printf("Sync FAILED.\n");
- 	}
- 
  unlock_srv_file:
  	/* Release server write lock. */
  	do {
--- 1187,1199 ----
  
  	} else if (afs_ConflictPolicy == SERVER_WINS) {
  	    /* DV mismatch, apply collision resolution policy. */
  	    /* Discard this files chunks and remove from current dir. */
! 	    afs_ResetVCache(tvc, acred);
  	    tvc->truncPos = AFS_NOTRUNC;
  	} else {
  	    printf("afs_ResyncDisconFiles: no resolution policy selected.\n");
  	}		/* if DV match or client wins policy */
  
  unlock_srv_file:
  	/* Release server write lock. */
  	do {
***************
*** 1247,1335 ****
  	    if (tc) {
  	    	XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_RELEASELOCK);
  	    	RX_AFS_GUNLOCK();
! 		code = RXAFS_ReleaseLock(tc->id,
  				(struct AFSFid *) &tvc->fid.Fid,
  				&tsync);
  		RX_AFS_GLOCK();
  		XSTATS_END_TIME;
  	    } else
! 		code = -1;
  	} while (afs_Analyze(tc,
! 			code,
  			&tvc->fid,
  			areq,
  			AFS_STATS_FS_RPCIDX_RELEASELOCK,
  			SHARED_LOCK,
  			NULL));
  
! skip_file:
! 	/* Pop this dirty vc out. */
! 	tmp = tvc;
! 	tvc = tvc->ddirty_next;
! 
! 	if (!defered) {
! 	    /* Vnode not deferred. Clean it up. */
! 	    if (!sync_failed) {
! 	    	if (tmp->ddirty_flags == VDisconShadowed) {
! 		    /* Dirs that have only the shadow flag set might still
! 		     * be used so keep them in a different list, that gets
! 		     * deleted after resync is done.
! 		     */
! 		    if (!shListStart)
! 		    	shListStart = shList = tmp;
! 		    else {
! 		    	shList->ddirty_next = tmp;
! 			shList = tmp;
! 		    }
! 		} else if (tmp->ddirty_flags & VDisconShadowed)
! 	    	    /* We can discard the shadow dir now. */
! 	    	    afs_DeleteShadowDir(tmp);
! 
! 		/* Drop the refcount on this vnode because it's not in the
! 		 * list anymore.
! 		 */
! 		 afs_PutVCache(tmp);
! 
! 	    	/* Only if sync was successfull,
! 		 * clear flags and dirty references.
! 		 */
! 	    	tmp->ddirty_next = NULL;
! 	    	tmp->ddirty_flags = 0;
! 	    } else
! 	    	ret_code = 1;
  	} else {
! 	    tmp->ddirty_next = NULL;
! 	    defered = 0;
! 	}			/* if (!defered) */
  
  	/* Release local write lock. */
! 	ReleaseWriteLock(&tmp->lock);
      }			/* while (tvc) */
  
!     /* Delete the rest of shadow dirs. */
!     tvc = shListStart;
!     while (tvc) {
!     	ObtainWriteLock(&tvc->lock, 764);
  
  	afs_DeleteShadowDir(tvc);
  	tvc->shVnode = 0;
  	tvc->shUnique = 0;
  
! 	tmp = tvc;
! 	tvc = tvc->ddirty_next;
! 	tmp->ddirty_next = NULL;
  
! 	ReleaseWriteLock(&tmp->lock);
      }				/* while (tvc) */
  
!     if (ret_code == 0) {
!     	/* NULLIFY dirty list only if resync complete. */
! 	afs_DDirtyVCListStart = NULL;
! 	afs_DDirtyVCList = NULL;
      }
-     ReleaseReadLock(&afs_DDirtyVCListLock);
  
!     return ret_code;
  }
  
  /*!
--- 1201,1323 ----
  	    if (tc) {
  	    	XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_RELEASELOCK);
  	    	RX_AFS_GUNLOCK();
! 		ucode = RXAFS_ReleaseLock(tc->id,
  				(struct AFSFid *) &tvc->fid.Fid,
  				&tsync);
  		RX_AFS_GLOCK();
  		XSTATS_END_TIME;
  	    } else
! 		ucode = -1;
  	} while (afs_Analyze(tc,
! 			ucode,
  			&tvc->fid,
  			areq,
  			AFS_STATS_FS_RPCIDX_RELEASELOCK,
  			SHARED_LOCK,
  			NULL));
  
! next_file:
! 	ObtainWriteLock(&afs_disconDirtyLock, 710);
! 	if (code == 0) {
! 	    /* Replayed successfully - pull the vcache from the 
! 	     * disconnected list */
! 	    tvc->ddirty_flags = 0;
! 	    QRemove(&tvc->dirtyq);
! 	    afs_PutVCache(tvc);
  	} else {
! 	    if (code == EAGAIN)	{
! 		/* Operation was deferred. Pull it from the current place in 
! 		 * the list, and stick it at the end again */
! 		QRemove(&tvc->dirtyq);
! 	   	QAdd(&afs_disconDirty, &tvc->dirtyq);
! 	    } else {
! 		/* Failed - keep state as is, and let the user know we died */
! 		ReleaseWriteLock(&tvc->lock);
! 		break;
! 	    }
! 	}
  
  	/* Release local write lock. */
! 	ReleaseWriteLock(&tvc->lock);
      }			/* while (tvc) */
  
!     if (code) {
!         ReleaseWriteLock(&afs_disconDirtyLock);
! 	return code;
!     }
! 
!     /* Dispose of all of the shadow directories */
!     afs_DisconDiscardAllShadows(0, acred);
! 
!     ReleaseWriteLock(&afs_disconDirtyLock);
!     return code;
! }
! 
! /*!
!  * Discard all of our shadow directory copies. If squash is true, then
!  * we also invalidate the vcache holding the shadow directory, to ensure
!  * that any disconnected changes are deleted
!  * 
!  * \param squash
!  * \param acred
!  *
!  * \note afs_disconDirtyLock must be held on entry. It will be released
!  * and reobtained
!  */
! 
! static void
! afs_DisconDiscardAllShadows(int squash, struct AFS_UCRED *acred) {
!    struct vcache *tvc;
! 
!    while (!QEmpty(&afs_disconShadow)) {
! 	tvc = QEntry(QNext(&afs_disconShadow), struct vcache, shadowq);
! 
! 	/* Must release the dirty lock to be able to get a vcache lock */
! 	ReleaseWriteLock(&afs_disconDirtyLock);
! 	ObtainWriteLock(&tvc->lock, 706);
  
  	afs_DeleteShadowDir(tvc);
  	tvc->shVnode = 0;
  	tvc->shUnique = 0;
  
! 	if (squash)
! 	   afs_ResetVCache(tvc, acred);
  
! 	ObtainWriteLock(&afs_disconDirtyLock, 709);
! 	QRemove(&tvc->shadowq);
! 
! 	ReleaseWriteLock(&tvc->lock);
      }				/* while (tvc) */
+ }
  
! /*!
!  * This function throws away the whole disconnected state, allowing
!  * the cache manager to reconnect to a server if we get into a state
!  * where reconiliation is impossible.
!  *
!  * \param acred
!  *
!  */
! void 
! afs_DisconDiscardAll(struct AFS_UCRED *acred) {
!     struct vcache *tvc;
! 
!     ObtainWriteLock(&afs_disconDirtyLock, 717);
!     while (!QEmpty(&afs_disconDirty)) {
! 	tvc = QEntry(QPrev(&afs_disconDirty), struct vcache, dirtyq);
! 	ReleaseWriteLock(&afs_disconDirtyLock);
! 
! 	ObtainWriteLock(&tvc->lock, 718);
! 	afs_ResetVCache(tvc, acred);
! 	tvc->truncPos = AFS_NOTRUNC;
! 	ReleaseWriteLock(&tvc->lock);
! 	afs_PutVCache(tvc);
! 	ObtainWriteLock(&afs_disconDirtyLock, 719);
      }
  
!     afs_DisconDiscardAllShadows(1, acred);
! 
!     ReleaseWriteLock(&afs_disconDirtyLock);
  }
  
  /*!
***************
*** 1340,1360 ****
  void afs_DbgDisconFiles()
  {
      struct vcache *tvc;
      int i = 0;
  
-     tvc = afs_DDirtyVCListStart;
      printf("List of dirty files: \n");
!     while (tvc) {
  	printf("Cell=%u Volume=%u VNode=%u Unique=%u\n",
  		tvc->fid.Cell,
  		tvc->fid.Fid.Volume,
  		tvc->fid.Fid.Vnode,
  		tvc->fid.Fid.Unique);
! 	tvc = tvc->ddirty_next;
  	i++;
  	if (i >= 30)
  	    osi_Panic("afs_DbgDisconFiles: loop in dirty list\n");
      }
  }
  
  /*!
--- 1328,1353 ----
  void afs_DbgDisconFiles()
  {
      struct vcache *tvc;
+     struct afs_q *q;
      int i = 0;
  
      printf("List of dirty files: \n");
! 
!     ObtainReadLock(&afs_disconDirtyLock);
!     for (q = QPrev(&afs_disconDirty); q != &afs_disconDirty; q = QPrev(q)) {
!         tvc = QEntry(q, struct vcache, dirtyq);
! 
  	printf("Cell=%u Volume=%u VNode=%u Unique=%u\n",
  		tvc->fid.Cell,
  		tvc->fid.Fid.Volume,
  		tvc->fid.Fid.Vnode,
  		tvc->fid.Fid.Unique);
! 
  	i++;
  	if (i >= 30)
  	    osi_Panic("afs_DbgDisconFiles: loop in dirty list\n");
      }
+     ReleaseReadLock(&afs_disconDirtyLock);
  }
  
  /*!
Index: openafs/src/afs/afs_init.c
diff -c openafs/src/afs/afs_init.c:1.37.4.9 openafs/src/afs/afs_init.c:1.37.4.11
*** openafs/src/afs/afs_init.c:1.37.4.9	Sat Nov  8 11:34:42 2008
--- openafs/src/afs/afs_init.c	Wed Jan 21 16:15:04 2009
***************
*** 17,23 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_init.c,v 1.37.4.9 2008/11/08 16:34:42 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
--- 17,23 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_init.c,v 1.37.4.11 2009/01/21 21:15:04 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 47,53 ****
  #endif
  #if defined(AFS_DISCON_ENV)
  afs_rwlock_t afs_discon_lock;
! extern afs_rwlock_t afs_DDirtyVCListLock;
  #endif
  
  /*
--- 47,53 ----
  #endif
  #if defined(AFS_DISCON_ENV)
  afs_rwlock_t afs_discon_lock;
! extern afs_rwlock_t afs_disconDirtyLock;
  #endif
  
  /*
***************
*** 116,122 ****
      RWLOCK_INIT(&afs_xaxs, "afs_xaxs");
  #ifdef AFS_DISCON_ENV
      RWLOCK_INIT(&afs_discon_lock, "afs_discon_lock");
!     RWLOCK_INIT(&afs_DDirtyVCListLock, "afs_DDirtyVCListLock");
  #endif
      osi_dnlc_init();
  
--- 116,124 ----
      RWLOCK_INIT(&afs_xaxs, "afs_xaxs");
  #ifdef AFS_DISCON_ENV
      RWLOCK_INIT(&afs_discon_lock, "afs_discon_lock");
!     RWLOCK_INIT(&afs_disconDirtyLock, "afs_disconDirtyLock");
!     QInit(&afs_disconDirty);
!     QInit(&afs_disconShadow);
  #endif
      osi_dnlc_init();
  
***************
*** 793,799 ****
  	 */
  	{
  	    struct server *ts, *nts;
! 	    struct conn *tc, *ntc;
  	    register struct afs_cbr *tcbrp, *tbrp;
  
  	    for (i = 0; i < NSERVERS; i++) {
--- 795,801 ----
  	 */
  	{
  	    struct server *ts, *nts;
! 	    struct afs_conn *tc, *ntc;
  	    register struct afs_cbr *tcbrp, *tbrp;
  
  	    for (i = 0; i < NSERVERS; i++) {
***************
*** 810,816 ****
  				AFS_GUNLOCK();
  				rx_DestroyConnection(tc->id);
  				AFS_GLOCK();
! 				afs_osi_Free(tc, sizeof(struct conn));
  				tc = ntc;
  			    }
  			}
--- 812,818 ----
  				AFS_GUNLOCK();
  				rx_DestroyConnection(tc->id);
  				AFS_GLOCK();
! 				afs_osi_Free(tc, sizeof(struct afs_conn));
  				tc = ntc;
  			    }
  			}
Index: openafs/src/afs/afs_nfsdisp.c
diff -c openafs/src/afs/afs_nfsdisp.c:1.21.4.1 openafs/src/afs/afs_nfsdisp.c:1.21.4.2
*** openafs/src/afs/afs_nfsdisp.c:1.21.4.1	Wed Aug 13 19:49:26 2008
--- openafs/src/afs/afs_nfsdisp.c	Thu Jan 15 08:27:28 2009
***************
*** 11,17 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_nfsdisp.c,v 1.21.4.1 2008/08/13 23:49:26 shadow Exp $");
  
  /* Ugly Ugly Ugly  but precludes conflicting XDR macros; We want kernel xdr */
  #define __XDR_INCLUDE__
--- 11,17 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_nfsdisp.c,v 1.21.4.2 2009/01/15 13:27:28 shadow Exp $");
  
  /* Ugly Ugly Ugly  but precludes conflicting XDR macros; We want kernel xdr */
  #define __XDR_INCLUDE__
***************
*** 378,385 ****
  afs_nfs2_getattr(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call = afs_nfs2_dispatcher(0, RFS_GETATTR, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
--- 378,385 ----
  afs_nfs2_getattr(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call = afs_nfs2_dispatcher(0, RFS_GETATTR, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
***************
*** 393,400 ****
  afs_nfs2_setattr(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call = afs_nfs2_dispatcher(0, RFS_SETATTR, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
--- 393,400 ----
  afs_nfs2_setattr(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call = afs_nfs2_dispatcher(0, RFS_SETATTR, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
***************
*** 408,415 ****
  afs_nfs2_lookup(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call = afs_nfs2_dispatcher(0, RFS_LOOKUP, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
--- 408,415 ----
  afs_nfs2_lookup(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call = afs_nfs2_dispatcher(0, RFS_LOOKUP, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
***************
*** 426,433 ****
  afs_nfs2_readlink(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call = afs_nfs2_dispatcher(0, RFS_READLINK, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
--- 426,433 ----
  afs_nfs2_readlink(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call = afs_nfs2_dispatcher(0, RFS_READLINK, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
***************
*** 441,448 ****
  afs_nfs2_read(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call = afs_nfs2_dispatcher(0, RFS_READ, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
--- 441,448 ----
  afs_nfs2_read(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call = afs_nfs2_dispatcher(0, RFS_READ, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
***************
*** 456,463 ****
  afs_nfs2_write(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call = afs_nfs2_dispatcher(0, RFS_WRITE, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
--- 456,463 ----
  afs_nfs2_write(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call = afs_nfs2_dispatcher(0, RFS_WRITE, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
***************
*** 471,478 ****
  afs_nfs2_create(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call = afs_nfs2_dispatcher(0, RFS_CREATE, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
--- 471,478 ----
  afs_nfs2_create(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call = afs_nfs2_dispatcher(0, RFS_CREATE, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
***************
*** 489,496 ****
  afs_nfs2_remove(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call = afs_nfs2_dispatcher(0, RFS_REMOVE, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
--- 489,496 ----
  afs_nfs2_remove(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call = afs_nfs2_dispatcher(0, RFS_REMOVE, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
***************
*** 504,511 ****
  afs_nfs2_rename(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call = afs_nfs2_dispatcher(0, RFS_RENAME, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
--- 504,511 ----
  afs_nfs2_rename(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call = afs_nfs2_dispatcher(0, RFS_RENAME, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
***************
*** 519,526 ****
  afs_nfs2_link(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call = afs_nfs2_dispatcher(0, RFS_LINK, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
--- 519,526 ----
  afs_nfs2_link(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call = afs_nfs2_dispatcher(0, RFS_LINK, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
***************
*** 534,541 ****
  afs_nfs2_symlink(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call = afs_nfs2_dispatcher(0, RFS_SYMLINK, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
--- 534,541 ----
  afs_nfs2_symlink(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call = afs_nfs2_dispatcher(0, RFS_SYMLINK, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
***************
*** 549,556 ****
  afs_nfs2_mkdir(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call = afs_nfs2_dispatcher(0, RFS_MKDIR, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
--- 549,556 ----
  afs_nfs2_mkdir(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call = afs_nfs2_dispatcher(0, RFS_MKDIR, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
***************
*** 567,574 ****
  afs_nfs2_rmdir(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call = afs_nfs2_dispatcher(0, RFS_RMDIR, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
--- 567,574 ----
  afs_nfs2_rmdir(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call = afs_nfs2_dispatcher(0, RFS_RMDIR, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
***************
*** 582,589 ****
  afs_nfs2_readdir(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call = afs_nfs2_dispatcher(0, RFS_READDIR, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
--- 582,589 ----
  afs_nfs2_readdir(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call = afs_nfs2_dispatcher(0, RFS_READDIR, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
***************
*** 597,604 ****
  afs_nfs2_statfs(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call = afs_nfs2_dispatcher(0, RFS_STATFS, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
--- 597,604 ----
  afs_nfs2_statfs(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call = afs_nfs2_dispatcher(0, RFS_STATFS, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
***************
*** 633,640 ****
  afs_acl2_getacl(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs2_dispatcher(1, ACLPROC2_GETACL, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 633,640 ----
  afs_acl2_getacl(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs2_dispatcher(1, ACLPROC2_GETACL, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 650,657 ****
  afs_acl2_setacl(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs2_dispatcher(1, ACLPROC2_SETACL, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 650,657 ----
  afs_acl2_setacl(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs2_dispatcher(1, ACLPROC2_SETACL, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 667,674 ****
  afs_acl2_getattr(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs2_dispatcher(1, ACLPROC2_GETATTR, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 667,674 ----
  afs_acl2_getattr(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs2_dispatcher(1, ACLPROC2_GETATTR, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 684,691 ****
  afs_acl2_access(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs2_dispatcher(1, ACLPROC2_ACCESS, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 684,691 ----
  afs_acl2_access(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs2_dispatcher(1, ACLPROC2_ACCESS, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 702,709 ****
  afs_acl2_getxattrdir(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs2_dispatcher(1, ACLPROC2_GETXATTRDIR, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 702,709 ----
  afs_acl2_getxattrdir(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs2_dispatcher(1, ACLPROC2_GETXATTRDIR, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1140,1147 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_GETATTR, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1140,1147 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_GETATTR, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1158,1165 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_SETATTR, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1158,1165 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_SETATTR, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1176,1183 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_LOOKUP, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1176,1183 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_LOOKUP, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1199,1206 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_ACCESS, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1199,1206 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_ACCESS, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1217,1224 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_READLINK, (char *)args, &exp, rp,
  			    crp);
--- 1217,1224 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_READLINK, (char *)args, &exp, rp,
  			    crp);
***************
*** 1236,1243 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call = afs_nfs3_dispatcher(0, NFSPROC3_READ, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
--- 1236,1243 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call = afs_nfs3_dispatcher(0, NFSPROC3_READ, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
***************
*** 1253,1260 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_WRITE, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1253,1260 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_WRITE, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1271,1278 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_CREATE, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1271,1278 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_CREATE, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1294,1301 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_MKDIR, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1294,1301 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_MKDIR, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1317,1324 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_SYMLINK, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1317,1324 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_SYMLINK, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1340,1347 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_MKNOD, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1340,1347 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_MKNOD, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1363,1370 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_REMOVE, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1363,1370 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_REMOVE, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1381,1388 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_RMDIR, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1381,1388 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_RMDIR, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1399,1406 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_RENAME, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1399,1406 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_RENAME, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1417,1424 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call = afs_nfs3_dispatcher(0, NFSPROC3_LINK, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
--- 1417,1424 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call = afs_nfs3_dispatcher(0, NFSPROC3_LINK, (char *)args, &exp, rp, crp);
      if (call > 1)
  	afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
***************
*** 1434,1441 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_READDIR, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1434,1441 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_READDIR, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1452,1459 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_READDIRPLUS, (char *)args, &exp, rp,
  			    crp);
--- 1452,1459 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_READDIRPLUS, (char *)args, &exp, rp,
  			    crp);
***************
*** 1473,1480 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_FSSTAT, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1473,1480 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_FSSTAT, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1491,1498 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_FSINFO, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1491,1498 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_FSINFO, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1509,1516 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_PATHCONF, (char *)args, &exp, rp,
  			    crp);
--- 1509,1516 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_PATHCONF, (char *)args, &exp, rp,
  			    crp);
***************
*** 1528,1535 ****
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_COMMIT, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1528,1535 ----
  {
      u_int call;
      afs_nfs3_resp dummy;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(0, NFSPROC3_COMMIT, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1570,1577 ****
  afs_acl3_getacl(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(1, ACLPROC3_GETACL, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1570,1577 ----
  afs_acl3_getacl(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(1, ACLPROC3_GETACL, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1587,1594 ****
  afs_acl3_setacl(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(1, ACLPROC3_SETACL, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1587,1594 ----
  afs_acl3_setacl(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(1, ACLPROC3_SETACL, (char *)args, &exp, rp, crp);
      if (call > 1)
***************
*** 1605,1612 ****
  afs_acl3_getxattrdir(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct cred *svcred = curthread->t_cred;
!     curthread->t_cred = (struct cred *)crp;
      call =
  	afs_nfs3_dispatcher(1, ACLPROC3_GETXATTRDIR, (char *)args, &exp, rp, crp);
      if (call > 1)
--- 1605,1612 ----
  afs_acl3_getxattrdir(char *args, char *xp, char *exp, char *rp, char *crp)
  {
      u_int call;
!     struct AFS_UCRED *svcred = curthread->t_cred;
!     curthread->t_cred = (struct AFS_UCRED *)crp;
      call =
  	afs_nfs3_dispatcher(1, ACLPROC3_GETXATTRDIR, (char *)args, &exp, rp, crp);
      if (call > 1)
Index: openafs/src/afs/afs_osi.h
diff -c openafs/src/afs/afs_osi.h:1.42.4.6 openafs/src/afs/afs_osi.h:1.42.4.7
*** openafs/src/afs/afs_osi.h:1.42.4.6	Tue Jul  1 16:56:35 2008
--- openafs/src/afs/afs_osi.h	Thu Jan 22 16:29:06 2009
***************
*** 117,123 ****
--- 117,125 ----
  /*
   * Alloc declarations.
   */
+ #if !defined(AFS_OBSD44_ENV)
  #define afs_osi_Alloc_NoSleep afs_osi_Alloc
+ #endif
  
  /*
   * Vnode related macros
Index: openafs/src/afs/afs_osi_alloc.c
diff -c openafs/src/afs/afs_osi_alloc.c:1.11.6.7 openafs/src/afs/afs_osi_alloc.c:1.11.6.8
*** openafs/src/afs/afs_osi_alloc.c:1.11.6.7	Tue Aug 26 10:01:31 2008
--- openafs/src/afs/afs_osi_alloc.c	Thu Jan 22 16:29:06 2009
***************
*** 11,17 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_osi_alloc.c,v 1.11.6.7 2008/08/26 14:01:31 shadow Exp $");
  
  
  
--- 11,17 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_osi_alloc.c,v 1.11.6.8 2009/01/22 21:29:06 shadow Exp $");
  
  
  
***************
*** 44,50 ****
      struct osimem *next;
  };
  
! 
  void *
  afs_osi_Alloc(size_t x)
  {
--- 44,50 ----
      struct osimem *next;
  };
  
! #if !defined(AFS_OBSD44_ENV)
  void *
  afs_osi_Alloc(size_t x)
  {
***************
*** 124,130 ****
      afs_osi_Free(x, strlen(x) + 1);
  }
  
! 
  
  /* free space allocated by AllocLargeSpace.  Also called by mclput when freeing
   * a packet allocated by osi_NetReceive. */
--- 124,130 ----
      afs_osi_Free(x, strlen(x) + 1);
  }
  
! #endif
  
  /* free space allocated by AllocLargeSpace.  Also called by mclput when freeing
   * a packet allocated by osi_NetReceive. */
Index: openafs/src/afs/afs_osi_gcpags.c
diff -c openafs/src/afs/afs_osi_gcpags.c:1.1.2.8 openafs/src/afs/afs_osi_gcpags.c:1.1.2.9
*** openafs/src/afs/afs_osi_gcpags.c:1.1.2.8	Sun Oct 12 14:44:36 2008
--- openafs/src/afs/afs_osi_gcpags.c	Thu Jan 15 08:27:29 2009
***************
*** 11,17 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_osi_gcpags.c,v 1.1.2.8 2008/10/12 18:44:36 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_osi_gcpags.c,v 1.1.2.9 2009/01/15 13:27:29 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 513,522 ****
  	|| (pr->state == TASK_UNINTERRUPTIBLE)
  	|| (pr->state == TASK_STOPPED)) {
  	cr.cr_ref = 1;
! 	cr.cr_uid = pr->uid;
  #if defined(AFS_LINUX26_ENV)
  	get_group_info(pr->group_info);
  	cr.cr_group_info = pr->group_info;
  #else
  	cr.cr_ngroups = pr->ngroups;
  	memcpy(cr.cr_groups, pr->groups, NGROUPS * sizeof(gid_t));
--- 513,527 ----
  	|| (pr->state == TASK_UNINTERRUPTIBLE)
  	|| (pr->state == TASK_STOPPED)) {
  	cr.cr_ref = 1;
! 	cr.cr_uid = task_uid(pr);
  #if defined(AFS_LINUX26_ENV)
+ #if defined(STRUCT_TASK_HAS_CRED)
+ 	get_group_info(pr->cred->group_info);
+ 	cr.cr_group_info = pr->cred->group_info;
+ #else
  	get_group_info(pr->group_info);
  	cr.cr_group_info = pr->group_info;
+ #endif
  #else
  	cr.cr_ngroups = pr->ngroups;
  	memcpy(cr.cr_groups, pr->groups, NGROUPS * sizeof(gid_t));
Index: openafs/src/afs/afs_pioctl.c
diff -c openafs/src/afs/afs_pioctl.c:1.110.2.24 openafs/src/afs/afs_pioctl.c:1.110.2.30
*** openafs/src/afs/afs_pioctl.c:1.110.2.24	Mon Dec 22 12:31:09 2008
--- openafs/src/afs/afs_pioctl.c	Wed Jan 21 16:27:52 2009
***************
*** 11,17 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_pioctl.c,v 1.110.2.24 2008/12/22 17:31:09 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #ifdef AFS_OBSD_ENV
--- 11,17 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_pioctl.c,v 1.110.2.30 2009/01/21 21:27:52 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #ifdef AFS_OBSD_ENV
***************
*** 33,39 ****
  
  #ifdef AFS_DISCON_ENV
  afs_int32 afs_is_disconnected;
- afs_int32 afs_is_logging;
  afs_int32 afs_is_discon_rw;
  /* On reconnection, turn this knob on until it finishes,
   * then turn it off.
--- 33,38 ----
***************
*** 1167,1173 ****
  DECL_PIOCTL(PSetAcl)
  {
      register afs_int32 code;
!     struct conn *tconn;
      struct AFSOpaque acl;
      struct AFSVolSync tsync;
      struct AFSFetchStatus OutStatus;
--- 1166,1172 ----
  DECL_PIOCTL(PSetAcl)
  {
      register afs_int32 code;
!     struct afs_conn *tconn;
      struct AFSOpaque acl;
      struct AFSVolSync tsync;
      struct AFSFetchStatus OutStatus;
***************
*** 1296,1302 ****
      struct AFSVolSync tsync;
      struct AFSFetchStatus OutStatus;
      afs_int32 code;
!     struct conn *tconn;
      struct AFSFid Fid;
      XSTATS_DECLS;
  
--- 1295,1301 ----
      struct AFSVolSync tsync;
      struct AFSFetchStatus OutStatus;
      afs_int32 code;
!     struct afs_conn *tconn;
      struct AFSFid Fid;
      XSTATS_DECLS;
  
***************
*** 1623,1629 ****
      char volName[32];
      char *offLineMsg = afs_osi_Alloc(256);
      char *motd = afs_osi_Alloc(256);
!     register struct conn *tc;
      register afs_int32 code = 0;
      struct AFSFetchVolumeStatus volstat;
      register char *cp;
--- 1622,1628 ----
      char volName[32];
      char *offLineMsg = afs_osi_Alloc(256);
      char *motd = afs_osi_Alloc(256);
!     register struct afs_conn *tc;
      register afs_int32 code = 0;
      struct AFSFetchVolumeStatus volstat;
      register char *cp;
***************
*** 1693,1699 ****
      char volName[32];
      char *offLineMsg = afs_osi_Alloc(256);
      char *motd = afs_osi_Alloc(256);
!     register struct conn *tc;
      register afs_int32 code = 0;
      struct AFSFetchVolumeStatus volstat;
      struct AFSStoreVolumeStatus storeStat;
--- 1692,1698 ----
      char volName[32];
      char *offLineMsg = afs_osi_Alloc(256);
      char *motd = afs_osi_Alloc(256);
!     register struct afs_conn *tc;
      register afs_int32 code = 0;
      struct AFSFetchVolumeStatus volstat;
      struct AFSStoreVolumeStatus storeStat;
***************
*** 1806,1822 ****
      afs_BozonLock(&avc->pvnLock, avc);	/* Since afs_TryToSmush will do a pvn_vptrunc */
  #endif
      ObtainWriteLock(&avc->lock, 225);
!     ObtainWriteLock(&afs_xcbhash, 456);
!     afs_DequeueCallback(avc);
!     avc->states &= ~(CStatd | CDirty);	/* next reference will re-stat cache entry */
!     ReleaseWriteLock(&afs_xcbhash);
!     /* now find the disk cache entries */
!     afs_TryToSmush(avc, *acred, 1);
!     osi_dnlc_purgedp(avc);
!     if (avc->linkData && !(avc->states & CCore)) {
! 	afs_osi_Free(avc->linkData, strlen(avc->linkData) + 1);
! 	avc->linkData = NULL;
!     }
      ReleaseWriteLock(&avc->lock);
  #ifdef AFS_BOZONLOCK_ENV
      afs_BozonUnlock(&avc->pvnLock, avc);
--- 1805,1811 ----
      afs_BozonLock(&avc->pvnLock, avc);	/* Since afs_TryToSmush will do a pvn_vptrunc */
  #endif
      ObtainWriteLock(&avc->lock, 225);
!     afs_ResetVCache(avc, *acred);
      ReleaseWriteLock(&avc->lock);
  #ifdef AFS_BOZONLOCK_ENV
      afs_BozonUnlock(&avc->pvnLock, avc);
***************
*** 2242,2248 ****
  {
      int i;
      struct srvAddr *sa;
!     struct conn *tc;
      struct unixuser *tu;
      afs_int32 retValue;
  
--- 2231,2237 ----
  {
      int i;
      struct srvAddr *sa;
!     struct afs_conn *tc;
      struct unixuser *tu;
      afs_int32 retValue;
  
***************
*** 2526,2532 ****
   */
  DECL_PIOCTL(PRemoveCallBack)
  {
!     register struct conn *tc;
      register afs_int32 code = 0;
      struct AFSCallBack CallBacks_Array[1];
      struct AFSCBFids theFids;
--- 2515,2521 ----
   */
  DECL_PIOCTL(PRemoveCallBack)
  {
!     register struct afs_conn *tc;
      register afs_int32 code = 0;
      struct AFSCallBack CallBacks_Array[1];
      struct AFSCBFids theFids;
***************
*** 2760,2766 ****
      char *bufp;
      struct sysname_info sysState;
      afs_size_t offset, len;
!     register struct conn *tc;
      register struct dcache *tdc;
      register struct vcache *tvc;
      struct AFSFetchStatus OutDirStatus;
--- 2749,2755 ----
      char *bufp;
      struct sysname_info sysState;
      afs_size_t offset, len;
!     register struct afs_conn *tc;
      register struct dcache *tdc;
      register struct vcache *tvc;
      struct AFSFetchStatus OutDirStatus;
***************
*** 4369,4375 ****
  {
      register afs_int32 code, code1;
      afs_int32 bytes;
!     struct conn *tc;
      struct rx_call *tcall;
      struct AFSVolSync tsync;
      struct AFSFetchStatus OutStatus;
--- 4358,4364 ----
  {
      register afs_int32 code, code1;
      afs_int32 bytes;
!     struct afs_conn *tc;
      struct rx_call *tcall;
      struct AFSVolSync tsync;
      struct AFSFetchStatus OutStatus;
***************
*** 4434,4440 ****
  DECL_PIOCTL(PResidencyCmd)
  {
      register afs_int32 code;
!     struct conn *tc;
      struct vcache *tvc;
      struct ResidencyCmdInputs *Inputs;
      struct ResidencyCmdOutputs *Outputs;
--- 4423,4429 ----
  DECL_PIOCTL(PResidencyCmd)
  {
      register afs_int32 code;
!     struct afs_conn *tc;
      struct vcache *tvc;
      struct ResidencyCmdInputs *Inputs;
      struct ResidencyCmdOutputs *Outputs;
***************
*** 4567,4573 ****
      int srvAddrCount;
      struct server *ts;
      struct srvAddr *sa;
!     struct conn *tc;
      afs_int32 i, j;
      struct unixuser *tu;
      struct srvAddr **addrs;
--- 4556,4562 ----
      int srvAddrCount;
      struct server *ts;
      struct srvAddr *sa;
!     struct afs_conn *tc;
      afs_int32 i, j;
      struct unixuser *tu;
      struct srvAddr **addrs;
***************
*** 4696,4708 ****
  	    ObtainWriteLock(&afs_discon_lock, 998);
  
  	    afs_in_sync = 1;
  	    code = afs_ResyncDisconFiles(areq, *acred);
  	    afs_in_sync = 0;
  
  	    if (code && !force) {
! 	    	printf("Files not synchronized properly, still in discon state. \
! 						Please retry or use \"force\".\n");
  	    } else {
  		afs_is_disconnected = 0;
  		afs_is_discon_rw = 0;
  		printf("\nSync succeeded. You are back online.\n");
--- 4685,4702 ----
  	    ObtainWriteLock(&afs_discon_lock, 998);
  
  	    afs_in_sync = 1;
+ 	    afs_MarkAllServersUp();
  	    code = afs_ResyncDisconFiles(areq, *acred);
  	    afs_in_sync = 0;
  
  	    if (code && !force) {
! 	    	printf("Files not synchronized properly, still in discon state. \n"
! 		       "Please retry or use \"force\".\n");
! 		mode = 0;
  	    } else {
+ 		if (force) {
+ 		    afs_DisconDiscardAll(*acred);
+ 		}
  		afs_is_disconnected = 0;
  		afs_is_discon_rw = 0;
  		printf("\nSync succeeded. You are back online.\n");
***************
*** 4719,4725 ****
  
      memcpy(aout, &mode, sizeof(afs_int32));
      *aoutSize = sizeof(afs_int32);
!     return 0;
  #else
      return EINVAL;
  #endif
--- 4713,4719 ----
  
      memcpy(aout, &mode, sizeof(afs_int32));
      *aoutSize = sizeof(afs_int32);
!     return code;
  #else
      return EINVAL;
  #endif
Index: openafs/src/afs/afs_prototypes.h
diff -c openafs/src/afs/afs_prototypes.h:1.74.2.22 openafs/src/afs/afs_prototypes.h:1.74.2.31
*** openafs/src/afs/afs_prototypes.h:1.74.2.22	Tue Dec 16 16:49:04 2008
--- openafs/src/afs/afs_prototypes.h	Thu Jan 22 16:49:15 2009
***************
*** 11,17 ****
  #define _AFS_PROTOTYPES_H_
  
  /* afs_analyze.c */
! extern int afs_Analyze(register struct conn *aconn, afs_int32 acode,
  		       struct VenusFid *afid, register struct vrequest *areq,
  		       int op, afs_int32 locktype, struct cell *cellp);
  
--- 11,17 ----
  #define _AFS_PROTOTYPES_H_
  
  /* afs_analyze.c */
! extern int afs_Analyze(register struct afs_conn *aconn, afs_int32 acode,
  		       struct VenusFid *afid, register struct vrequest *areq,
  		       int op, afs_int32 locktype, struct cell *cellp);
  
***************
*** 30,35 ****
--- 30,36 ----
  extern int DVOffset(register void *ap);
  extern void DZap(struct dcache * fid);
  extern void DFlush(void);
+ extern void DFlushDCache(struct dcache *);
  extern void *DNew(register struct dcache * fid, register int page);
  extern void shutdown_bufferpackage(void);
  
***************
*** 174,195 ****
  extern afs_int32 cryptall;
  extern afs_rwlock_t afs_xinterface;
  extern afs_rwlock_t afs_xconn;
! extern struct conn *afs_Conn(register struct VenusFid *afid,
  			     register struct vrequest *areq,
  			     afs_int32 locktype);
! extern struct conn *afs_ConnBySA(struct srvAddr *sap, unsigned short aport,
  				 afs_int32 acell, struct unixuser *tu,
  				 int force_if_down, afs_int32 create,
  				 afs_int32 locktype);
! extern struct conn *afs_ConnByMHosts(struct server *ahosts[],
  				     unsigned short aport, afs_int32 acell,
  				     register struct vrequest *areq,
  				     afs_int32 locktype);
! extern struct conn *afs_ConnByHost(struct server *aserver,
  				   unsigned short aport, afs_int32 acell,
  				   struct vrequest *areq, int aforce,
  				   afs_int32 locktype);
! extern void afs_PutConn(register struct conn *ac, afs_int32 locktype);
  extern void ForceNewConnections(struct srvAddr *sap);
  
  
--- 175,196 ----
  extern afs_int32 cryptall;
  extern afs_rwlock_t afs_xinterface;
  extern afs_rwlock_t afs_xconn;
! extern struct afs_conn *afs_Conn(register struct VenusFid *afid,
  			     register struct vrequest *areq,
  			     afs_int32 locktype);
! extern struct afs_conn *afs_ConnBySA(struct srvAddr *sap, unsigned short aport,
  				 afs_int32 acell, struct unixuser *tu,
  				 int force_if_down, afs_int32 create,
  				 afs_int32 locktype);
! extern struct afs_conn *afs_ConnByMHosts(struct server *ahosts[],
  				     unsigned short aport, afs_int32 acell,
  				     register struct vrequest *areq,
  				     afs_int32 locktype);
! extern struct afs_conn *afs_ConnByHost(struct server *aserver,
  				   unsigned short aport, afs_int32 acell,
  				   struct vrequest *areq, int aforce,
  				   afs_int32 locktype);
! extern void afs_PutConn(register struct afs_conn *ac, afs_int32 locktype);
  extern void ForceNewConnections(struct srvAddr *sap);
  
  
***************
*** 278,283 ****
--- 279,290 ----
  extern int afs_wakeup(register struct vcache *avc);
  extern int afs_InitCacheFile(char *afile, ino_t ainode);
  extern int afs_DCacheMissingChunks(struct vcache *avc);
+ extern struct dcache *afs_ObtainDCacheForWriting(struct vcache *avc, 
+ 						 afs_size_t filePos, 
+ 						 afs_size_t len, 
+ 						 struct vrequest *areq,
+ 						 int noLock);
+ 
  
  /* afs_disconnected.c */
  
***************
*** 541,547 ****
--- 548,556 ----
  #ifndef afs_osi_Free
  extern void afs_osi_Free(void *x, size_t asize);
  #endif
+ #if !defined(AFS_OBSD44_ENV)
  extern void afs_osi_FreeStr(char *x);
+ #endif
  extern void osi_FreeLargeSpace(void *adata);
  extern void osi_FreeSmallSpace(void *adata);
  extern void *osi_AllocLargeSpace(size_t size);
***************
*** 778,783 ****
--- 787,794 ----
  extern int afs_StoreAllSegments(register struct vcache *avc,
  				struct vrequest *areq, int sync);
  extern int afs_InvalidateAllSegments(struct vcache *avc);
+ extern int afs_ExtendSegments(struct vcache *avc,
+ 			      afs_size_t alen, struct vrequest *areq);
  extern int afs_TruncateAllSegments(register struct vcache *avc,
  				   afs_size_t alen, struct vrequest *areq,
  				   struct AFS_UCRED *acred);
***************
*** 820,826 ****
  extern int afs_HaveCallBacksFrom(struct server *aserver);
  extern void shutdown_server(void);
  extern void afs_RemoveAllConns(void);
! 
  
  /* afs_osidnlc.c */
  extern int osi_dnlc_enter(struct vcache *adp, char *aname, struct vcache *avc,
--- 831,837 ----
  extern int afs_HaveCallBacksFrom(struct server *aserver);
  extern void shutdown_server(void);
  extern void afs_RemoveAllConns(void);
! extern void afs_MarkAllServersUp(void);
  
  /* afs_osidnlc.c */
  extern int osi_dnlc_enter(struct vcache *adp, char *aname, struct vcache *avc,
***************
*** 985,990 ****
--- 996,1002 ----
  			    struct AFSCallBack *CallBackp,
  			    struct server **serverp,
  			    struct AFSVolSync *tsyncp);
+ extern void afs_ResetVCache(struct vcache *, struct AFS_UCRED *);
  extern afs_int32 afs_NFSFindVCache(struct vcache **avcp,
  				   struct VenusFid *afid);
  extern void afs_vcacheInit(int astatSize);
***************
*** 1162,1168 ****
  extern int afs_readdir(OSI_VC_DECL(avc), struct uio *auio, 
  		       struct AFS_UCRED *acred, int *eofp);
  #elif defined(AFS_HPUX100_ENV)
! extern int afs_readdir2(OIS_VC_DECL(avc), struct uio *auio, 
  		        struct AFS_UCRED *acred);
  #else
  extern int afs_readdir(OSI_VC_DECL(avc), struct uio *auio, 
--- 1174,1180 ----
  extern int afs_readdir(OSI_VC_DECL(avc), struct uio *auio, 
  		       struct AFS_UCRED *acred, int *eofp);
  #elif defined(AFS_HPUX100_ENV)
! extern int afs_readdir2(OSI_VC_DECL(avc), struct uio *auio, 
  		        struct AFS_UCRED *acred);
  #else
  extern int afs_readdir(OSI_VC_DECL(avc), struct uio *auio, 
Index: openafs/src/afs/afs_segments.c
diff -c openafs/src/afs/afs_segments.c:1.22.8.4 openafs/src/afs/afs_segments.c:1.22.8.7
*** openafs/src/afs/afs_segments.c:1.22.8.4	Sat Nov  8 11:34:42 2008
--- openafs/src/afs/afs_segments.c	Wed Jan 21 16:15:04 2009
***************
*** 14,20 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_segments.c,v 1.22.8.4 2008/11/08 16:34:42 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
--- 14,20 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_segments.c,v 1.22.8.7 2009/01/21 21:15:04 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
***************
*** 40,46 ****
  int
  afs_StoreMini(register struct vcache *avc, struct vrequest *areq)
  {
!     register struct conn *tc;
      struct AFSStoreStatus InStatus;
      struct AFSFetchStatus OutStatus;
      struct AFSVolSync tsync;
--- 40,46 ----
  int
  afs_StoreMini(register struct vcache *avc, struct vrequest *areq)
  {
!     register struct afs_conn *tc;
      struct AFSStoreStatus InStatus;
      struct AFSFetchStatus OutStatus;
      struct AFSVolSync tsync;
***************
*** 216,226 ****
  	    osi_VM_StoreAllSegments(avc);
      }
      if (AFS_IS_DISCONNECTED && !AFS_IN_SYNC) {
!         if (!AFS_IS_LOGGING) {
!             /* This will probably make someone sad ... */
! 	    /*printf("Net down in afs_StoreSegments\n");*/
!             return ENETDOWN;
!         }
      }
      ConvertWToSLock(&avc->lock);
  
--- 216,224 ----
  	    osi_VM_StoreAllSegments(avc);
      }
      if (AFS_IS_DISCONNECTED && !AFS_IN_SYNC) {
! 	/* This will probably make someone sad ... */
! 	/*printf("Net down in afs_StoreSegments\n");*/
! 	return ENETDOWN;
      }
      ConvertWToSLock(&avc->lock);
  
***************
*** 311,317 ****
  	    int nomore;
  	    unsigned int first = 0;
  	    int *shouldwake;
! 	    struct conn *tc;
  	    struct osi_file *tfile;
  	    struct rx_call *tcall;
  	    XSTATS_DECLS;
--- 309,315 ----
  	    int nomore;
  	    unsigned int first = 0;
  	    int *shouldwake;
! 	    struct afs_conn *tc;
  	    struct osi_file *tfile;
  	    struct rx_call *tcall;
  	    XSTATS_DECLS;
***************
*** 920,925 ****
--- 918,985 ----
      return 0;
  }
  
+ /*! 
+  * 
+  * Extend a cache file
+  *
+  * \param avc pointer to vcache to extend data for
+  * \param alen Length to extend file to
+  * \param areq
+  *
+  * \note avc must be write locked. May release and reobtain avc and GLOCK
+  */
+ int
+ afs_ExtendSegments(struct vcache *avc, afs_size_t alen, struct vrequest *areq) {
+     afs_size_t offset, toAdd;
+     struct osi_file *tfile;
+     afs_int32 code = 0;
+     struct dcache *tdc;
+     void *zeros;
+ 
+     zeros = (void *) afs_osi_Alloc(AFS_PAGESIZE);
+     if (zeros == NULL)
+ 	return ENOMEM;
+     memset(zeros, 0, AFS_PAGESIZE);
+ 
+     while (avc->m.Length < alen) {
+         tdc = afs_ObtainDCacheForWriting(avc, avc->m.Length, alen - avc->m.Length, areq, 0);
+         if (!tdc) {
+ 	    code = EIO;
+ 	    break;
+         }
+ 
+ 	toAdd = alen - avc->m.Length;
+ 
+         offset = avc->m.Length - AFS_CHUNKTOBASE(tdc->f.chunk);
+ 	if (offset + toAdd > AFS_CHUNKTOSIZE(tdc->f.chunk)) {
+ 	    toAdd = AFS_CHUNKTOSIZE(tdc->f.chunk) - offset;
+ 	}
+ #if defined(LINUX_USE_FH)
+         tfile = afs_CFileOpen(&tdc->f.fh, tdc->f.fh_type);
+ #else
+         tfile = afs_CFileOpen(tdc->f.inode);
+ #endif
+ 	while(tdc->validPos < avc->m.Length + toAdd) {
+ 	     afs_size_t towrite;
+ 
+ 	     towrite = (avc->m.Length + toAdd) - tdc->validPos;
+ 	     if (towrite > AFS_PAGESIZE) towrite = AFS_PAGESIZE;
+ 
+ 	     code = afs_CFileWrite(tfile, 
+ 			           tdc->validPos - AFS_CHUNKTOBASE(tdc->f.chunk), 
+ 				   zeros, towrite);
+ 	     tdc->validPos += towrite;
+ 	}
+ 	afs_CFileClose(tfile);
+ 	afs_AdjustSize(tdc, offset + toAdd );
+ 	avc->m.Length += toAdd;
+ 	ReleaseWriteLock(&tdc->lock);
+ 	afs_PutDCache(tdc);
+     }
+ 
+     afs_osi_Free(zeros, AFS_PAGESIZE);
+     return code;
+ }
  
  /*
   * afs_TruncateAllSegments
Index: openafs/src/afs/afs_server.c
diff -c openafs/src/afs/afs_server.c:1.43.4.7 openafs/src/afs/afs_server.c:1.43.4.9
*** openafs/src/afs/afs_server.c:1.43.4.7	Fri May 23 10:25:16 2008
--- openafs/src/afs/afs_server.c	Wed Jan 21 16:27:52 2009
***************
*** 33,39 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_server.c,v 1.43.4.7 2008/05/23 14:25:16 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
--- 33,39 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_server.c,v 1.43.4.9 2009/01/21 21:27:52 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 288,294 ****
  CheckVLServer(register struct srvAddr *sa, struct vrequest *areq)
  {
      register struct server *aserver = sa->server;
!     register struct conn *tc;
      register afs_int32 code;
  
      AFS_STATCNT(CheckVLServer);
--- 288,294 ----
  CheckVLServer(register struct srvAddr *sa, struct vrequest *areq)
  {
      register struct server *aserver = sa->server;
!     register struct afs_conn *tc;
      register afs_int32 code;
  
      AFS_STATCNT(CheckVLServer);
***************
*** 531,537 ****
      struct vrequest treq;
      struct server *ts;
      struct srvAddr *sa;
!     struct conn *tc;
      afs_int32 i, j;
      afs_int32 code;
      afs_int32 start, end = 0, delta;
--- 531,537 ----
      struct vrequest treq;
      struct server *ts;
      struct srvAddr *sa;
!     struct afs_conn *tc;
      afs_int32 i, j;
      afs_int32 code;
      afs_int32 start, end = 0, delta;
***************
*** 540,546 ****
      char tbuffer[CVBS];
      int srvAddrCount;
      struct srvAddr **addrs;
!     struct conn **conns;
      int nconns;
      struct rx_connection **rxconns;      
      afs_int32 *conntimer, *deltas, *results;
--- 540,546 ----
      char tbuffer[CVBS];
      int srvAddrCount;
      struct srvAddr **addrs;
!     struct afs_conn **conns;
      int nconns;
      struct rx_connection **rxconns;      
      afs_int32 *conntimer, *deltas, *results;
***************
*** 554,560 ****
      if (AFS_IS_DISCONNECTED)
          return;
  
!     conns = (struct conn **)0;
      rxconns = (struct rx_connection **) 0;
      conntimer = 0;
      nconns = 0;
--- 554,560 ----
      if (AFS_IS_DISCONNECTED)
          return;
  
!     conns = (struct afs_conn **)0;
      rxconns = (struct rx_connection **) 0;
      conntimer = 0;
      nconns = 0;
***************
*** 584,590 ****
      ReleaseReadLock(&afs_xsrvAddr);
      ReleaseReadLock(&afs_xserver);
  
!     conns = (struct conn **)afs_osi_Alloc(j * sizeof(struct conn *));
      rxconns = (struct rx_connection **)afs_osi_Alloc(j * sizeof(struct rx_connection *));
      conntimer = (afs_int32 *)afs_osi_Alloc(j * sizeof (afs_int32));
      deltas = (afs_int32 *)afs_osi_Alloc(j * sizeof (afs_int32));
--- 584,590 ----
      ReleaseReadLock(&afs_xsrvAddr);
      ReleaseReadLock(&afs_xserver);
  
!     conns = (struct afs_conn **)afs_osi_Alloc(j * sizeof(struct afs_conn *));
      rxconns = (struct rx_connection **)afs_osi_Alloc(j * sizeof(struct rx_connection *));
      conntimer = (afs_int32 *)afs_osi_Alloc(j * sizeof (afs_int32));
      deltas = (afs_int32 *)afs_osi_Alloc(j * sizeof (afs_int32));
***************
*** 752,758 ****
      }
      
      afs_osi_Free(addrs, srvAddrCount * sizeof(*addrs));
!     afs_osi_Free(conns, j * sizeof(struct conn *));
      afs_osi_Free(rxconns, j * sizeof(struct rx_connection *));
      afs_osi_Free(conntimer, j * sizeof(afs_int32));
      afs_osi_Free(deltas, j * sizeof(afs_int32));
--- 752,758 ----
      }
      
      afs_osi_Free(addrs, srvAddrCount * sizeof(*addrs));
!     afs_osi_Free(conns, j * sizeof(struct afs_conn *));
      afs_osi_Free(rxconns, j * sizeof(struct rx_connection *));
      afs_osi_Free(conntimer, j * sizeof(afs_int32));
      afs_osi_Free(deltas, j * sizeof(afs_int32));
***************
*** 1852,1865 ****
      }
  }
  
- #ifdef AFS_DISCON_ENV
- 
  void afs_RemoveAllConns()
  {
      int i;
      struct server *ts, *nts;
      struct srvAddr *sa;
!     struct conn *tc, *ntc;
  
      ObtainReadLock(&afs_xserver);
      ObtainWriteLock(&afs_xconn, 1001);
--- 1852,1863 ----
      }
  }
  
  void afs_RemoveAllConns()
  {
      int i;
      struct server *ts, *nts;
      struct srvAddr *sa;
!     struct afs_conn *tc, *ntc;
  
      ObtainReadLock(&afs_xserver);
      ObtainWriteLock(&afs_xconn, 1001);
***************
*** 1876,1882 ****
                          AFS_GUNLOCK();
                          rx_DestroyConnection(tc->id);
                          AFS_GLOCK();
!                         afs_osi_Free(tc, sizeof(struct conn));
                          tc = ntc;
                      }
                      sa->conns = NULL;
--- 1874,1880 ----
                          AFS_GUNLOCK();
                          rx_DestroyConnection(tc->id);
                          AFS_GLOCK();
!                         afs_osi_Free(tc, sizeof(struct afs_conn));
                          tc = ntc;
                      }
                      sa->conns = NULL;
***************
*** 1891,1897 ****
      
  }
  
! #endif /* AFS_DISCON_ENV */
  
  void shutdown_server()
  {
--- 1889,1912 ----
      
  }
  
! void afs_MarkAllServersUp()
! {
!     int i;
!     struct server *ts;
!     struct srvAddr *sa;
! 
!     ObtainWriteLock(&afs_xserver, 721);
!     ObtainWriteLock(&afs_xsrvAddr, 722);
!     for (i = 0; i< NSERVERS; i++) {
! 	for (ts = afs_servers[i]; ts; ts = ts->next) {
! 	    for (sa = ts->addr; sa; sa = sa->next_sa) {
! 		afs_MarkServerUpOrDown(sa, 0);
! 	    }
! 	}
!     }
!     ReleaseWriteLock(&afs_xsrvAddr);
!     ReleaseWriteLock(&afs_xserver);
! }
  
  void shutdown_server()
  {
Index: openafs/src/afs/afs_trace.et
diff -c openafs/src/afs/afs_trace.et:1.18.4.1 openafs/src/afs/afs_trace.et:1.18.4.2
*** openafs/src/afs/afs_trace.et:1.18.4.1	Fri Nov 23 09:32:56 2007
--- openafs/src/afs/afs_trace.et	Mon Jan 12 08:24:24 2009
***************
*** 132,139 ****
  	ec	CM_TRACE_VMRDWR, "afs_vm_rdwr: vp = 0x%lx, xfrSize 0x%lx,  toffset 0x%x"
  	ec	CM_TRACE_READFAST, "ReadFast vp 0x%lx off (0x%x, 0x%x) resid 0x%x file length (0x%x, 0x%x)"
  	ec	CM_TRACE_FETCH64CODE, "StartRX_FetchData64 for vp 0x%lx returned %d"
! 	ec	CM_TRACE_FETCH64LENG, "FetchData64 for vp 0xl%x code = %d, length = (0x%x, 0x%x)"
! 	ec	CM_TRACE_FETCH64READ, "FetchData64 for vp 0xl%x code = %d, length = 0x%x"
  	ec	CM_TRACE_VMWRITE, "afs_vm_rdwr: vp 0x%lx offset (0x%x, 0x%x) length (0x%x, 0x%x)"
  	ec	CM_TRACE_VMWRITE2, "afs_vm_rdwr: vp 0x%lx first page 0x%x pages %d"
  	ec	CM_TRACE_VMSTOREALL, "osi_VM_StoreAllSegments for vp 0x%lx call %d"
--- 132,139 ----
  	ec	CM_TRACE_VMRDWR, "afs_vm_rdwr: vp = 0x%lx, xfrSize 0x%lx,  toffset 0x%x"
  	ec	CM_TRACE_READFAST, "ReadFast vp 0x%lx off (0x%x, 0x%x) resid 0x%x file length (0x%x, 0x%x)"
  	ec	CM_TRACE_FETCH64CODE, "StartRX_FetchData64 for vp 0x%lx returned %d"
! 	ec      CM_TRACE_FETCH64LENG, "FetchData64 for vp 0x%lx code = %d, length = (0x%x, 0x%x)"
! 	ec      CM_TRACE_FETCH64READ, "FetchData64 for vp 0x%lx code = %d, length = 0x%x"
  	ec	CM_TRACE_VMWRITE, "afs_vm_rdwr: vp 0x%lx offset (0x%x, 0x%x) length (0x%x, 0x%x)"
  	ec	CM_TRACE_VMWRITE2, "afs_vm_rdwr: vp 0x%lx first page 0x%x pages %d"
  	ec	CM_TRACE_VMSTOREALL, "osi_VM_StoreAllSegments for vp 0x%lx call %d"
Index: openafs/src/afs/afs_user.c
diff -c openafs/src/afs/afs_user.c:1.15.14.4 openafs/src/afs/afs_user.c:1.15.14.5
*** openafs/src/afs/afs_user.c:1.15.14.4	Wed Dec 20 15:08:33 2006
--- openafs/src/afs/afs_user.c	Wed Jan 21 15:07:47 2009
***************
*** 14,20 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_user.c,v 1.15.14.4 2006/12/20 20:08:33 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
--- 14,20 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_user.c,v 1.15.14.5 2009/01/21 20:07:47 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 65,71 ****
      register int i;
      register struct server *ts;
      register struct srvAddr *sa;
!     register struct conn *tc, **lc;
  
      AFS_STATCNT(RemoveUserConns);
      for (i = 0; i < NSERVERS; i++) {
--- 65,71 ----
      register int i;
      register struct server *ts;
      register struct srvAddr *sa;
!     register struct afs_conn *tc, **lc;
  
      AFS_STATCNT(RemoveUserConns);
      for (i = 0; i < NSERVERS; i++) {
***************
*** 78,84 ****
  			AFS_GUNLOCK();
  			rx_DestroyConnection(tc->id);
  			AFS_GLOCK();
! 			afs_osi_Free(tc, sizeof(struct conn));
  			break;	/* at most one instance per server */
  		    }		/*Found unreferenced connection for user */
  		}		/*For each connection on the server */
--- 78,84 ----
  			AFS_GUNLOCK();
  			rx_DestroyConnection(tc->id);
  			AFS_GLOCK();
! 			afs_osi_Free(tc, sizeof(struct afs_conn));
  			break;	/* at most one instance per server */
  		    }		/*Found unreferenced connection for user */
  		}		/*For each connection on the server */
***************
*** 243,249 ****
  {
      int i;
      struct srvAddr *sa;
!     struct conn *tc;
  
      AFS_STATCNT(afs_ResetUserConns);
      ObtainReadLock(&afs_xsrvAddr);
--- 243,249 ----
  {
      int i;
      struct srvAddr *sa;
!     struct afs_conn *tc;
  
      AFS_STATCNT(afs_ResetUserConns);
      ObtainReadLock(&afs_xsrvAddr);
Index: openafs/src/afs/afs_util.c
diff -c openafs/src/afs/afs_util.c:1.28.2.8 openafs/src/afs/afs_util.c:1.28.2.9
*** openafs/src/afs/afs_util.c:1.28.2.8	Mon Jun 30 23:35:23 2008
--- openafs/src/afs/afs_util.c	Wed Jan 21 15:07:47 2009
***************
*** 16,22 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_util.c,v 1.28.2.8 2008/07/01 03:35:23 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.9 2009/01/21 20:07:47 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 244,250 ****
      {
  	struct srvAddr *sa;
  	struct server *ts;
! 	struct conn *tc;
  	for (i = 0; i < NSERVERS; i++) {
  	    for (ts = afs_servers[i]; ts; ts = ts->next) {
  		if (ts->flags & SRVR_ISDOWN)
--- 244,250 ----
      {
  	struct srvAddr *sa;
  	struct server *ts;
! 	struct afs_conn *tc;
  	for (i = 0; i < NSERVERS; i++) {
  	    for (ts = afs_servers[i]; ts; ts = ts->next) {
  		if (ts->flags & SRVR_ISDOWN)
Index: openafs/src/afs/afs_vcache.c
diff -c openafs/src/afs/afs_vcache.c:1.114.2.15 openafs/src/afs/afs_vcache.c:1.114.2.19
*** openafs/src/afs/afs_vcache.c:1.114.2.15	Sun Nov 30 15:06:51 2008
--- openafs/src/afs/afs_vcache.c	Wed Jan 21 16:15:04 2009
***************
*** 41,47 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_vcache.c,v 1.114.2.15 2008/11/30 20:06:51 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
--- 41,47 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_vcache.c,v 1.114.2.19 2009/01/21 21:15:04 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
***************
*** 388,394 ****
      struct server *tsp;
      int i;
      struct vrequest treq;
!     struct conn *tc;
      int safety1, safety2, safety3;
      XSTATS_DECLS;
      if ((code = afs_InitReq(&treq, afs_osi_credp)))
--- 388,394 ----
      struct server *tsp;
      int i;
      struct vrequest treq;
!     struct afs_conn *tc;
      int safety1, safety2, safety3;
      XSTATS_DECLS;
      if ((code = afs_InitReq(&treq, afs_osi_credp)))
***************
*** 935,942 ****
      tvc->callback = serverp;    /* to minimize chance that clear
  				 * request is lost */
  #if defined(AFS_DISCON_ENV)
-     tvc->ddirty_next = NULL;
      tvc->ddirty_flags = 0;
  #endif
  
      i = VCHash(afid);
--- 935,943 ----
      tvc->callback = serverp;    /* to minimize chance that clear
  				 * request is lost */
  #if defined(AFS_DISCON_ENV)
      tvc->ddirty_flags = 0;
+     tvc->shVnode = 0;
+     tvc->shUnique = 0;
  #endif
  
      i = VCHash(afid);
***************
*** 1172,1178 ****
  {
      register struct vcache *tvc;
      register int i;
!     register struct conn *tc;
      register afs_int32 code;
      register struct AFS_UCRED *cred = NULL;
      struct vrequest treq, ureq;
--- 1173,1179 ----
  {
      register struct vcache *tvc;
      register int i;
!     register struct afs_conn *tc;
      register afs_int32 code;
      register struct AFS_UCRED *cred = NULL;
      struct vrequest treq, ureq;
***************
*** 1502,1508 ****
  		struct vrequest *areq)
  {
      afs_int32 code;
!     struct conn *tc;
      struct AFSFetchStatus OutStatus;
      struct AFSVolSync tsync;
      XSTATS_DECLS;
--- 1503,1509 ----
  		struct vrequest *areq)
  {
      afs_int32 code;
!     struct afs_conn *tc;
      struct AFSFetchStatus OutStatus;
      struct AFSVolSync tsync;
      XSTATS_DECLS;
***************
*** 1617,1636 ****
       	flags |= VDisconTrunc;
       }
  
!     ObtainWriteLock(&afs_DDirtyVCListLock, 701);
! 
!     if (flags) {
!     	/* Add to disconnected dirty list and set dirty flag.*/
! 	if (!avc->ddirty_flags ||
! 		(avc->ddirty_flags == VDisconShadowed)) {
! 		/* Not in dirty list. */
! 		AFS_DISCON_ADD_DIRTY(avc, 1);
! 	}
! 
! 	avc->ddirty_flags |= flags;
!     }
! 
!     ReleaseWriteLock(&afs_DDirtyVCListLock);
  
      /* XXX: How about the rest of the fields? */
  
--- 1618,1625 ----
       	flags |= VDisconTrunc;
       }
  
!     if (flags)
! 	afs_DisconAddDirty(avc, flags, 1);
  
      /* XXX: How about the rest of the fields? */
  
***************
*** 1760,1766 ****
  {
      afs_int32 code;
      afs_uint32 start;
!     register struct conn *tc;
      struct AFSFetchStatus OutDirStatus;
      XSTATS_DECLS;
      if (!name)
--- 1749,1755 ----
  {
      afs_int32 code;
      afs_uint32 start;
!     register struct afs_conn *tc;
      struct AFSFetchStatus OutDirStatus;
      XSTATS_DECLS;
      if (!name)
***************
*** 2020,2035 ****
  	} else {
  
  	    if (AFS_IS_DISCONNECTED) {
! 		if (AFS_IS_DISCON_RW) {
! 		    if (vType(tvc) == VDIR)
! 		    	OutStatus.FileType = Directory;
! 
! 		    code = tvc?0:ENOENT;
! 		} else {
! 		    /* Nothing to do otherwise...*/
! 		    code = ENETDOWN;
! 		    printf("Network is down in afs_GetCache");
! 		}
  	    } else
  	        code = afs_FetchStatus(tvc, afid, areq, &OutStatus);
  
--- 2009,2017 ----
  	} else {
  
  	    if (AFS_IS_DISCONNECTED) {
! 		/* Nothing to do otherwise...*/
! 		code = ENETDOWN;
! 		printf("Network is down in afs_GetCache");
  	    } else
  	        code = afs_FetchStatus(tvc, afid, areq, &OutStatus);
  
***************
*** 2568,2574 ****
  {
      int code;
      afs_uint32 start = 0;
!     register struct conn *tc;
      struct AFSCallBack CallBack;
      struct AFSVolSync tsync;
      XSTATS_DECLS;
--- 2550,2556 ----
  {
      int code;
      afs_uint32 start = 0;
!     register struct afs_conn *tc;
      struct AFSCallBack CallBack;
      struct AFSVolSync tsync;
      XSTATS_DECLS;
***************
*** 2633,2639 ****
  void
  afs_StuffVcache(register struct VenusFid *afid,
  		struct AFSFetchStatus *OutStatus,
! 		struct AFSCallBack *CallBack, register struct conn *tc,
  		struct vrequest *areq)
  {
      register afs_int32 code, i, newvcache = 0;
--- 2615,2621 ----
  void
  afs_StuffVcache(register struct VenusFid *afid,
  		struct AFSFetchStatus *OutStatus,
! 		struct AFSCallBack *CallBack, register struct afs_conn *tc,
  		struct vrequest *areq)
  {
      register afs_int32 code, i, newvcache = 0;
***************
*** 2783,2788 ****
--- 2765,2794 ----
  
  
  /*!
+  * Reset a vcache entry, so local contents are ignored, and the
+  * server will be reconsulted next time the vcache is used
+  * 
+  * \param avc Pointer to the cache entry to reset
+  * \param acred 
+  *
+  * \note avc must be write locked on entry
+  */
+ void 
+ afs_ResetVCache(struct vcache *avc, struct AFS_UCRED *acred) {
+     ObtainWriteLock(&afs_xcbhash, 456);
+     afs_DequeueCallback(avc);
+     avc->states &= ~(CStatd | CDirty);	/* next reference will re-stat */
+     ReleaseWriteLock(&afs_xcbhash);
+     /* now find the disk cache entries */
+     afs_TryToSmush(avc, acred, 1);
+     osi_dnlc_purgedp(avc);
+     if (avc->linkData && !(avc->states & CCore)) {
+ 	afs_osi_Free(avc->linkData, strlen(avc->linkData) + 1);
+ 	avc->linkData = NULL;
+     }
+ }
+ 
+ /*!
   * Sleepa when searching for a vcache. Releases all the pending locks,
   * sleeps then obtains the previously released locks.
   *
***************
*** 3288,3297 ****
      for (i = 0; i < VCSIZE; i++) {
          for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
              if ((tvc->states & CRO) == 0 && tvc->callback) {
-                 /* XXX - should we check if the callback has expired here? */
                  afs_QueueVCB(tvc);
                  tvc->callback = NULL;
-                 tvc->states &- ~(CStatd | CUnique);
                  nq++;
              }
          }
--- 3294,3301 ----
Index: openafs/src/afs/afs_volume.c
diff -c openafs/src/afs/afs_volume.c:1.31.2.8 openafs/src/afs/afs_volume.c:1.31.2.9
*** openafs/src/afs/afs_volume.c:1.31.2.8	Sat Nov  8 11:34:42 2008
--- openafs/src/afs/afs_volume.c	Wed Jan 21 15:07:47 2009
***************
*** 19,25 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_volume.c,v 1.31.2.8 2008/11/08 16:34:42 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
--- 19,25 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_volume.c,v 1.31.2.9 2009/01/21 20:07:47 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 708,714 ****
      struct uvldbentry *utve;
      struct cell *tcell;
      char *tbuffer, *ve;
!     struct conn *tconn;
      struct vrequest treq;
  
      if (strlen(aname) > VL_MAXNAMELEN)	/* Invalid volume name */
--- 708,714 ----
      struct uvldbentry *utve;
      struct cell *tcell;
      char *tbuffer, *ve;
!     struct afs_conn *tconn;
      struct vrequest treq;
  
      if (strlen(aname) > VL_MAXNAMELEN)	/* Invalid volume name */
***************
*** 1009,1015 ****
  		    struct cell *tcell, struct vrequest *areq)
  {
      register struct server *ts;
!     struct conn *tconn;
      struct cell *cellp;
      register int i, j;
      afs_uint32 serverid;
--- 1009,1015 ----
  		    struct cell *tcell, struct vrequest *areq)
  {
      register struct server *ts;
!     struct afs_conn *tconn;
      struct cell *cellp;
      register int i, j;
      afs_uint32 serverid;
Index: openafs/src/afs/discon.h
diff -c openafs/src/afs/discon.h:1.2.2.4 openafs/src/afs/discon.h:1.2.2.7
*** openafs/src/afs/discon.h:1.2.2.4	Sun Nov 30 15:06:51 2008
--- openafs/src/afs/discon.h	Thu Jan 22 15:20:01 2009
***************
*** 3,31 ****
  
  #ifndef AFS_DISCON_ENV
  #define AFS_IS_DISCONNECTED 0
- #define AFS_IS_LOGGING 0
  #define AFS_IS_DISCON_RW 0
  #define AFS_IN_SYNC 0
  #define AFS_DISCON_LOCK()
  #define AFS_DISCON_UNLOCK()
  
! #define AFS_DISCON_ADD_DIRTY(avc, lock)
  
  #else
  
  extern afs_int32    afs_is_disconnected;
- extern afs_int32    afs_is_logging;
  extern afs_int32    afs_is_discon_rw;
  extern afs_int32    afs_in_sync;
  extern afs_rwlock_t afs_discon_lock;
  
! extern struct vcache *afs_DDirtyVCList;
! extern struct vcache *afs_DDirtyVCListStart;
! extern struct vcache *afs_DDirtyVCListPrev;
! extern afs_rwlock_t afs_DDirtyVCListLock;
! extern afs_int32 afs_ConflictPolicy;
  
- extern void afs_RemoveAllConns();
  extern afs_uint32 afs_DisconVnode; /* XXX: not protected. */
  
  /* For afs_GenFakeFid. */
--- 3,31 ----
  
  #ifndef AFS_DISCON_ENV
  #define AFS_IS_DISCONNECTED 0
  #define AFS_IS_DISCON_RW 0
  #define AFS_IN_SYNC 0
  #define AFS_DISCON_LOCK()
  #define AFS_DISCON_UNLOCK()
  
! #define afs_DisconAddDirty(x, y, z)
  
  #else
  
+ #if !defined(inline) && !defined(__GNUC__)
+ #define inline
+ #endif
+ 
  extern afs_int32    afs_is_disconnected;
  extern afs_int32    afs_is_discon_rw;
  extern afs_int32    afs_in_sync;
  extern afs_rwlock_t afs_discon_lock;
  
! extern struct afs_q afs_disconDirty;
! extern struct afs_q afs_disconShadow;
! extern afs_rwlock_t afs_disconDirtyLock;
! extern afs_int32    afs_ConflictPolicy;
  
  extern afs_uint32 afs_DisconVnode; /* XXX: not protected. */
  
  /* For afs_GenFakeFid. */
***************
*** 38,44 ****
  					struct vattr *attrs);
  extern int afs_ResyncDisconFiles(struct vrequest *areq,
  					struct AFS_UCRED *acred);
! extern void afs_RemoveAllConns();
  extern void afs_GenFakeFid(struct VenusFid *afid, afs_uint32 avtype);
  extern void afs_GenShadowFid(struct VenusFid *afid);
  extern void afs_GenDisconStatus(struct vcache *adp,
--- 38,44 ----
  					struct vattr *attrs);
  extern int afs_ResyncDisconFiles(struct vrequest *areq,
  					struct AFS_UCRED *acred);
! extern void afs_RemoveAllConns(void);
  extern void afs_GenFakeFid(struct VenusFid *afid, afs_uint32 avtype);
  extern void afs_GenShadowFid(struct VenusFid *afid);
  extern void afs_GenDisconStatus(struct vcache *adp,
***************
*** 47,87 ****
  					struct vattr *attrs,
  					struct vrequest *areq,
  					int file_type);
! extern int afs_HashOutDCache(struct dcache *adc, int zap);
! extern int afs_MakeShadowDir(struct vcache *avc);
  extern void afs_DeleteShadowDir(struct vcache *avc);
! extern struct dcache *afs_FindDCacheByFid(register struct VenusFid *afid);
  extern void afs_UpdateStatus(struct vcache *avc,
  					struct VenusFid *afid,
  					struct vrequest *areq,
  					struct AFSFetchStatus *Outsp,
  					struct AFSCallBack *acb,
  					afs_uint32 start);
! extern void afs_RemoveAllConns();
  
  #define AFS_IS_DISCONNECTED (afs_is_disconnected)
- #define AFS_IS_LOGGING (afs_is_logging)
  #define AFS_IS_DISCON_RW (afs_is_discon_rw)
  #define AFS_IN_SYNC (afs_in_sync)
  #define AFS_DISCON_LOCK() ObtainReadLock(&afs_discon_lock)
  #define AFS_DISCON_UNLOCK() ReleaseReadLock(&afs_discon_lock)
  
! /* Call with avc and afs_DDirtyVCListLock w locks held. */
! #define AFS_DISCON_ADD_DIRTY(avc, lock)				\
! do {								\
!     int retry = 0;						\
!     if (!afs_DDirtyVCListStart) {				\
!     	afs_DDirtyVCListStart = afs_DDirtyVCList = avc;		\
!     } else {							\
!     	afs_DDirtyVCList->ddirty_next = avc;			\
! 	afs_DDirtyVCList = avc;					\
!     }								\
!     if (lock)							\
! 	ObtainWriteLock(&afs_xvcache, 763);			\
!     osi_vnhold(avc, 0);						\
!     if (lock)							\
! 	ReleaseWriteLock(&afs_xvcache);				\
! } while(0);
  
  #endif /* AFS_DISCON_ENV */
  #endif /* _DISCON_H */
--- 47,92 ----
  					struct vattr *attrs,
  					struct vrequest *areq,
  					int file_type);
! extern int afs_MakeShadowDir(struct vcache *avc, struct dcache *adc);
  extern void afs_DeleteShadowDir(struct vcache *avc);
! extern struct dcache *afs_FindDCacheByFid(struct VenusFid *afid);
  extern void afs_UpdateStatus(struct vcache *avc,
  					struct VenusFid *afid,
  					struct vrequest *areq,
  					struct AFSFetchStatus *Outsp,
  					struct AFSCallBack *acb,
  					afs_uint32 start);
! extern void afs_DisconDiscardAll(struct AFS_UCRED *);
  
  #define AFS_IS_DISCONNECTED (afs_is_disconnected)
  #define AFS_IS_DISCON_RW (afs_is_discon_rw)
  #define AFS_IN_SYNC (afs_in_sync)
  #define AFS_DISCON_LOCK() ObtainReadLock(&afs_discon_lock)
  #define AFS_DISCON_UNLOCK() ReleaseReadLock(&afs_discon_lock)
  
! /* Call with avc lock held */
! static inline void afs_DisconAddDirty(struct vcache *avc, int operation, int lock) {
!     if (!avc->ddirty_flags) {
! 	if (lock) 
! 	    ObtainWriteLock(&afs_xvcache, 702);
! 	ObtainWriteLock(&afs_disconDirtyLock, 703);
! 	QAdd(&afs_disconDirty, &avc->dirtyq);
! 	osi_vnhold(avc, 0);
! 	ReleaseWriteLock(&afs_disconDirtyLock);
! 	if (lock)
! 	    ReleaseWriteLock(&afs_xvcache);
!     }
!     avc->ddirty_flags |= operation;
! } 
! 
! /* Call with avc lock held */
! static inline void afs_DisconRemoveDirty(struct vcache *avc) {
!     ObtainWriteLock(&afs_disconDirtyLock, 704);
!     QRemove(&avc->dirtyq);
!     ReleaseWriteLock(&afs_disconDirtyLock);
!     avc->ddirty_flags = 0;
!     afs_PutVCache(avc);
! }
  
  #endif /* AFS_DISCON_ENV */
  #endif /* _DISCON_H */
Index: openafs/src/afs/DOC/afs_rwlocks
diff -c openafs/src/afs/DOC/afs_rwlocks:1.5 openafs/src/afs/DOC/afs_rwlocks:1.5.4.1
*** openafs/src/afs/DOC/afs_rwlocks:1.5	Thu Jan 26 11:03:03 2006
--- openafs/src/afs/DOC/afs_rwlocks	Wed Jan 21 16:15:05 2009
***************
*** 7,12 ****
--- 7,15 ----
  
  Locking order (in order of locking) --
  
+ 0.1 afs_discon_lock. Locks the current disconnected state, so it
+     can't be changed under active operations
+ 
  1.  PVN lock in cache entry.  Locks out pvn operations on vnode from
  our own layer.
  
***************
*** 21,39 ****
  However, if it turns out we never need to lock multiple dcache's,
  we should just say it's not allowed, and simplify things.
  
! 5. afs_xdcache.  Protects the dcache hash tables and afs_index* in
  afs_dcache.c.  As with afs_xvcache below, a newly created dcache
  entries can be locked while holding afs_xdcache.
  
  Bugs: afs_xvcache locked before afs_xdcache in afs_remove, afs_symlink,
  etc in the file afs_vnodeops.c
  
! 6. afs_xvcache.  Must be able to load new cache entries while holding
  locks on others.  Note this means you can't lock a cache entry while
  holding either of this lock, unless, as in afs_create, the cache entry
  is actually created while the afs_xvcache is held.
  
! 6a. afs_xvreclaim. Protects the lookaside reclaim list. Locked inside xvcache in FlushReclaimedVcaches via NewVCache or the 1 min loop.
  
  7. afs_xvcb.  Volume callback lock.  Locked before afs_xserver in
  afs_RemoveVCB.
--- 24,47 ----
  However, if it turns out we never need to lock multiple dcache's,
  we should just say it's not allowed, and simplify things.
  
! 5.  afs_xdcache.  Protects the dcache hash tables and afs_index* in
  afs_dcache.c.  As with afs_xvcache below, a newly created dcache
  entries can be locked while holding afs_xdcache.
  
  Bugs: afs_xvcache locked before afs_xdcache in afs_remove, afs_symlink,
  etc in the file afs_vnodeops.c
  
! 6.  afs_xvcache.  Must be able to load new cache entries while holding
  locks on others.  Note this means you can't lock a cache entry while
  holding either of this lock, unless, as in afs_create, the cache entry
  is actually created while the afs_xvcache is held.
  
! 6a. afs_disconDirtyLock. Protects the disconnected dirty and shadow
! vcache queues. Must be after afs_xvcache, because we lock this whilst
! hold xvcache in afs_create.
! 
! 6b. afs_xvreclaim. Protects the lookaside reclaim list. Locked inside 
! xvcache in FlushReclaimedVcaches via NewVCache or the 1 min loop.
  
  7. afs_xvcb.  Volume callback lock.  Locked before afs_xserver in
  afs_RemoveVCB.
Index: openafs/src/afs/FBSD/osi_vnodeops.c
diff -c openafs/src/afs/FBSD/osi_vnodeops.c:1.22.6.2 openafs/src/afs/FBSD/osi_vnodeops.c:1.22.6.4
*** openafs/src/afs/FBSD/osi_vnodeops.c:1.22.6.2	Tue Aug 26 10:01:33 2008
--- openafs/src/afs/FBSD/osi_vnodeops.c	Thu Jan 22 16:49:17 2009
***************
*** 48,54 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/FBSD/osi_vnodeops.c,v 1.22.6.2 2008/08/26 14:01:33 shadow Exp $");
  
  #include <afs/sysincludes.h>	/* Standard vendor system headers */
  #include <afsincludes.h>	/* Afs-based standard headers */
--- 48,54 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/FBSD/osi_vnodeops.c,v 1.22.6.4 2009/01/22 21:49:17 shadow Exp $");
  
  #include <afs/sysincludes.h>	/* Standard vendor system headers */
  #include <afsincludes.h>	/* Afs-based standard headers */
***************
*** 1044,1051 ****
      if (((ap->a_command >> 8) & 0xff) == 'V') {
  	/* This is a VICEIOCTL call */
  	AFS_GLOCK();
! 	error = HandleIoctl(tvc, NULL /*Not used */ ,
! 			    ap->a_command, ap->a_data);
  	AFS_GUNLOCK();
  	return (error);
      } else {
--- 1044,1050 ----
      if (((ap->a_command >> 8) & 0xff) == 'V') {
  	/* This is a VICEIOCTL call */
  	AFS_GLOCK();
! 	error = HandleIoctl(tvc, ap->a_command, ap->a_data);
  	AFS_GUNLOCK();
  	return (error);
      } else {
***************
*** 1559,1565 ****
  {
      int error;
      AFS_GLOCK();
!     error = afs_ustrategy(ap->a_bp);
      AFS_GUNLOCK();
      return error;
  }
--- 1558,1564 ----
  {
      int error;
      AFS_GLOCK();
!     error = afs_ustrategy(ap->a_bp, osi_cred());
      AFS_GUNLOCK();
      return error;
  }
Index: openafs/src/afs/LINUX/osi_cred.c
diff -c openafs/src/afs/LINUX/osi_cred.c:1.12.6.1 openafs/src/afs/LINUX/osi_cred.c:1.12.6.2
*** openafs/src/afs/LINUX/osi_cred.c:1.12.6.1	Mon Dec 18 21:29:39 2006
--- openafs/src/afs/LINUX/osi_cred.c	Thu Jan 15 08:27:29 2009
***************
*** 15,21 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_cred.c,v 1.12.6.1 2006/12/19 02:29:39 shadow Exp $");
  
  #include "afs/sysincludes.h"
  #include "afsincludes.h"
--- 15,21 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_cred.c,v 1.12.6.2 2009/01/15 13:27:29 shadow Exp $");
  
  #include "afs/sysincludes.h"
  #include "afsincludes.h"
***************
*** 79,93 ****
  {
      cred_t *cr = crget();
  
!     cr->cr_uid = current->fsuid;
!     cr->cr_ruid = current->uid;
!     cr->cr_gid = current->fsgid;
!     cr->cr_rgid = current->gid;
  
  #if defined(AFS_LINUX26_ENV)
      task_lock(current);
!     get_group_info(current->group_info);
!     cr->cr_group_info = current->group_info;
      task_unlock(current);
  #else
      memcpy(cr->cr_groups, current->groups, NGROUPS * sizeof(gid_t));
--- 79,93 ----
  {
      cred_t *cr = crget();
  
!     cr->cr_uid = current_fsuid();
!     cr->cr_ruid = current_uid();
!     cr->cr_gid = current_fsgid();
!     cr->cr_rgid = current_gid();
  
  #if defined(AFS_LINUX26_ENV)
      task_lock(current);
!     get_group_info(current_group_info());
!     cr->cr_group_info = current_group_info();
      task_unlock(current);
  #else
      memcpy(cr->cr_groups, current->groups, NGROUPS * sizeof(gid_t));
***************
*** 101,110 ****
--- 101,120 ----
  void
  crset(cred_t * cr)
  {
+ #if defined(STRUCT_TASK_HAS_CRED)
+     struct cred *new_creds;
+ 
+     new_creds = prepare_creds();
+     new_creds->fsuid = cr->cr_uid;
+     new_creds->uid = cr->cr_ruid;
+     new_creds->fsgid = cr->cr_gid;
+     new_creds->gid = cr->cr_rgid;
+ #else
      current->fsuid = cr->cr_uid;
      current->uid = cr->cr_ruid;
      current->fsgid = cr->cr_gid;
      current->gid = cr->cr_rgid;
+ #endif
  #if defined(AFS_LINUX26_ENV)
  {
      struct group_info *old_info;
***************
*** 113,120 ****
--- 123,136 ----
      get_group_info(cr->cr_group_info);
  
      task_lock(current);
+ #if defined(STRUCT_TASK_HAS_CRED)
+     old_info = current->cred->group_info;
+     new_creds->group_info = cr->cr_group_info;
+     commit_creds(new_creds);
+ #else
      old_info = current->group_info;
      current->group_info = cr->cr_group_info;
+ #endif
      task_unlock(current);
  
      put_group_info(old_info);
Index: openafs/src/afs/LINUX/osi_file.c
diff -c openafs/src/afs/LINUX/osi_file.c:1.28.2.11 openafs/src/afs/LINUX/osi_file.c:1.28.2.14
*** openafs/src/afs/LINUX/osi_file.c:1.28.2.11	Sat Nov  8 11:34:42 2008
--- openafs/src/afs/LINUX/osi_file.c	Thu Jan 15 08:27:29 2009
***************
*** 11,17 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_file.c,v 1.28.2.11 2008/11/08 16:34:42 shadow Exp $");
  
  #ifdef AFS_LINUX24_ENV
  #include "h/module.h" /* early to avoid printf->printk mapping */
--- 11,17 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_file.c,v 1.28.2.14 2009/01/15 13:27:29 shadow Exp $");
  
  #ifdef AFS_LINUX24_ENV
  #include "h/module.h" /* early to avoid printf->printk mapping */
***************
*** 87,93 ****
--- 87,97 ----
  #endif
      tip->i_flags |= MS_NOATIME;	/* Disable updating access times. */
  
+ #if defined(STRUCT_TASK_HAS_CRED)
+     filp = dentry_open(dp, mntget(afs_cacheMnt), O_RDWR, current_cred());
+ #else
      filp = dentry_open(dp, mntget(afs_cacheMnt), O_RDWR);
+ #endif
      if (IS_ERR(filp))
  #if defined(LINUX_USE_FH)
  	osi_Panic("Can't open file\n");
***************
*** 95,101 ****
  	osi_Panic("Can't open inode %d\n", ainode);
  #endif
      afile->filp = filp;
!     afile->size = FILE_INODE(filp)->i_size;
      AFS_GLOCK();
      afile->offset = 0;
      afile->proc = (int (*)())0;
--- 99,105 ----
  	osi_Panic("Can't open inode %d\n", ainode);
  #endif
      afile->filp = filp;
!     afile->size = i_size_read(FILE_INODE(filp));
      AFS_GLOCK();
      afile->offset = 0;
      afile->proc = (int (*)())0;
***************
*** 150,156 ****
  	code = filp->f_op->open(tip, filp);
      if (code)
  	osi_Panic("Can't open inode %d\n", ainode);
!     afile->size = tip->i_size;
      AFS_GLOCK();
      afile->offset = 0;
      afile->proc = (int (*)())0;
--- 154,160 ----
  	code = filp->f_op->open(tip, filp);
      if (code)
  	osi_Panic("Can't open inode %d\n", ainode);
!     afile->size = i_size_read(tip);
      AFS_GLOCK();
      afile->offset = 0;
      afile->proc = (int (*)())0;
***************
*** 182,188 ****
      register afs_int32 code;
      AFS_STATCNT(osi_Stat);
      MObtainWriteLock(&afs_xosi, 320);
!     astat->size = OSIFILE_INODE(afile)->i_size;
  #if defined(AFS_LINUX26_ENV)
      astat->mtime = OSIFILE_INODE(afile)->i_mtime.tv_sec;
      astat->atime = OSIFILE_INODE(afile)->i_atime.tv_sec;
--- 186,192 ----
      register afs_int32 code;
      AFS_STATCNT(osi_Stat);
      MObtainWriteLock(&afs_xosi, 320);
!     astat->size = i_size_read(OSIFILE_INODE(afile));
  #if defined(AFS_LINUX26_ENV)
      astat->mtime = OSIFILE_INODE(afile)->i_mtime.tv_sec;
      astat->atime = OSIFILE_INODE(afile)->i_atime.tv_sec;
***************
*** 272,278 ****
      if (!code)
  	truncate_inode_pages(&inode->i_data, asize);
  #else
!     inode->i_size = asize;
      if (inode->i_sb->s_op && inode->i_sb->s_op->notify_change) {
  	code = inode->i_sb->s_op->notify_change(&afile->dentry, &newattrs);
      }
--- 276,282 ----
      if (!code)
  	truncate_inode_pages(&inode->i_data, asize);
  #else
!     i_size_write(inode, asize);
      if (inode->i_sb->s_op && inode->i_sb->s_op->notify_change) {
  	code = inode->i_sb->s_op->notify_change(&afile->dentry, &newattrs);
      }
Index: openafs/src/afs/LINUX/osi_groups.c
diff -c openafs/src/afs/LINUX/osi_groups.c:1.28.4.14 openafs/src/afs/LINUX/osi_groups.c:1.28.4.15
*** openafs/src/afs/LINUX/osi_groups.c:1.28.4.14	Sun Jun  8 23:39:16 2008
--- openafs/src/afs/LINUX/osi_groups.c	Thu Jan 15 08:27:29 2009
***************
*** 20,26 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_groups.c,v 1.28.4.14 2008/06/09 03:39:16 shadow Exp $");
  
  #include "afs/sysincludes.h"
  #include "afsincludes.h"
--- 20,26 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_groups.c,v 1.28.4.15 2009/01/15 13:27:29 shadow Exp $");
  
  #include "afs/sysincludes.h"
  #include "afsincludes.h"
***************
*** 51,57 ****
  
      crset(*cr);
  
! #ifdef STRUCT_TASK_STRUCT_HAS_PARENT
      if (change_parent) {
  	old_info = current->parent->group_info;
  	get_group_info(group_info);
--- 51,57 ----
  
      crset(*cr);
  
! #if defined(STRUCT_TASK_STRUCT_HAS_PARENT) && !defined(STRUCT_TASK_HAS_CRED)
      if (change_parent) {
  	old_info = current->parent->group_info;
  	get_group_info(group_info);
***************
*** 247,258 ****
  
  #ifdef KEY_ALLOC_NEEDS_STRUCT_TASK
  	keyring = key_alloc(__key_type_keyring, desc,
! 			    task->uid, task->gid, task,
  			    (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
  			    not_in_quota);
  #else
  	keyring = key_alloc(__key_type_keyring, desc,
! 			    task->uid, task->gid,
  			    (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
  			    not_in_quota);
  #endif
--- 247,258 ----
  
  #ifdef KEY_ALLOC_NEEDS_STRUCT_TASK
  	keyring = key_alloc(__key_type_keyring, desc,
! 			    task_uid(task), task_gid(task), task,
  			    (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
  			    not_in_quota);
  #else
  	keyring = key_alloc(__key_type_keyring, desc,
! 			    task_uid(task), task_gid(task),
  			    (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
  			    not_in_quota);
  #endif
***************
*** 270,278 ****
  
      /* install the keyring */
      spin_lock_irq(&task->sighand->siglock);
!     old = task->signal->session_keyring;
      smp_wmb();
!     task->signal->session_keyring = keyring;
      spin_unlock_irq(&task->sighand->siglock);
  
      if (old)
--- 270,278 ----
  
      /* install the keyring */
      spin_lock_irq(&task->sighand->siglock);
!     old = task_session_keyring(task);
      smp_wmb();
!     task_session_keyring(task) = keyring;
      spin_unlock_irq(&task->sighand->siglock);
  
      if (old)
***************
*** 337,343 ****
      if (code == 0 && (*cr)->cr_rgid != NFSXLATOR_CRED) {
  	(void) install_session_keyring(current, NULL);
  
! 	if (current->signal->session_keyring) {
  	    struct key *key;
  	    key_perm_t perm;
  
--- 337,343 ----
      if (code == 0 && (*cr)->cr_rgid != NFSXLATOR_CRED) {
  	(void) install_session_keyring(current, NULL);
  
! 	if (current_session_keyring()) {
  	    struct key *key;
  	    key_perm_t perm;
  
***************
*** 352,358 ****
  
  	    if (!IS_ERR(key)) {
  		key_instantiate_and_link(key, (void *) newpag, sizeof(afs_uint32),
! 					 current->signal->session_keyring, NULL);
  		key_put(key);
  	    }
  	}
--- 352,358 ----
  
  	    if (!IS_ERR(key)) {
  		key_instantiate_and_link(key, (void *) newpag, sizeof(afs_uint32),
! 					 current_session_keyring(), NULL);
  		key_put(key);
  	    }
  	}
***************
*** 549,574 ****
  {
      int code;
      afs_uint32 *userpag, pag = NOPAG;
      int g0, g1;
  
      if (key->uid != 0 || key->gid != 0)
  	return -EPERM;
  
      code = -EINVAL;
!     get_group_info(current->group_info);
  
      if (datalen != sizeof(afs_uint32) || !data)
  	goto error;
  
!     if (current->group_info->ngroups < NUMPAGGROUPS)
  	goto error;
  
      /* ensure key being set matches current pag */
  #ifdef AFS_LINUX26_ONEGROUP_ENV
!     pag = afs_get_pag_from_groups(current->group_info);
  #else
!     g0 = GROUP_AT(current->group_info, 0);
!     g1 = GROUP_AT(current->group_info, 1);
  
      pag = afs_get_pag_from_groups(g0, g1);
  #endif
--- 549,576 ----
  {
      int code;
      afs_uint32 *userpag, pag = NOPAG;
+ #ifndef AFS_LINUX26_ONEGROUP_ENV
      int g0, g1;
+ #endif
  
      if (key->uid != 0 || key->gid != 0)
  	return -EPERM;
  
      code = -EINVAL;
!     get_group_info(current_group_info());
  
      if (datalen != sizeof(afs_uint32) || !data)
  	goto error;
  
!     if (current_group_info()->ngroups < NUMPAGGROUPS)
  	goto error;
  
      /* ensure key being set matches current pag */
  #ifdef AFS_LINUX26_ONEGROUP_ENV
!     pag = afs_get_pag_from_groups(current_group_info());
  #else
!     g0 = GROUP_AT(current_group_info(), 0);
!     g1 = GROUP_AT(current_group_info(), 1);
  
      pag = afs_get_pag_from_groups(g0, g1);
  #endif
***************
*** 584,590 ****
      code = 0;
  
  error:
!     put_group_info(current->group_info);
      return code;
  }
  
--- 586,592 ----
      code = 0;
  
  error:
!     put_group_info(current_group_info());
      return code;
  }
  
***************
*** 651,658 ****
  #else
  	p = find_task_by_vpid(1);
  #endif
! 	if (p && p->user->session_keyring)
! 	    __key_type_keyring = p->user->session_keyring->type;
  # ifdef EXPORTED_TASKLIST_LOCK
  	if (&tasklist_lock)
  	    read_unlock(&tasklist_lock);
--- 653,660 ----
  #else
  	p = find_task_by_vpid(1);
  #endif
! 	if (p && task_user(p)->session_keyring)
! 	    __key_type_keyring = task_user(p)->session_keyring->type;
  # ifdef EXPORTED_TASKLIST_LOCK
  	if (&tasklist_lock)
  	    read_unlock(&tasklist_lock);
Index: openafs/src/afs/LINUX/osi_machdep.h
diff -c openafs/src/afs/LINUX/osi_machdep.h:1.34.2.6 openafs/src/afs/LINUX/osi_machdep.h:1.34.2.7
*** openafs/src/afs/LINUX/osi_machdep.h:1.34.2.6	Fri Nov 23 08:40:47 2007
--- openafs/src/afs/LINUX/osi_machdep.h	Thu Jan 15 08:27:29 2009
***************
*** 155,161 ****
  #endif
  
  /* cred struct */
! typedef struct cred {		/* maps to task field: */
      int cr_ref;
      uid_t cr_uid;		/* euid */
      uid_t cr_ruid;		/* uid */
--- 155,161 ----
  #endif
  
  /* cred struct */
! typedef struct afs_cred {		/* maps to task field: */
      int cr_ref;
      uid_t cr_uid;		/* euid */
      uid_t cr_ruid;		/* uid */
***************
*** 167,176 ****
      gid_t cr_groups[NGROUPS];	/* 32 groups - empty set to NOGROUP */
      int cr_ngroups;
  #endif
!     struct cred *cr_next;
  } cred_t;
! #define AFS_UCRED cred
  #define AFS_PROC struct task_struct
  #define crhold(c) (c)->cr_ref++
  
  /* UIO manipulation */
--- 167,200 ----
      gid_t cr_groups[NGROUPS];	/* 32 groups - empty set to NOGROUP */
      int cr_ngroups;
  #endif
!     struct afs_cred *cr_next;
  } cred_t;
! #define AFS_UCRED afs_cred
  #define AFS_PROC struct task_struct
+ #if !defined(current_cred)
+ #define current_gid() (current->gid)
+ #define current_uid() (current->uid)
+ #define current_fsgid() (current->fsgid)
+ #define current_fsuid() (current->fsuid)
+ #endif
+ #if defined(STRUCT_TASK_HAS_CRED)
+ #define current_group_info() (current->cred->group_info)
+ #define task_gid(task) (task->cred->gid)
+ #define task_user(task) (task->cred->user)
+ #define task_session_keyring(task) (task->cred->tgcred->session_keyring)
+ #define current_session_keyring() (current->cred->tgcred->session_keyring)
+ #else
+ #define current_group_info() (current->group_info)
+ #if !defined(task_gid)
+ #define task_gid(task) (task->gid)
+ #endif
+ #if !defined(task_uid)
+ #define task_uid(task) (task->uid)
+ #endif
+ #define task_user(task) (task->user)
+ #define task_session_keyring(task) (task->signal->session_keyring)
+ #define current_session_keyring() (current->signal->session_keyring)
+ #endif
  #define crhold(c) (c)->cr_ref++
  
  /* UIO manipulation */
Index: openafs/src/afs/LINUX/osi_probe.c
diff -c openafs/src/afs/LINUX/osi_probe.c:1.11.2.15 openafs/src/afs/LINUX/osi_probe.c:1.11.2.16
*** openafs/src/afs/LINUX/osi_probe.c:1.11.2.15	Thu Jul  3 16:33:12 2008
--- openafs/src/afs/LINUX/osi_probe.c	Thu Jan 15 08:13:09 2009
***************
*** 1210,1223 ****
      if (probe_debug & 0x0001) {                                                              \
  	printk("<7>osi_probe: %s = 0x%016lx %s\n", P->symbol, (unsigned long)(x), (m)); \
      }                                                                                      \
!     if ((x)) {                                                                             \
  	*method = (m);                                                                     \
          final_answer = (void *)(x);                                                        \
      }                                                                                      \
  } while (0)
  #else
  #define check_result(x,m) do {  \
!     if ((x)) {                  \
          *method = (m);          \
          return (void *)(x);     \
      }                           \
--- 1210,1223 ----
      if (probe_debug & 0x0001) {                                                              \
  	printk("<7>osi_probe: %s = 0x%016lx %s\n", P->symbol, (unsigned long)(x), (m)); \
      }                                                                                      \
!     if ((x) && ((int)(x)) != -ENOENT) {                                                    \
  	*method = (m);                                                                     \
          final_answer = (void *)(x);                                                        \
      }                                                                                      \
  } while (0)
  #else
  #define check_result(x,m) do {  \
!     if ((x) && ((int)(x)) != -ENOENT) { \
          *method = (m);          \
          return (void *)(x);     \
      }                           \
Index: openafs/src/afs/LINUX/osi_vfs.hin
diff -c openafs/src/afs/LINUX/osi_vfs.hin:1.8 openafs/src/afs/LINUX/osi_vfs.hin:1.8.4.1
*** openafs/src/afs/LINUX/osi_vfs.hin:1.8	Mon Jul 11 14:45:51 2005
--- openafs/src/afs/LINUX/osi_vfs.hin	Fri Jan  9 09:57:36 2009
***************
*** 78,81 ****
--- 78,86 ----
  
  #define VATTR_NULL(A) memset(A, 0, sizeof(struct vattr))
  
+ #ifndef HAVE_LINUX_I_SIZE_READ
+ #define i_size_read(X) ((X)->i_size)
+ #define i_size_write(X,Y) (X)->i_size = Y
+ #endif
+ 
  #endif /* OSI_VFS_H_ */
Index: openafs/src/afs/LINUX/osi_vfsops.c
diff -c openafs/src/afs/LINUX/osi_vfsops.c:1.42.4.23 openafs/src/afs/LINUX/osi_vfsops.c:1.42.4.25
*** openafs/src/afs/LINUX/osi_vfsops.c:1.42.4.23	Sat Nov  8 11:14:01 2008
--- openafs/src/afs/LINUX/osi_vfsops.c	Fri Jan  9 10:09:24 2009
***************
*** 16,22 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_vfsops.c,v 1.42.4.23 2008/11/08 16:14:01 shadow 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.25 2009/01/09 15:09:24 shadow Exp $");
  
  #define __NO_VERSION__		/* don't define kernel_version in module.h */
  #include <linux/module.h> /* early to avoid printf->printk mapping */
***************
*** 545,551 ****
      ip->i_mode = vp->va_mode;
      ip->i_uid = vp->va_uid;
      ip->i_gid = vp->va_gid;
!     ip->i_size = vp->va_size;
  #if defined(AFS_LINUX26_ENV)
      ip->i_atime.tv_sec = vp->va_atime.tv_sec;
      ip->i_atime.tv_nsec = 0;
--- 545,551 ----
      ip->i_mode = vp->va_mode;
      ip->i_uid = vp->va_uid;
      ip->i_gid = vp->va_gid;
!     i_size_write(ip, vp->va_size);
  #if defined(AFS_LINUX26_ENV)
      ip->i_atime.tv_sec = vp->va_atime.tv_sec;
      ip->i_atime.tv_nsec = 0;
Index: openafs/src/afs/LINUX/osi_vnodeops.c
diff -c openafs/src/afs/LINUX/osi_vnodeops.c:1.126.2.40 openafs/src/afs/LINUX/osi_vnodeops.c:1.126.2.45
*** openafs/src/afs/LINUX/osi_vnodeops.c:1.126.2.40	Sun Nov 30 15:06:52 2008
--- openafs/src/afs/LINUX/osi_vnodeops.c	Wed Jan 21 16:33:43 2009
***************
*** 22,28 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_vnodeops.c,v 1.126.2.40 2008/11/30 20:06:52 shadow Exp $");
  
  #include "afs/sysincludes.h"
  #include "afsincludes.h"
--- 22,28 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_vnodeops.c,v 1.126.2.45 2009/01/21 21:33:43 shadow Exp $");
  
  #include "afs/sysincludes.h"
  #include "afsincludes.h"
***************
*** 662,681 ****
  				&treq,
  				AFS_SYNC | AFS_LASTSTORE);
  	} else {
! #if defined(AFS_DISCON_ENV)
! 		if (!vcp->ddirty_flags ||
! 		    (vcp->ddirty_flags == VDisconShadowed)) {
! 
! 		    ObtainWriteLock(&afs_DDirtyVCListLock, 710);
! 		    AFS_DISCON_ADD_DIRTY(vcp, 1);
! 		    ReleaseWriteLock(&afs_DDirtyVCListLock);
! 		}
! 
! 		/* Set disconnected write flag. */
! 		vcp->ddirty_flags |= VDisconWriteOsiFlush;
! #endif
  	}
- 
  	ConvertWToSLock(&vcp->lock);
      }
      code = afs_CheckCode(code, &treq, 54);
--- 662,669 ----
  				&treq,
  				AFS_SYNC | AFS_LASTSTORE);
  	} else {
! 		afs_DisconAddDirty(vcp, VDisconWriteOsiFlush, 1);
  	}
  	ConvertWToSLock(&vcp->lock);
      }
      code = afs_CheckCode(code, &treq, 54);
***************
*** 1011,1017 ****
      struct vcache *vcp = VTOAFS(ip);
  
      AFS_GLOCK();
!     (void) afs_InactiveVCache(vcp, NULL);
      AFS_GUNLOCK();
  #ifdef DCACHE_NFSFS_RENAMED
  #ifdef AFS_LINUX26_ENV
--- 999,1007 ----
      struct vcache *vcp = VTOAFS(ip);
  
      AFS_GLOCK();
!     if (!AFS_IS_DISCONNECTED || (vcp->states & CUnlinked)) {
! 	(void) afs_InactiveVCache(vcp, NULL);
!     }
      AFS_GUNLOCK();
  #ifdef DCACHE_NFSFS_RENAMED
  #ifdef AFS_LINUX26_ENV
***************
*** 1799,1804 ****
--- 1789,1795 ----
  	 maybe_lock_kernel();
  #endif
  	 AFS_GLOCK();
+ 	 AFS_DISCON_LOCK();
  	 afs_Trace4(afs_iclSetp, CM_TRACE_READPAGE, ICL_TYPE_POINTER, ip, ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, cnt, ICL_TYPE_INT32, 99999);	/* not a possible code value */
  
  	 code = afs_rdwr(avc, auio, UIO_READ, 0, credp);
***************
*** 1806,1811 ****
--- 1797,1803 ----
  	 afs_Trace4(afs_iclSetp, CM_TRACE_READPAGE, ICL_TYPE_POINTER, ip,
  				ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, cnt, ICL_TYPE_INT32,
  				code);
+ 	 AFS_DISCON_UNLOCK();
  	 AFS_GUNLOCK();
  #ifdef AFS_LINUX24_ENV
  	 maybe_unlock_kernel();
***************
*** 1918,1924 ****
  
      code = afs_write(vcp, &tuio, f_flags, credp, 0);
  
!     ip->i_size = vcp->m.Length;
      ip->i_blocks = ((vcp->m.Length + 1023) >> 10) << 1;
  
      if (!code) {
--- 1910,1916 ----
  
      code = afs_write(vcp, &tuio, f_flags, credp, 0);
  
!     i_size_write(ip, vcp->m.Length);
      ip->i_blocks = ((vcp->m.Length + 1023) >> 10) << 1;
  
      if (!code) {
***************
*** 1972,1984 ****
  #endif
  
      inode = (struct inode *)mapping->host;
!     end_index = inode->i_size >> PAGE_CACHE_SHIFT;
  
      /* easy case */
      if (pp->index < end_index)
  	goto do_it;
      /* things got complicated... */
!     offset = inode->i_size & (PAGE_CACHE_SIZE - 1);
      /* OK, are we completely out? */
      if (pp->index >= end_index + 1 || !offset)
  	return -EIO;
--- 1964,1976 ----
  #endif
  
      inode = (struct inode *)mapping->host;
!     end_index = i_size_read(inode) >> PAGE_CACHE_SHIFT;
  
      /* easy case */
      if (pp->index < end_index)
  	goto do_it;
      /* things got complicated... */
!     offset = i_size_read(inode) & (PAGE_CACHE_SIZE - 1);
      /* OK, are we completely out? */
      if (pp->index >= end_index + 1 || !offset)
  	return -EIO;
***************
*** 2012,2017 ****
--- 2004,2010 ----
  
      credp = crref();
      AFS_GLOCK();
+     AFS_DISCON_LOCK();
      afs_Trace4(afs_iclSetp, CM_TRACE_UPDATEPAGE, ICL_TYPE_POINTER, vcp,
  	       ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, page_count(pp),
  	       ICL_TYPE_INT32, 99999);
***************
*** 2021,2027 ****
  
      code = afs_write(vcp, &tuio, fp->f_flags, credp, 0);
  
!     ip->i_size = vcp->m.Length;
      ip->i_blocks = ((vcp->m.Length + 1023) >> 10) << 1;
  
      if (!code) {
--- 2014,2020 ----
  
      code = afs_write(vcp, &tuio, fp->f_flags, credp, 0);
  
!     i_size_write(ip, vcp->m.Length);
      ip->i_blocks = ((vcp->m.Length + 1023) >> 10) << 1;
  
      if (!code) {
***************
*** 2039,2044 ****
--- 2032,2038 ----
  	       ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, page_count(pp),
  	       ICL_TYPE_INT32, code);
  
+     AFS_DISCON_UNLOCK();
      AFS_GUNLOCK();
      crfree(credp);
  
***************
*** 2128,2134 ****
--- 2122,2132 ----
  {
      struct page *page;
      pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+ #if defined(HAVE_GRAB_CACHE_PAGE_WRITE_BEGIN)
+     page = grab_cache_page_write_begin(mapping, index, flags);
+ #else
      page = __grab_cache_page(mapping, index);
+ #endif
      *pagep = page;
  
      return 0;
***************
*** 2266,2272 ****
--- 2264,2272 ----
      if (vattr)
  	vattr2inode(ip, vattr);
  
+ #if defined(AFS_LINUX26_ENV)
      ip->i_mapping->backing_dev_info = &afs_backing_dev_info;
+ #endif
  /* Reset ops if symlink or directory. */
      if (S_ISREG(ip->i_mode)) {
  	ip->i_op = &afs_file_iops;
Index: openafs/src/afs/OBSD/osi_groups.c
diff -c openafs/src/afs/OBSD/osi_groups.c:1.6 openafs/src/afs/OBSD/osi_groups.c:1.6.2.1
*** openafs/src/afs/OBSD/osi_groups.c:1.6	Mon Mar 13 11:26:27 2006
--- openafs/src/afs/OBSD/osi_groups.c	Thu Jan 22 16:29:08 2009
***************
*** 19,25 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/OBSD/osi_groups.c,v 1.6 2006/03/13 16:26:27 rees Exp $");
  
  #include "afs/sysincludes.h"
  #include "afs/afsincludes.h"
--- 19,25 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/OBSD/osi_groups.c,v 1.6.2.1 2009/01/22 21:29:08 shadow Exp $");
  
  #include "afs/sysincludes.h"
  #include "afs/afsincludes.h"
***************
*** 47,56 ****
      struct vrequest treq;
  
      AFS_STATCNT(afs_xsetgroups);
!     AFS_GLOCKP(p);
  
      code = afs_InitReq(&treq, p->p_rcred);
!     AFS_GUNLOCKP(p);
      if (code)
  	return code;
  
--- 47,58 ----
      struct vrequest treq;
  
      AFS_STATCNT(afs_xsetgroups);
!     AFS_GLOCK();
! 
!     p = osi_curproc();
  
      code = afs_InitReq(&treq, p->p_rcred);
!     AFS_GUNLOCK();
      if (code)
  	return code;
  
***************
*** 61,70 ****
       */
      if (PagInCred(p->p_rcred) == NOPAG) {
  	if (((treq.uid >> 24) & 0xff) == 'A') {
! 	    AFS_GLOCKP(p);
  	    /* we've already done a setpag, so now we redo it */
  	    AddPag(p, treq.uid, &p->p_rcred);
! 	    AFS_GUNLOCKP(p);
  	}
      }
      return code;
--- 63,72 ----
       */
      if (PagInCred(p->p_rcred) == NOPAG) {
  	if (((treq.uid >> 24) & 0xff) == 'A') {
! 	    AFS_GLOCK();
  	    /* we've already done a setpag, so now we redo it */
  	    AddPag(p, treq.uid, &p->p_rcred);
! 	    AFS_GUNLOCK();
  	}
      }
      return code;
Index: openafs/src/afs/OBSD/osi_machdep.h
diff -c openafs/src/afs/OBSD/osi_machdep.h:1.27.2.1 openafs/src/afs/OBSD/osi_machdep.h:1.27.2.2
*** openafs/src/afs/OBSD/osi_machdep.h:1.27.2.1	Thu Nov  9 19:11:07 2006
--- openafs/src/afs/OBSD/osi_machdep.h	Thu Jan 22 16:29:08 2009
***************
*** 16,22 ****
   * afs_osi.h.
   */
  
! /* $Id: osi_machdep.h,v 1.27.2.1 2006/11/10 00:11:07 shadow Exp $ */
  
  #ifndef _OSI_MACHDEP_H_
  #define _OSI_MACHDEP_H_
--- 16,22 ----
   * afs_osi.h.
   */
  
! /* $Id: osi_machdep.h,v 1.27.2.2 2009/01/22 21:29:08 shadow Exp $ */
  
  #ifndef _OSI_MACHDEP_H_
  #define _OSI_MACHDEP_H_
***************
*** 54,61 ****
  #define AFS_UIOUSER	UIO_USERSPACE
  
  /* malloc */
! #define AFS_KALLOC(s)	afs_nbsd_Alloc(s)
! #define AFS_KFREE(p, s)	afs_nbsd_Free((p), (s))
  
  /* proc, cred */
  #define	AFS_PROC	struct proc
--- 54,90 ----
  #define AFS_UIOUSER	UIO_USERSPACE
  
  /* malloc */
! inline void afs_osi_Free(void *buf, size_t asize);
! inline void afs_osi_FreeStr(char *x);
! extern void *osi_obsd_Alloc(size_t asize, int cansleep);
! extern void osi_obsd_Free(void *p, size_t asize);
! 
! #define afs_osi_Alloc_NoSleep(asize) osi_obsd_Alloc((asize), 0)
! #define afs_osi_Alloc(asize) osi_obsd_Alloc((asize), 1)
! #define afs_osi_FreeStr(s) afs_osi_Free((s), strlen((s)) + 1)
! #define afs_osi_Free(buf, asize) osi_obsd_Free((buf), (asize))
! 
! #ifdef AFS_KALLOC
! #undef AFS_KALLOC
! #define AFS_KALLOC(s) osi_obsd_Alloc((s), 1 /* cansleep */)
! #endif
! 
! #ifdef AFS_KFREE
! #undef AFS_KFREE
! #define AFS_KFREE(p, s) (osi_obsd_Free((p), (s)))
! #endif
! 
! #ifdef AFS_OBSD42_ENV
! /* removed, live with it */
! #define BSD_KMALLOC(p, ptype, msize, mtype, mflags)     \
!   (p) = malloc((msize), (mtype), (mflags))
! 
! #define BSD_KFREE(p, mflags) \
!   free((p), (mflags))
! #else
! #define BSD_KMALLOC MALLOC
! #define BSD_KFREE KFREE
! #endif /* AFS_OBSD42_ENV */
  
  /* proc, cred */
  #define	AFS_PROC	struct proc
***************
*** 92,102 ****
  /* This is not always in scope yet */
  struct vcache;
  
! extern int afs_nbsd_lookupname(char *fnamep, enum uio_seg segflg,
  			       int followlink, struct vnode **compvpp);
! extern void afs_nbsd_getnewvnode(struct vcache *tvc);
! extern void *afs_nbsd_Alloc(size_t asize);
! extern void afs_nbsd_Free(void *p, size_t asize);
  extern int afs_vget();
  
  #undef gop_lookupname
--- 121,131 ----
  /* This is not always in scope yet */
  struct vcache;
  
! extern int afs_obsd_lookupname(char *fnamep, enum uio_seg segflg,
  			       int followlink, struct vnode **compvpp);
! extern void afs_obsd_getnewvnode(struct vcache *tvc);
! extern void *afs_obsd_Alloc(size_t asize);
! extern void afs_obsd_Free(void *p, size_t asize);
  extern int afs_vget();
  
  #undef gop_lookupname
***************
*** 111,116 ****
--- 140,188 ----
  
  #ifdef KERNEL
  
+ #ifdef AFS_OBSD44_ENV
+ /* Revert to classical, BSD locks */
+ 
+ extern struct lock afs_global_lock;
+ extern struct proc *afs_global_owner;
+ 
+ #ifdef AFS_GLOBAL_SUNLOCK
+ 
+ #if defined(LOCKDEBUG)
+ 
+ #define AFS_GLOCK() \
+   do { \
+   _lockmgr(&afs_global_lock, LK_EXCLUSIVE, NULL, __FILE__, __LINE__); \
+   } while(0);
+ #define AFS_GUNLOCK() \
+   do { \
+   _lockmgr(&afs_global_lock, LK_RELEASE, NULL, __FILE__, __LINE__); \
+   } while(0);
+ 
+ #else
+ 
+ #define AFS_GLOCK() \
+   do { \
+   lockmgr(&afs_global_lock, LK_EXCLUSIVE, NULL); \
+   } while(0);
+ #define AFS_GUNLOCK() \
+   do { \
+   lockmgr(&afs_global_lock, LK_RELEASE, NULL); \
+   } while(0);
+ #endif /* LOCKDEBUG */
+ #define ISAFS_GLOCK() (lockstatus(&afs_global_lock) == LK_EXCLUSIVE)
+ #else
+ extern struct lock afs_global_lock;
+ #define AFS_GLOCKP(p)
+ #define AFS_GUNLOCKP(p)
+ #define AFS_ASSERT_GLOCK()
+ #define ISAFS_GLOCK() 1
+ #endif
+ 
+ #else
+ /* I don't see doing locks this way for older kernels, either,
+  * but, smart folks wrote this
+  */
  #define AFS_GLOCK() AFS_GLOCKP(curproc)
  #define AFS_GUNLOCK() AFS_GUNLOCKP(curproc)
  #ifdef AFS_GLOBAL_SUNLOCK
***************
*** 139,144 ****
--- 211,218 ----
  #define ISAFS_GLOCK() 1
  #endif
  
+ #endif /* AFS_OBSD44_ENV */
+ 
  #undef SPLVAR
  #define SPLVAR int splvar
  #undef NETPRI
Index: openafs/src/afs/OBSD/osi_misc.c
diff -c openafs/src/afs/OBSD/osi_misc.c:1.4 openafs/src/afs/OBSD/osi_misc.c:1.4.14.1
*** openafs/src/afs/OBSD/osi_misc.c:1.4	Thu Oct  9 12:13:16 2003
--- openafs/src/afs/OBSD/osi_misc.c	Thu Jan 22 16:29:08 2009
***************
*** 1,7 ****
  /* 
   * osi_misc.c
   *
!  * $Id: osi_misc.c,v 1.4 2003/10/09 16:13:16 rees Exp $
   */
  
  /*
--- 1,7 ----
  /* 
   * osi_misc.c
   *
!  * $Id: osi_misc.c,v 1.4.14.1 2009/01/22 21:29:08 shadow Exp $
   */
  
  /*
***************
*** 47,56 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/OBSD/osi_misc.c,v 1.4 2003/10/09 16:13:16 rees Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afs/afsincludes.h"	/* Afs-based standard headers */
  
  /*
   * afs_suser() returns true if the caller is superuser, false otherwise.
--- 47,58 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/OBSD/osi_misc.c,v 1.4.14.1 2009/01/22 21:29:08 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afs/afsincludes.h"	/* Afs-based standard headers */
+ #include <sys/types.h>
+ #include <sys/malloc.h>
  
  /*
   * afs_suser() returns true if the caller is superuser, false otherwise.
***************
*** 74,93 ****
  #endif
  }
  
  void *
! afs_nbsd_Alloc(size_t asize)
  {
!     void *p;
  
      MALLOC(p, void *, asize, M_AFSGENERIC, M_WAITOK);
!     return p;
  }
  
  void
! afs_nbsd_Free(void *p, size_t asize)
  {
!     FREE(p, M_AFSGENERIC);
  }
  
  int
  afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, retval)
--- 76,169 ----
  #endif
  }
  
+ /*
+  * reworked for netbsd and openbsd at 4.0/4.4
+  */
+ 
+ #if defined(AFS_OBSD42_ENV)
+ /* ripped out MALLOC/FREE */
+ 
+ void *
+ osi_obsd_Alloc(size_t asize, int cansleep)
+ {
+   void *p;
+   int glocked;
+ 
+   if (cansleep) {
+     glocked = ISAFS_GLOCK();
+     if (glocked)
+       AFS_GUNLOCK();
+     p = malloc(asize, M_AFSGENERIC, M_WAITOK);
+     if (glocked)
+       AFS_GLOCK();
+   } else {
+     p = malloc(asize, M_AFSGENERIC, M_NOWAIT);
+   }
+ 
+   return (p);
+ }
+ 
+ void
+ osi_obsd_Free(void *p, size_t asize)
+ {
+   free(p, M_AFSGENERIC);
+ }
+ 
+ #else
  void *
! osi_obsd_Alloc(size_t asize, int cansleep)
  {
!   void *p;
!   int glocked;
  
+   if (cansleep) {
+     glocked = ISAFS_GLOCK();
+     if (glocked)
+       AFS_GUNLOCK();
      MALLOC(p, void *, asize, M_AFSGENERIC, M_WAITOK);
!     if (glocked)
!       AFS_GLOCK();
!   } else {
!     MALLOC(p, void *, asize, M_AFSGENERIC, M_NOWAIT);
!   }
! 
!   return (p);
  }
  
  void
! osi_obsd_Free(void *p, size_t asize)
  {
!   FREE(p, M_AFSGENERIC);
  }
+ #endif
+ 
+ #if 0 /* XXX */
+ /* I speculate this usage may be more correct than definitions
+  * in afs_osi_alloc.c, which I discarded successfully for FreeBSD 7+,
+  * and am trying to discard for NetBSD 4.x, but until tested, I'm
+  * not rocking the boat.  Matt.
+  */
+    
+ void
+ osi_FreeLargeSpace(void *p)
+ {
+   osi_obsd_Free(p, 0);
+ }
+ 
+ void
+ osi_FreeSmallSpace(void *p)
+ {
+   osi_obsd_Free(p, 0);
+ }
+ 
+ void *
+ osi_AllocLargeSpace(size_t size)
+ {
+   AFS_ASSERT_GLOCK();
+   AFS_STATCNT(osi_AllocLargeSpace);
+   return (osi_obsd_Alloc(size, 1));
+ }
+ #endif
  
  int
  afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, retval)
Index: openafs/src/afs/OBSD/osi_vnodeops.c
diff -c openafs/src/afs/OBSD/osi_vnodeops.c:1.20 openafs/src/afs/OBSD/osi_vnodeops.c:1.20.2.1
*** openafs/src/afs/OBSD/osi_vnodeops.c:1.20	Thu Mar  9 10:27:17 2006
--- openafs/src/afs/OBSD/osi_vnodeops.c	Thu Jan 22 16:29:08 2009
***************
*** 3,9 ****
   * Original NetBSD version for Transarc afs by John Kohl <jtk@MIT.EDU>
   * OpenBSD version by Jim Rees <rees@umich.edu>
   *
!  * $Id: osi_vnodeops.c,v 1.20 2006/03/09 15:27:17 rees Exp $
   */
  
  /*
--- 3,9 ----
   * Original NetBSD version for Transarc afs by John Kohl <jtk@MIT.EDU>
   * OpenBSD version by Jim Rees <rees@umich.edu>
   *
!  * $Id: osi_vnodeops.c,v 1.20.2.1 2009/01/22 21:29:08 shadow Exp $
   */
  
  /*
***************
*** 99,105 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/OBSD/osi_vnodeops.c,v 1.20 2006/03/09 15:27:17 rees Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afs/afsincludes.h"	/* Afs-based standard headers */
--- 99,105 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/OBSD/osi_vnodeops.c,v 1.20.2.1 2009/01/22 21:29:08 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afs/afsincludes.h"	/* Afs-based standard headers */
***************
*** 160,166 ****
--- 160,170 ----
  /* Global vfs data structures for AFS. */
  int (**afs_vnodeop_p) __P((void *));
  struct vnodeopv_entry_desc afs_vnodeop_entries[] = {
+ #ifdef AFS_OBSD44_ENV /* feel free to zero in on this */
+   {&vop_default_desc, eopnotsupp},
+ #else
      {&vop_default_desc, vn_default_error},
+ #endif
      {&vop_lookup_desc, afs_nbsd_lookup},	/* lookup */
      {&vop_create_desc, afs_nbsd_create},	/* create */
      {&vop_mknod_desc, afs_nbsd_mknod},		/* mknod */
***************
*** 207,217 ****
  #define GETNAME()	\
      struct componentname *cnp = ap->a_cnp; \
      char *name; \
!     MALLOC(name, char *, cnp->cn_namelen+1, M_TEMP, M_WAITOK); \
      bcopy(cnp->cn_nameptr, name, cnp->cn_namelen); \
      name[cnp->cn_namelen] = '\0'
  
! #define DROPNAME() FREE(name, M_TEMP)
  
  #ifdef AFS_OBSD36_ENV
  #define DROPCNP(cnp) pool_put(&namei_pool, (cnp)->cn_pnbuf)
--- 211,221 ----
  #define GETNAME()	\
      struct componentname *cnp = ap->a_cnp; \
      char *name; \
!     BSD_KMALLOC(name, char *, cnp->cn_namelen+1, M_TEMP, M_WAITOK); \
      bcopy(cnp->cn_nameptr, name, cnp->cn_namelen); \
      name[cnp->cn_namelen] = '\0'
  
! #define DROPNAME() BSD_KFREE(name, M_TEMP)
  
  #ifdef AFS_OBSD36_ENV
  #define DROPCNP(cnp) pool_put(&namei_pool, (cnp)->cn_pnbuf)
***************
*** 687,696 ****
      if ((code = vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curproc)))
  	goto abortit;
  
!     MALLOC(fname, char *, fcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
      bcopy(fcnp->cn_nameptr, fname, fcnp->cn_namelen);
      fname[fcnp->cn_namelen] = '\0';
!     MALLOC(tname, char *, tcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
      bcopy(tcnp->cn_nameptr, tname, tcnp->cn_namelen);
      tname[tcnp->cn_namelen] = '\0';
  
--- 691,700 ----
      if ((code = vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curproc)))
  	goto abortit;
  
!     BSD_KMALLOC(fname, char *, fcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
      bcopy(fcnp->cn_nameptr, fname, fcnp->cn_namelen);
      fname[fcnp->cn_namelen] = '\0';
!     BSD_KMALLOC(tname, char *, tcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
      bcopy(tcnp->cn_nameptr, tname, tcnp->cn_namelen);
      tname[tcnp->cn_namelen] = '\0';
  
***************
*** 702,709 ****
      AFS_GUNLOCK();
  
      VOP_UNLOCK(fvp, 0, curproc);
!     FREE(fname, M_TEMP);
!     FREE(tname, M_TEMP);
      if (code)
  	goto abortit;		/* XXX */
      if (tdvp == tvp)
--- 706,713 ----
      AFS_GUNLOCK();
  
      VOP_UNLOCK(fvp, 0, curproc);
!     BSD_KFREE(fname, M_TEMP);
!     BSD_KFREE(tname, M_TEMP);
      if (code)
  	goto abortit;		/* XXX */
      if (tdvp == tvp)
Index: openafs/src/afs/VNOPS/afs_vnop_access.c
diff -c openafs/src/afs/VNOPS/afs_vnop_access.c:1.11.8.8 openafs/src/afs/VNOPS/afs_vnop_access.c:1.11.8.9
*** openafs/src/afs/VNOPS/afs_vnop_access.c:1.11.8.8	Sat Nov 29 13:20:27 2008
--- openafs/src/afs/VNOPS/afs_vnop_access.c	Wed Jan 21 16:15:09 2009
***************
*** 23,29 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_access.c,v 1.11.8.8 2008/11/29 18:20:27 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 23,29 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_access.c,v 1.11.8.9 2009/01/21 21:15:09 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 90,95 ****
--- 90,100 ----
  	}
      }
  
+     if (AFS_IS_DISCONNECTED && !AFS_IN_SYNC) {
+ 	/* If we get this far, we have to ask the network. But we can't, so
+ 	 * they're out of luck... */
+ 	return 0;
+     } else
      {				/* Ok, user has valid tokens, go ask the server. */
  	struct AFSFetchStatus OutStatus;
  	afs_int32 code;
Index: openafs/src/afs/VNOPS/afs_vnop_attrs.c
diff -c openafs/src/afs/VNOPS/afs_vnop_attrs.c:1.41.2.5 openafs/src/afs/VNOPS/afs_vnop_attrs.c:1.41.2.8
*** openafs/src/afs/VNOPS/afs_vnop_attrs.c:1.41.2.5	Mon Dec 29 16:26:13 2008
--- openafs/src/afs/VNOPS/afs_vnop_attrs.c	Mon Jan 19 14:42:44 2009
***************
*** 24,30 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_attrs.c,v 1.41.2.5 2008/12/29 21:26:13 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 24,30 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_attrs.c,v 1.41.2.8 2009/01/19 19:42:44 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 545,551 ****
  	ObtainWriteLock(&avc->lock, 128);
  	avc->states |= CDirty;
  
! 	code = afs_TruncateAllSegments(avc, tsize, &treq, acred);
  	/* if date not explicitly set by this call, set it ourselves, since we
  	 * changed the data */
  	if (!(astat.Mask & AFS_SETMODTIME)) {
--- 545,564 ----
  	ObtainWriteLock(&avc->lock, 128);
  	avc->states |= CDirty;
  
!         if (AFS_IS_DISCONNECTED && tsize >=avc->m.Length) {
! 	    /* If we're growing the file, and we're disconnected, we need
!  	     * to make the relevant dcache chunks appear ourselves. */
! 	    code = afs_ExtendSegments(avc, tsize, &treq);
! 	} else {
! 	    code = afs_TruncateAllSegments(avc, tsize, &treq, acred);
! 	}
! #ifdef AFS_LINUX26_ENV
! 	/* We must update the Linux kernel's idea of file size as soon as
! 	 * possible, to avoid racing with delayed writepages delivered by
! 	 * pdflush */
! 	if (code == 0)
! 	    i_size_write(AFSTOV(avc), tsize);
! #endif
  	/* if date not explicitly set by this call, set it ourselves, since we
  	 * changed the data */
  	if (!(astat.Mask & AFS_SETMODTIME)) {
Index: openafs/src/afs/VNOPS/afs_vnop_create.c
diff -c openafs/src/afs/VNOPS/afs_vnop_create.c:1.23.4.9 openafs/src/afs/VNOPS/afs_vnop_create.c:1.23.4.11
*** openafs/src/afs/VNOPS/afs_vnop_create.c:1.23.4.9	Mon Dec 29 16:26:13 2008
--- openafs/src/afs/VNOPS/afs_vnop_create.c	Wed Jan 21 16:15:09 2009
***************
*** 17,23 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_create.c,v 1.23.4.9 2008/12/29 21:26:13 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 17,23 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_create.c,v 1.23.4.11 2009/01/21 21:15:09 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 45,51 ****
      afs_int32 origCBs, origZaps, finalZaps;
      struct vrequest treq;
      register afs_int32 code;
!     register struct conn *tc;
      struct VenusFid newFid;
      struct AFSStoreStatus InStatus;
      struct AFSFetchStatus OutFidStatus, OutDirStatus;
--- 45,51 ----
      afs_int32 origCBs, origZaps, finalZaps;
      struct vrequest treq;
      register afs_int32 code;
!     register struct afs_conn *tc;
      struct VenusFid newFid;
      struct AFSStoreStatus InStatus;
      struct AFSFetchStatus OutFidStatus, OutDirStatus;
***************
*** 393,398 ****
--- 393,401 ----
  	ReleaseWriteLock(&tdc->lock);
  	afs_PutDCache(tdc);
      }
+     if (AFS_IS_DISCON_RW)
+ 	adp->m.LinkCount++;
+ 
      newFid.Cell = adp->fid.Cell;
      newFid.Fid.Volume = adp->fid.Fid.Volume;
      ReleaseWriteLock(&adp->lock);
***************
*** 442,449 ****
  	    if (origCBs == finalCBs && origZaps == finalZaps) {
  		tvc->states |= CStatd;	/* we've fake entire thing, so don't stat */
  		tvc->states &= ~CBulkFetching;
! 		tvc->cbExpires = CallBack.ExpirationTime;
! 		afs_QueueCallback(tvc, CBHash(CallBack.ExpirationTime), volp);
  	    } else {
  		afs_DequeueCallback(tvc);
  		tvc->states &= ~(CStatd | CUnique);
--- 445,454 ----
  	    if (origCBs == finalCBs && origZaps == finalZaps) {
  		tvc->states |= CStatd;	/* we've fake entire thing, so don't stat */
  		tvc->states &= ~CBulkFetching;
! 		if (!AFS_IS_DISCON_RW) {
! 		    tvc->cbExpires = CallBack.ExpirationTime;
! 		    afs_QueueCallback(tvc, CBHash(CallBack.ExpirationTime), volp);
! 		}
  	    } else {
  		afs_DequeueCallback(tvc);
  		tvc->states &= ~(CStatd | CUnique);
***************
*** 452,487 ****
  		    osi_dnlc_purgedp(tvc);
  	    }
  	    ReleaseWriteLock(&afs_xcbhash);
! 	    if (!AFS_IS_DISCON_RW)
! 	    	afs_ProcessFS(tvc, &OutFidStatus, &treq);
  	    tvc->parentVnode = adp->fid.Fid.Vnode;
  	    tvc->parentUnique = adp->fid.Fid.Unique;
  	    ReleaseWriteLock(&tvc->lock);
  	    *avcp = tvc;
  	    code = 0;
- 
- 	    if (AFS_IS_DISCON_RW) {
- #if defined(AFS_DISCON_ENV)
- 	    	/* After tvc has been created, we can do various ops on it. */
- 		/* Add to dirty list. */
- 		if (!tvc->ddirty_flags ||
- 			(tvc->ddirty_flags == VDisconShadowed)) {
- 	    	    /* Put it in the list only if it's fresh. */
- 		    ObtainWriteLock(&afs_DDirtyVCListLock, 729);
- 	    	    AFS_DISCON_ADD_DIRTY(tvc, 0);
- 	    	    ReleaseWriteLock(&afs_DDirtyVCListLock);
- 		}
- 
- 		/* Set create flag. */
- 		ObtainWriteLock(&tvc->lock, 730);
- 		afs_GenDisconStatus(adp, tvc, &newFid, attrs, &treq, VREG);
- 		tvc->ddirty_flags |= VDisconCreate;
- 		ReleaseWriteLock(&tvc->lock);
- 
- #endif				/* #ifdef AFS_DISCON_ENV */
-     	    }			/* if (AFS_IS_DISCON_RW) */
- 
- 
  	} else
  	    code = ENOENT;
      } else {
--- 457,476 ----
  		    osi_dnlc_purgedp(tvc);
  	    }
  	    ReleaseWriteLock(&afs_xcbhash);
! 	    if (AFS_IS_DISCON_RW) {
! #if defined(AFS_DISCON_ENV)
! 		afs_DisconAddDirty(tvc, VDisconCreate, 0);
! 		afs_GenDisconStatus(adp, tvc, &newFid, attrs, &treq, VREG);
! #endif
! 	    } else {
! 		afs_ProcessFS(tvc, &OutFidStatus, &treq);
! 	    }
! 
  	    tvc->parentVnode = adp->fid.Fid.Vnode;
  	    tvc->parentUnique = adp->fid.Fid.Unique;
  	    ReleaseWriteLock(&tvc->lock);
  	    *avcp = tvc;
  	    code = 0;
  	} else
  	    code = ENOENT;
      } else {
Index: openafs/src/afs/VNOPS/afs_vnop_dirops.c
diff -c openafs/src/afs/VNOPS/afs_vnop_dirops.c:1.21.4.5 openafs/src/afs/VNOPS/afs_vnop_dirops.c:1.21.4.9
*** openafs/src/afs/VNOPS/afs_vnop_dirops.c:1.21.4.5	Sun Nov 30 15:06:53 2008
--- openafs/src/afs/VNOPS/afs_vnop_dirops.c	Thu Jan 22 15:11:56 2009
***************
*** 21,27 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_dirops.c,v 1.21.4.5 2008/11/30 20:06:53 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 21,27 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_dirops.c,v 1.21.4.9 2009/01/22 20:11:56 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 41,47 ****
  {
      struct vrequest treq;
      register afs_int32 code;
!     register struct conn *tc;
      struct VenusFid newFid;
      register struct dcache *tdc;
      struct dcache *new_dc;
--- 41,47 ----
  {
      struct vrequest treq;
      register afs_int32 code;
!     register struct afs_conn *tc;
      struct VenusFid newFid;
      register struct dcache *tdc;
      struct dcache *new_dc;
***************
*** 102,108 ****
      ObtainWriteLock(&adp->lock, 153);
  
      if (!AFS_IS_DISCON_RW) {
- 
      	do {
  	    tc = afs_Conn(&adp->fid, &treq, SHARED_LOCK);
  	    if (tc) {
--- 102,107 ----
***************
*** 195,201 ****
  	/* Generate a new vcache and fill it. */
  	tvc = afs_NewVCache(&newFid, NULL);
  	if (tvc) {
- 	    code = 0;
  	    *avcp = tvc;
  	} else {
  	    code = ENOENT;
--- 194,199 ----
***************
*** 218,243 ****
  	ObtainWriteLock(&afs_xdcache, 739);
  	code = afs_dir_MakeDir(new_dc,
  				(afs_int32 *) &newFid.Fid,
! 				(afs_int32) &adp->fid.Fid);
  	ReleaseWriteLock(&afs_xdcache);
  	if (code)
  	    printf("afs_mkdir: afs_dirMakeDir code = %u\n", code);
  
! 	/* Add to dirty list. */
! 	if (!tvc->ddirty_flags ||
! 		(tvc->ddirty_flags == VDisconShadowed)) {
! 
! 	    /* Put it in the list only if it's fresh. */
! 	    ObtainWriteLock(&afs_DDirtyVCListLock, 730);
! 	    AFS_DISCON_ADD_DIRTY(tvc, 1);
! 	    ReleaseWriteLock(&afs_DDirtyVCListLock);
! 	}
  
  	ObtainWriteLock(&tvc->lock, 731);
  	/* Update length in the vcache. */
  	tvc->m.Length = new_dc->f.chunkBytes;
- 	/* Set create flag. */
- 	tvc->ddirty_flags |= VDisconCreate;
  	ReleaseWriteLock(&tvc->lock);
  #endif				/* #ifdef AFS_DISCON_ENV */
      } else {
--- 216,232 ----
  	ObtainWriteLock(&afs_xdcache, 739);
  	code = afs_dir_MakeDir(new_dc,
  				(afs_int32 *) &newFid.Fid,
! 				(afs_int32 *) &adp->fid.Fid);
  	ReleaseWriteLock(&afs_xdcache);
  	if (code)
  	    printf("afs_mkdir: afs_dirMakeDir code = %u\n", code);
  
! 	afs_PutDCache(new_dc);
  
  	ObtainWriteLock(&tvc->lock, 731);
+ 	afs_DisconAddDirty(tvc, VDisconCreate, 1);
  	/* Update length in the vcache. */
  	tvc->m.Length = new_dc->f.chunkBytes;
  	ReleaseWriteLock(&tvc->lock);
  #endif				/* #ifdef AFS_DISCON_ENV */
      } else {
***************
*** 273,279 ****
      register struct dcache *tdc;
      register struct vcache *tvc = NULL;
      register afs_int32 code;
!     register struct conn *tc;
      afs_size_t offset, len;
      struct AFSFetchStatus OutDirStatus;
      struct AFSVolSync tsync;
--- 262,268 ----
      register struct dcache *tdc;
      register struct vcache *tvc = NULL;
      register afs_int32 code;
!     register struct afs_conn *tc;
      afs_size_t offset, len;
      struct AFSFetchStatus OutDirStatus;
      struct AFSVolSync tsync;
***************
*** 389,394 ****
--- 378,390 ----
  #if defined(AFS_DISCON_ENV)
      	/* Disconnected. */
  
+ 	if (!tdc) {
+ 	    ReleaseWriteLock(&adp->lock);
+ 	    printf("afs_rmdir: No local dcache!\n");
+ 	    code = ENETDOWN;
+ 	    goto done;
+ 	}
+ 	
  	if (!tvc) {
  	    /* Find the vcache. */
  	    struct VenusFid tfid;
***************
*** 400,412 ****
  	    ObtainSharedLock(&afs_xvcache, 764);
  	    tvc = afs_FindVCache(&tfid, 0, 1 /* do xstats */ );
  	    ReleaseSharedLock(&afs_xvcache);
! 
  	    if (!tvc) {
  		printf("afs_rmdir: Can't find dir's vcache!\n");
  		ReleaseSharedLock(&tdc->lock);
! 		afs_PutDCache(tdc);	/* drop ref count */
!     		ReleaseWriteLock(&adp->lock);
! 	    	goto done;
  	    }
  	}
  
--- 396,409 ----
  	    ObtainSharedLock(&afs_xvcache, 764);
  	    tvc = afs_FindVCache(&tfid, 0, 1 /* do xstats */ );
  	    ReleaseSharedLock(&afs_xvcache);
! 	    
  	    if (!tvc) {
  		printf("afs_rmdir: Can't find dir's vcache!\n");
  		ReleaseSharedLock(&tdc->lock);
! 	        afs_PutDCache(tdc);	/* drop ref count */
!     	        ReleaseWriteLock(&adp->lock);
! 		code = ENETDOWN;
! 	        goto done;
  	    }
  	}
  
***************
*** 415,452 ****
  	     * deleted.
  	     */
  	    ReleaseSharedLock(&tdc->lock);
  	    code = ENOTEMPTY;
  	    goto done;
  	}
  
      	/* Make a shadow copy of the parent dir (if not done already).
! 	 * There's no need to make a shadow copy of the deleted directory
! 	 * because a dir must be empty in order to be rmdir'ed.
! 	 * If the deleted dir has no shadow, it means that it was empty.
  	 */
! 	if (!(adp->ddirty_flags & VDisconShadowed)) {
! 	    /* If tdc available, then it is locked.
! 	     * afs_MakeShadowDir unlocks it.
! 	     */
! 	    if (tdc)
! 	    	ReleaseSharedLock(&tdc->lock);
! 	    afs_MakeShadowDir(adp);
! 	    if (tdc)
! 	    	ObtainSharedLock(&tdc->lock, 732);
! 	}
! 
! 	if (!tvc->ddirty_flags) {
! 	    /* Put it in the list only if it's fresh or has only been shadowed. */
! 	    ObtainWriteLock(&afs_DDirtyVCListLock, 728);
! 	    AFS_DISCON_ADD_DIRTY(tvc, 1);
! 	    ReleaseWriteLock(&afs_DDirtyVCListLock);
  	}
  
- 	/* Now add the vcache to the dirty list. */
- 	ObtainWriteLock(&tvc->lock, 727);
- 	tvc->ddirty_flags |= VDisconRemove;
- 	ReleaseWriteLock(&tvc->lock);
- 
  	adp->m.LinkCount--;
  #endif				/* #ifdef AFS_DISCON_ENV */
      }				/* if (!AFS_IS_DISCON_RW) */
--- 412,432 ----
  	     * deleted.
  	     */
  	    ReleaseSharedLock(&tdc->lock);
+ 	    afs_PutDCache(tdc);
+ 	    afs_PutVCache(tvc);
+ 	    ReleaseWriteLock(&adp->lock);
  	    code = ENOTEMPTY;
  	    goto done;
  	}
  
      	/* Make a shadow copy of the parent dir (if not done already).
! 	 * If we were created locally, then we don't need to have a shadow
! 	 * directory (as there's no server state to remember)
  	 */
! 	if (!adp->shVnode && !(adp->ddirty_flags & VDisconCreate)) {
! 	    afs_MakeShadowDir(adp, tdc);
  	}
  
  	adp->m.LinkCount--;
  #endif				/* #ifdef AFS_DISCON_ENV */
      }				/* if (!AFS_IS_DISCON_RW) */
***************
*** 466,472 ****
  	afs_PutDCache(tdc);	/* drop ref count */
      }
  
- 
      if (tvc)
  	osi_dnlc_purgedp(tvc);	/* get rid of any entries for this directory */
      else
--- 446,451 ----
***************
*** 475,480 ****
--- 454,470 ----
      if (tvc) {
  	ObtainWriteLock(&tvc->lock, 155);
  	tvc->states &= ~CUnique;	/* For the dfs xlator */
+ #if AFS_DISCON_ENV
+ 	if (AFS_IS_DISCON_RW) {
+ 	    if (tvc->ddirty_flags & VDisconCreate) {
+ 		/* If we we were created whilst disconnected, removal doesn't
+ 		 * need to get logged. Just go away gracefully */
+ 		afs_DisconRemoveDirty(tvc);
+ 	    } else {
+ 		afs_DisconAddDirty(tvc, VDisconRemove, 1);
+ 	    }
+ 	}
+ #endif
  	ReleaseWriteLock(&tvc->lock);
  	afs_PutVCache(tvc);
      }
Index: openafs/src/afs/VNOPS/afs_vnop_flock.c
diff -c openafs/src/afs/VNOPS/afs_vnop_flock.c:1.29.2.6 openafs/src/afs/VNOPS/afs_vnop_flock.c:1.29.2.7
*** openafs/src/afs/VNOPS/afs_vnop_flock.c:1.29.2.6	Fri May 23 10:25:16 2008
--- openafs/src/afs/VNOPS/afs_vnop_flock.c	Wed Jan 21 15:07:49 2009
***************
*** 16,22 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_flock.c,v 1.29.2.6 2008/05/23 14:25:16 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 16,22 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_flock.c,v 1.29.2.7 2009/01/21 20:07:49 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 228,234 ****
  HandleFlock(register struct vcache *avc, int acom, struct vrequest *areq,
  	    pid_t clid, int onlymine)
  {
!     struct conn *tc;
      struct SimpleLocks *slp, *tlp, **slpp;
      afs_int32 code;
      struct AFSVolSync tsync;
--- 228,234 ----
  HandleFlock(register struct vcache *avc, int acom, struct vrequest *areq,
  	    pid_t clid, int onlymine)
  {
!     struct afs_conn *tc;
      struct SimpleLocks *slp, *tlp, **slpp;
      afs_int32 code;
      struct AFSVolSync tsync;
***************
*** 828,834 ****
  static int
  GetFlockCount(struct vcache *avc, struct vrequest *areq)
  {
!     register struct conn *tc;
      register afs_int32 code;
      struct AFSFetchStatus OutStatus;
      struct AFSCallBack CallBack;
--- 828,834 ----
  static int
  GetFlockCount(struct vcache *avc, struct vrequest *areq)
  {
!     register struct afs_conn *tc;
      register afs_int32 code;
      struct AFSFetchStatus OutStatus;
      struct AFSCallBack CallBack;
Index: openafs/src/afs/VNOPS/afs_vnop_link.c
diff -c openafs/src/afs/VNOPS/afs_vnop_link.c:1.19.8.3 openafs/src/afs/VNOPS/afs_vnop_link.c:1.19.8.5
*** openafs/src/afs/VNOPS/afs_vnop_link.c:1.19.8.3	Sat Nov 29 13:20:27 2008
--- openafs/src/afs/VNOPS/afs_vnop_link.c	Wed Jan 21 16:15:09 2009
***************
*** 17,23 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_link.c,v 1.19.8.3 2008/11/29 18:20:27 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 17,23 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_link.c,v 1.19.8.5 2009/01/21 21:15:09 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 43,49 ****
      struct vrequest treq;
      register struct dcache *tdc;
      register afs_int32 code;
!     register struct conn *tc;
      afs_size_t offset, len;
      struct AFSFetchStatus OutFidStatus, OutDirStatus;
      struct AFSVolSync tsync;
--- 43,49 ----
      struct vrequest treq;
      register struct dcache *tdc;
      register afs_int32 code;
!     register struct afs_conn *tc;
      afs_size_t offset, len;
      struct AFSFetchStatus OutFidStatus, OutDirStatus;
      struct AFSVolSync tsync;
***************
*** 91,97 ****
  	goto done;
      }
      
!     if (AFS_IS_DISCONNECTED && !AFS_IS_LOGGING) {
          code = ENETDOWN;
          goto done;
      }
--- 91,97 ----
  	goto done;
      }
      
!     if (AFS_IS_DISCONNECTED) {
          code = ENETDOWN;
          goto done;
      }
Index: openafs/src/afs/VNOPS/afs_vnop_lookup.c
diff -c openafs/src/afs/VNOPS/afs_vnop_lookup.c:1.72.2.10 openafs/src/afs/VNOPS/afs_vnop_lookup.c:1.72.2.11
*** openafs/src/afs/VNOPS/afs_vnop_lookup.c:1.72.2.10	Mon Oct 27 19:41:43 2008
--- openafs/src/afs/VNOPS/afs_vnop_lookup.c	Wed Jan 21 15:07:49 2009
***************
*** 18,24 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_lookup.c,v 1.72.2.10 2008/10/27 23:41:43 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 18,24 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_lookup.c,v 1.72.2.11 2009/01/21 20:07:49 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 648,654 ****
      AFSCBFids fidParm;		/* file ID parm for bulk stat */
      AFSBulkStats statParm;	/* stat info parm for bulk stat */
      int fidIndex = 0;		/* which file were stating */
!     struct conn *tcp = 0;	/* conn for call */
      AFSCBs cbParm;		/* callback parm for bulk stat */
      struct server *hostp = 0;	/* host we got callback from */
      long startTime;		/* time we started the call,
--- 648,654 ----
      AFSCBFids fidParm;		/* file ID parm for bulk stat */
      AFSBulkStats statParm;	/* stat info parm for bulk stat */
      int fidIndex = 0;		/* which file were stating */
!     struct afs_conn *tcp = 0;	/* conn for call */
      AFSCBs cbParm;		/* callback parm for bulk stat */
      struct server *hostp = 0;	/* host we got callback from */
      long startTime;		/* time we started the call,
Index: openafs/src/afs/VNOPS/afs_vnop_remove.c
diff -c openafs/src/afs/VNOPS/afs_vnop_remove.c:1.52.2.8 openafs/src/afs/VNOPS/afs_vnop_remove.c:1.52.2.11
*** openafs/src/afs/VNOPS/afs_vnop_remove.c:1.52.2.8	Sun Nov 30 15:06:53 2008
--- openafs/src/afs/VNOPS/afs_vnop_remove.c	Wed Jan 21 16:18:03 2009
***************
*** 21,27 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_remove.c,v 1.52.2.8 2008/11/30 20:06:53 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 21,27 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_remove.c,v 1.52.2.11 2009/01/21 21:18:03 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 102,108 ****
  	  struct vrequest *treqp)
  {
      register afs_int32 code = 0;
!     register struct conn *tc;
      struct AFSFetchStatus OutDirStatus;
      struct AFSVolSync tsync;
      XSTATS_DECLS;
--- 102,108 ----
  	  struct vrequest *treqp)
  {
      register afs_int32 code = 0;
!     register struct afs_conn *tc;
      struct AFSFetchStatus OutDirStatus;
      struct AFSVolSync tsync;
      XSTATS_DECLS;
***************
*** 313,323 ****
      
      tdc = afs_GetDCache(adp, (afs_size_t) 0, &treq, &offset, &len, 1);	/* test for error below */
      ObtainWriteLock(&adp->lock, 142);
- #if defined(AFS_DISCON_ENV)
-     if (AFS_IS_DISCON_RW && !(adp->ddirty_flags & VDisconShadowed))
- 	/* Make shadow copy of parent dir. */
-     	afs_MakeShadowDir(adp);
- #endif
      if (tdc)
  	ObtainSharedLock(&tdc->lock, 638);
  
--- 313,318 ----
***************
*** 364,387 ****
  
  #if defined(AFS_DISCON_ENV)
      if (AFS_IS_DISCON_RW) {
! 	/* Add removed file vcache to dirty list. */
! 
! 	if (!tvc->ddirty_flags ||
! 		(tvc->ddirty_flags == VDisconShadowed)) {
! 	    /* Add to list only if fresh. */
! 	    ObtainWriteLock(&afs_DDirtyVCListLock, 725);
! 	    AFS_DISCON_ADD_DIRTY(tvc, 1);
! 	    ReleaseWriteLock(&afs_DDirtyVCListLock);
  	}
  
! 	ObtainWriteLock(&tvc->lock, 726);
! 	tvc->ddirty_flags |= VDisconRemove;
! 	ReleaseWriteLock(&tvc->lock);
  
! 	//ObtainWriteLock(&adp->lock, 751);
  	adp->m.LinkCount--;
! 	//ReleaseWriteLock(&adp->lock);
!     }
  #endif
  
      if (tvc && osi_Active(tvc)) {
--- 359,390 ----
  
  #if defined(AFS_DISCON_ENV)
      if (AFS_IS_DISCON_RW) {
! 	if (!adp->shVnode && !(adp->ddirty_flags & VDisconCreate)) {
!     	    /* Make shadow copy of parent dir. */
! 	    afs_MakeShadowDir(adp, tdc);
  	}
  
! 	/* Can't hold a dcache lock whilst we're getting a vcache one */
! 	if (tdc)
! 	    ReleaseSharedLock(&tdc->lock);
  
!         /* XXX - We're holding adp->lock still, and we've got no 
! 	 * guarantee about whether the ordering matches the lock hierarchy */
! 	ObtainWriteLock(&tvc->lock, 713);
! 
! 	/* If we were locally created, then we don't need to do very
! 	 * much beyond ensuring that we don't exist anymore */	
!     	if (tvc->ddirty_flags & VDisconCreate) {
! 	    afs_DisconRemoveDirty(tvc);
! 	} else {
! 	    /* Add removed file vcache to dirty list. */
! 	    afs_DisconAddDirty(tvc, VDisconRemove, 1);
!         }
  	adp->m.LinkCount--;
! 	ReleaseWriteLock(&tvc->lock);
! 	if (tdc)
! 	    ObtainSharedLock(&tdc->lock, 714);
!      }
  #endif
  
      if (tvc && osi_Active(tvc)) {
***************
*** 448,458 ****
  	}
  	if (tdc)
  	    afs_PutDCache(tdc);
! 	/* Don't decrease refcount for this vcache if disconnected, we will
! 	 * need it during replay.
! 	 */
! 	if (!AFS_IS_DISCON_RW)
! 	    afs_PutVCache(tvc);
      } else {
  	code = afsremove(adp, tdc, tvc, aname, acred, &treq);
      }
--- 451,457 ----
  	}
  	if (tdc)
  	    afs_PutDCache(tdc);
! 	afs_PutVCache(tvc);
      } else {
  	code = afsremove(adp, tdc, tvc, aname, acred, &treq);
      }
Index: openafs/src/afs/VNOPS/afs_vnop_rename.c
diff -c openafs/src/afs/VNOPS/afs_vnop_rename.c:1.28.4.5 openafs/src/afs/VNOPS/afs_vnop_rename.c:1.28.4.8
*** openafs/src/afs/VNOPS/afs_vnop_rename.c:1.28.4.5	Sun Nov 30 15:11:19 2008
--- openafs/src/afs/VNOPS/afs_vnop_rename.c	Wed Jan 21 16:18:03 2009
***************
*** 18,24 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_rename.c,v 1.28.4.5 2008/11/30 20:11:19 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 18,24 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_rename.c,v 1.28.4.8 2009/01/21 21:18:03 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 36,42 ****
  afsrename(struct vcache *aodp, char *aname1, struct vcache *andp,
  	  char *aname2, struct AFS_UCRED *acred, struct vrequest *areq)
  {
!     register struct conn *tc;
      register afs_int32 code = 0;
      afs_int32 returnCode;
      int oneDir, doLocally;
--- 36,42 ----
  afsrename(struct vcache *aodp, char *aname1, struct vcache *andp,
  	  char *aname2, struct AFS_UCRED *acred, struct vrequest *areq)
  {
!     register struct afs_conn *tc;
      register afs_int32 code = 0;
      afs_int32 returnCode;
      int oneDir, doLocally;
***************
*** 204,252 ****
  	ReleaseSharedLock(&afs_xvcache);
  
  	if (tvc) {
! 	    if (!(tvc->ddirty_flags & VDisconRename)) {
! 		/* We only care about vnodes that haven't been
! 		 * renamed. Those that have been renamed at least once
! 		 * already have an asociated shadow dir and the flags set
! 		 * for the first old location, which is what interests us
! 		 * when reconnecting.
  		 */
! 
! 	    	if (!(aodp->ddirty_flags & VDisconShadowed) &&
! 			!(tvc->ddirty_flags & VDisconCreate)) {
! 	    	    /*
! 		     * Make shadow copy of parent dir only.
! 		     * Files that are created locally and renamed,
! 		     * don't need a shadow dir, so skip this step.
! 		     */
! 		    if (tdc1)
! 	    	    	ReleaseWriteLock(&tdc1->lock);
!     	    	    afs_MakeShadowDir(aodp);
! 	    	    if (tdc1)
! 	    	    	ObtainWriteLock(&tdc1->lock, 753);
  	        }
  
! 		if (!tvc->ddirty_flags ||
! 			(tvc->ddirty_flags == VDisconShadowed)) {
! 	    	    /* Add in dirty list.*/
! 	 	    ObtainWriteLock(&afs_DDirtyVCListLock, 751);
! 		    AFS_DISCON_ADD_DIRTY(tvc, 1);
! 		    ReleaseWriteLock(&afs_DDirtyVCListLock);
! 		}
  
- 	    	ObtainWriteLock(&tvc->lock, 750);
  	    	/* Save old parent dir fid so it will be searchable
  	     	 * in the shadow dir.
  	     	 */
      	    	tvc->oldVnode = aodp->fid.Fid.Vnode;
  	    	tvc->oldUnique = aodp->fid.Fid.Unique;
! 	    	/* Set discon state flag. */
! 	    	tvc->ddirty_flags |= VDisconRename;
! 	    	if (oneDir)
! 		    tvc->ddirty_flags |= VDisconRenameSameDir;
! 	    	ReleaseWriteLock(&tvc->lock);
! 	    }			/* if not previously renamed */
  
  	    afs_PutVCache(tvc);
  	} else {
  	    code = ENOENT;
--- 204,236 ----
  	ReleaseSharedLock(&afs_xvcache);
  
  	if (tvc) {
! 	    /* XXX - We're locking this vcache whilst holding dcaches. Ooops */
! 	    ObtainWriteLock(&tvc->lock, 750);
! 	    if (!(tvc->ddirty_flags & (VDisconRename|VDisconCreate))) {
! 		/* If the vnode was created locally, then we don't care
! 		 * about recording the rename - we'll do it automatically
! 		 * on replay. If we've already renamed, we've already stored
! 		 * the required information about where we came from.
  		 */
! 		
! 		if (!aodp->shVnode) {
! 	    	    /* Make shadow copy of parent dir only. */
!     	    	    afs_MakeShadowDir(aodp, tdc1);
  	        }
  
! 		afs_DisconAddDirty(tvc, 
! 				   VDisconRename 
! 				     | (oneDir ? VDisconRenameSameDir:0), 
! 				   1);
  
  	    	/* Save old parent dir fid so it will be searchable
  	     	 * in the shadow dir.
  	     	 */
      	    	tvc->oldVnode = aodp->fid.Fid.Vnode;
  	    	tvc->oldUnique = aodp->fid.Fid.Unique;
! 	    }
  
+ 	    ReleaseWriteLock(&tvc->lock);
  	    afs_PutVCache(tvc);
  	} else {
  	    code = ENOENT;
***************
*** 317,328 ****
  	    }
  	}
  
  	/* update dir link counts */
! 	aodp->m.LinkCount = AFS_IS_DISCON_RW ?
! 			(aodp->m.LinkCount - 1):OutOldDirStatus.LinkCount;
! 	if (!oneDir)
! 	    andp->m.LinkCount = AFS_IS_DISCON_RW ?
! 	    		(andp->m.LinkCount + 1):OutNewDirStatus.LinkCount;
  
      } else {			/* operation failed (code != 0) */
  	if (code < 0) {
--- 301,319 ----
  	    }
  	}
  
+ 
  	/* update dir link counts */
! 	if (AFS_IS_DISCON_RW) {
! 	    if (!oneDir) {
! 		aodp->m.LinkCount--;
! 		andp->m.LinkCount++;
! 	    }
! 	    /* If we're in the same directory, link count doesn't change */
! 	} else {
! 	    aodp->m.LinkCount = OutOldDirStatus.LinkCount;
! 	    if (!oneDir)
! 		andp->m.LinkCount = OutNewDirStatus.LinkCount;
! 	}
  
      } else {			/* operation failed (code != 0) */
  	if (code < 0) {
Index: openafs/src/afs/VNOPS/afs_vnop_symlink.c
diff -c openafs/src/afs/VNOPS/afs_vnop_symlink.c:1.24.4.8 openafs/src/afs/VNOPS/afs_vnop_symlink.c:1.24.4.10
*** openafs/src/afs/VNOPS/afs_vnop_symlink.c:1.24.4.8	Sat Nov 29 13:20:27 2008
--- openafs/src/afs/VNOPS/afs_vnop_symlink.c	Wed Jan 21 16:15:09 2009
***************
*** 22,28 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_symlink.c,v 1.24.4.8 2008/11/29 18:20:27 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 22,28 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_symlink.c,v 1.24.4.10 2009/01/21 21:15:09 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 48,54 ****
      afs_uint32 now = 0;
      struct vrequest treq;
      afs_int32 code;
!     struct conn *tc;
      struct VenusFid newFid;
      struct dcache *tdc;
      afs_size_t offset, len;
--- 48,54 ----
      afs_uint32 now = 0;
      struct vrequest treq;
      afs_int32 code;
!     struct afs_conn *tc;
      struct VenusFid newFid;
      struct dcache *tdc;
      afs_size_t offset, len;
***************
*** 107,113 ****
  	goto done;
      }
  
!     if (AFS_IS_DISCONNECTED && !AFS_IS_LOGGING) {
          code = ENETDOWN;
          goto done;
      }
--- 107,113 ----
  	goto done;
      }
  
!     if (AFS_IS_DISCONNECTED) {
          code = ENETDOWN;
          goto done;
      }
Index: openafs/src/afs/VNOPS/afs_vnop_write.c
diff -c openafs/src/afs/VNOPS/afs_vnop_write.c:1.50.2.8 openafs/src/afs/VNOPS/afs_vnop_write.c:1.50.2.10
*** openafs/src/afs/VNOPS/afs_vnop_write.c:1.50.2.8	Tue Dec 16 16:05:35 2008
--- openafs/src/afs/VNOPS/afs_vnop_write.c	Wed Jan 21 16:15:09 2009
***************
*** 21,27 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_write.c,v 1.50.2.8 2008/12/16 21:05:35 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 21,27 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_write.c,v 1.50.2.10 2009/01/21 21:15:09 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 84,105 ****
  	 * afs_{rd,wr} routines which means the vcache is a perfect candidate
  	 * for flushing!
  	 */
- 
- #ifdef AFS_DISCON_ENV
       } else if (AFS_IS_DISCON_RW) {
! 	/* Disconnected. */
! 
! 	if (!avc->ddirty_flags ||
! 		(avc->ddirty_flags == VDisconShadowed)) {
! 
!   	    /* Add to disconnected dirty list. */
! 	    AFS_DISCON_ADD_DIRTY(avc, 1);
! 	}
! 
! 	/* Set disconnected write flag. */
! 	avc->ddirty_flags |= VDisconWriteClose;
! #endif
!     }		/* if not disconnected */
  
  #if defined(AFS_SGI_ENV)
      osi_Assert(avc->opens > 0 && avc->execsOrWriters > 0);
--- 84,92 ----
  	 * afs_{rd,wr} routines which means the vcache is a perfect candidate
  	 * for flushing!
  	 */
       } else if (AFS_IS_DISCON_RW) {
! 	afs_DisconAddDirty(avc, VDisconWriteClose, 0);
!      }		/* if not disconnected */
  
  #if defined(AFS_SGI_ENV)
      osi_Assert(avc->opens > 0 && avc->execsOrWriters > 0);
***************
*** 110,117 ****
      return code;
  }
  
- 
- 
  int
  afs_MemWrite(register struct vcache *avc, struct uio *auio, int aio,
  	     struct AFS_UCRED *acred, int noLock)
--- 97,102 ----
***************
*** 217,282 ****
      tvec = (struct iovec *)osi_AllocSmallSpace(sizeof(struct iovec));
  #endif
      while (totalLength > 0) {
! 	/* 
! 	 *  The following line is necessary because afs_GetDCache with
! 	 *  flag == 4 expects the length field to be filled. It decides
! 	 *  from this whether it's necessary to fetch data into the chunk
! 	 *  before writing or not (when the whole chunk is overwritten!).
! 	 */
! 	len = totalLength;	/* write this amount by default */
! 	if (noLock) {
! 	    tdc = afs_FindDCache(avc, filePos);
! 	    if (tdc)
! 		ObtainWriteLock(&tdc->lock, 653);
! 	} else if (afs_blocksUsed >
! 		   PERCENT(CM_WAITFORDRAINPCT, afs_cacheBlocks)) {
! 	    tdc = afs_FindDCache(avc, filePos);
! 	    if (tdc) {
! 		ObtainWriteLock(&tdc->lock, 654);
! 		if (!hsame(tdc->f.versionNo, avc->m.DataVersion)
! 		    || (tdc->dflags & DFFetching)) {
! 		    ReleaseWriteLock(&tdc->lock);
! 		    afs_PutDCache(tdc);
! 		    tdc = NULL;
! 		}
! 	    }
! 	    if (!tdc) {
! 		afs_MaybeWakeupTruncateDaemon();
! 		while (afs_blocksUsed >
! 		       PERCENT(CM_WAITFORDRAINPCT, afs_cacheBlocks)) {
! 		    ReleaseWriteLock(&avc->lock);
! 		    if (afs_blocksUsed - afs_blocksDiscarded >
! 			PERCENT(CM_WAITFORDRAINPCT, afs_cacheBlocks)) {
! 			afs_WaitForCacheDrain = 1;
! 			afs_osi_Sleep(&afs_WaitForCacheDrain);
! 		    }
! 		    afs_MaybeFreeDiscardedDCache();
! 		    afs_MaybeWakeupTruncateDaemon();
! 		    ObtainWriteLock(&avc->lock, 506);
! 		}
! 		avc->states |= CDirty;
! 		tdc = afs_GetDCache(avc, filePos, &treq, &offset, &len, 4);
! 		if (tdc)
! 		    ObtainWriteLock(&tdc->lock, 655);
! 	    }
! 	} else {
! 	    tdc = afs_GetDCache(avc, filePos, &treq, &offset, &len, 4);
! 	    if (tdc)
! 		ObtainWriteLock(&tdc->lock, 656);
! 	}
  	if (!tdc) {
  	    error = EIO;
  	    break;
  	}
! 	if (!(afs_indexFlags[tdc->index] & IFDataMod)) {
! 	    afs_stats_cmperf.cacheCurrDirtyChunks++;
! 	    afs_indexFlags[tdc->index] |= IFDataMod;	/* so it doesn't disappear */
! 	}
! 	if (!(tdc->f.states & DWriting)) {
! 	    /* don't mark entry as mod if we don't have to */
! 	    tdc->f.states |= DWriting;
! 	    tdc->dflags |= DFEntryMod;
! 	}
  	len = totalLength;	/* write this amount by default */
  	offset = filePos - AFS_CHUNKTOBASE(tdc->f.chunk);
  	max = AFS_CHUNKTOSIZE(tdc->f.chunk);	/* max size of this chunk */
--- 202,214 ----
      tvec = (struct iovec *)osi_AllocSmallSpace(sizeof(struct iovec));
  #endif
      while (totalLength > 0) {
! 	tdc = afs_ObtainDCacheForWriting(avc, filePos, totalLength, &treq, 
! 					 noLock);
  	if (!tdc) {
  	    error = EIO;
  	    break;
  	}
! 
  	len = totalLength;	/* write this amount by default */
  	offset = filePos - AFS_CHUNKTOBASE(tdc->f.chunk);
  	max = AFS_CHUNKTOSIZE(tdc->f.chunk);	/* max size of this chunk */
***************
*** 483,549 ****
      tvec = (struct iovec *)osi_AllocSmallSpace(sizeof(struct iovec));
  #endif
      while (totalLength > 0) {
! 	/* 
! 	 *  The following line is necessary because afs_GetDCache with
! 	 *  flag == 4 expects the length field to be filled. It decides
! 	 *  from this whether it's necessary to fetch data into the chunk
! 	 *  before writing or not (when the whole chunk is overwritten!).
! 	 */
! 	len = totalLength;	/* write this amount by default */
! 	/* read the cached info */
! 	if (noLock) {
! 	    tdc = afs_FindDCache(avc, filePos);
! 	    if (tdc)
! 		ObtainWriteLock(&tdc->lock, 657);
! 	} else if (afs_blocksUsed >
! 		   PERCENT(CM_WAITFORDRAINPCT, afs_cacheBlocks)) {
! 	    tdc = afs_FindDCache(avc, filePos);
! 	    if (tdc) {
! 		ObtainWriteLock(&tdc->lock, 658);
! 		if (!hsame(tdc->f.versionNo, avc->m.DataVersion)
! 		    || (tdc->dflags & DFFetching)) {
! 		    ReleaseWriteLock(&tdc->lock);
! 		    afs_PutDCache(tdc);
! 		    tdc = NULL;
! 		}
! 	    }
! 	    if (!tdc) {
! 		afs_MaybeWakeupTruncateDaemon();
! 		while (afs_blocksUsed >
! 		       PERCENT(CM_WAITFORDRAINPCT, afs_cacheBlocks)) {
! 		    ReleaseWriteLock(&avc->lock);
! 		    if (afs_blocksUsed - afs_blocksDiscarded >
! 			PERCENT(CM_WAITFORDRAINPCT, afs_cacheBlocks)) {
! 			afs_WaitForCacheDrain = 1;
! 			afs_osi_Sleep(&afs_WaitForCacheDrain);
! 		    }
! 		    afs_MaybeFreeDiscardedDCache();
! 		    afs_MaybeWakeupTruncateDaemon();
! 		    ObtainWriteLock(&avc->lock, 509);
! 		}
! 		avc->states |= CDirty;
! 		tdc = afs_GetDCache(avc, filePos, &treq, &offset, &len, 4);
! 		if (tdc)
! 		    ObtainWriteLock(&tdc->lock, 659);
! 	    }
! 	} else {
! 	    tdc = afs_GetDCache(avc, filePos, &treq, &offset, &len, 4);
! 	    if (tdc)
! 		ObtainWriteLock(&tdc->lock, 660);
! 	}
  	if (!tdc) {
  	    error = EIO;
  	    break;
  	}
- 	if (!(afs_indexFlags[tdc->index] & IFDataMod)) {
- 	    afs_stats_cmperf.cacheCurrDirtyChunks++;
- 	    afs_indexFlags[tdc->index] |= IFDataMod;	/* so it doesn't disappear */
- 	}
- 	if (!(tdc->f.states & DWriting)) {
- 	    /* don't mark entry as mod if we don't have to */
- 	    tdc->f.states |= DWriting;
- 	    tdc->dflags |= DFEntryMod;
- 	}
  #if defined(LINUX_USE_FH)
  	tfile = (struct osi_file *)osi_UFSOpen_fh(&tdc->f.fh, tdc->f.fh_type);
  #else
--- 415,426 ----
      tvec = (struct iovec *)osi_AllocSmallSpace(sizeof(struct iovec));
  #endif
      while (totalLength > 0) {
! 	tdc = afs_ObtainDCacheForWriting(avc, filePos, totalLength, &treq, 
! 					 noLock);
  	if (!tdc) {
  	    error = EIO;
  	    break;
  	}
  #if defined(LINUX_USE_FH)
  	tfile = (struct osi_file *)osi_UFSOpen_fh(&tdc->f.fh, tdc->f.fh_type);
  #else
***************
*** 765,771 ****
      register afs_int32 code;
  
      if (afs_stats_cmperf.cacheCurrDirtyChunks <=
! 	afs_stats_cmperf.cacheMaxDirtyChunks)
  	return 0;		/* nothing to do */
      /* otherwise, call afs_StoreDCache (later try to do this async, if possible) */
      afs_Trace2(afs_iclSetp, CM_TRACE_PARTIALWRITE, ICL_TYPE_POINTER, avc,
--- 642,649 ----
      register afs_int32 code;
  
      if (afs_stats_cmperf.cacheCurrDirtyChunks <=
! 	afs_stats_cmperf.cacheMaxDirtyChunks
! 	|| AFS_IS_DISCONNECTED)
  	return 0;		/* nothing to do */
      /* otherwise, call afs_StoreDCache (later try to do this async, if possible) */
      afs_Trace2(afs_iclSetp, CM_TRACE_PARTIALWRITE, ICL_TYPE_POINTER, avc,
***************
*** 1084,1105 ****
  
  #if defined(AFS_DISCON_ENV)
  	} else {
- 	    /* Disconnected flush. */
- 	    ObtainWriteLock(&afs_DDirtyVCListLock, 708);
- 
- 	    if (!avc->ddirty_flags ||
- 	    	(avc->ddirty_flags == VDisconShadowed)) {
- 
- 		/* Add to disconnected dirty list. */
- 		AFS_DISCON_ADD_DIRTY(avc, 1);
- 	    }
  
  	    UpgradeSToWLock(&avc->lock, 711);
! 	    /* Set disconnected write flag. */
! 	    avc->ddirty_flags |= VDisconWriteFlush;
  	    ConvertWToSLock(&avc->lock);
- 
- 	    ReleaseWriteLock(&afs_DDirtyVCListLock);
  #endif
      	}		/* if not disconnected */
      }			/* if (avc->execsOrWriters > 0) */
--- 962,971 ----
  
  #if defined(AFS_DISCON_ENV)
  	} else {
  
  	    UpgradeSToWLock(&avc->lock, 711);
! 	    afs_DisconAddDirty(avc, VDisconWriteFlush, 1);
  	    ConvertWToSLock(&avc->lock);
  #endif
      	}		/* if not disconnected */
      }			/* if (avc->execsOrWriters > 0) */
Index: openafs/src/afsd/afs.rc.linux
diff -c openafs/src/afsd/afs.rc.linux:1.12.4.1 openafs/src/afsd/afs.rc.linux:1.12.4.2
*** openafs/src/afsd/afs.rc.linux:1.12.4.1	Mon Jan 21 16:04:53 2008
--- openafs/src/afsd/afs.rc.linux	Mon Jan 19 15:53:51 2009
***************
*** 1,4 ****
! #! /bin/sh
  # Copyright 2000, International Business Machines Corporation and others.
  # All Rights Reserved.
  # 
--- 1,4 ----
! #! /bin/bash
  # Copyright 2000, International Business Machines Corporation and others.
  # All Rights Reserved.
  # 
Index: openafs/src/aklog/Makefile.in
diff -c openafs/src/aklog/Makefile.in:1.10.2.6 openafs/src/aklog/Makefile.in:1.10.2.8
*** openafs/src/aklog/Makefile.in:1.10.2.6	Sat Jun 28 03:18:15 2008
--- openafs/src/aklog/Makefile.in	Thu Jan 22 16:19:57 2009
***************
*** 9,17 ****
  AKLIBS = ${LIBS} @KRB5LIBS@
  AFSLIBS = ${TOP_LIBDIR}/libprot.a ${TOP_LIBDIR}/libubik.a \
  	  ${TOP_LIBDIR}/libauth.a ${TOP_LIBDIR}/librxkad.a \
! 	  ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a \
! 	  ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/libdes.a \
! 	  ${TOP_LIBDIR}/libcom_err.a ${TOP_LIBDIR}/libafsutil.a
  
  SRCS=	aklog.c aklog_main.c  krb_util.c linked_list.c
  OBJS=   aklog.o aklog_main.o krb_util.o linked_list.o
--- 9,19 ----
  AKLIBS = ${LIBS} @KRB5LIBS@
  AFSLIBS = ${TOP_LIBDIR}/libprot.a ${TOP_LIBDIR}/libubik.a \
  	  ${TOP_LIBDIR}/libauth.a ${TOP_LIBDIR}/librxkad.a \
! 	  ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/librx.a \
! 	  ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/liblwp.a \
! 	  ${TOP_LIBDIR}/libdes.a \
! 	  ${TOP_LIBDIR}/libcom_err.a ${TOP_LIBDIR}/libcmd.a \
! 	  ${TOP_LIBDIR}/libafsutil.a
  
  SRCS=	aklog.c aklog_main.c  krb_util.c linked_list.c
  OBJS=   aklog.o aklog_main.o krb_util.o linked_list.o
***************
*** 26,32 ****
  
  klog: klog.o skipwrap.o ${AFSLIBS}
  	${CC} -o $@ ${CFLAGS} skipwrap.o klog.o ${AKLIBS} ${AFSLIBS} \
! 		${TOP_LIBDIR}/libcmd.a ${TOP_LIBDIR}/librx.a ${XLIBS}
  
  #
  # Installation targets
--- 28,34 ----
  
  klog: klog.o skipwrap.o ${AFSLIBS}
  	${CC} -o $@ ${CFLAGS} skipwrap.o klog.o ${AKLIBS} ${AFSLIBS} \
! 		${XLIBS}
  
  #
  # Installation targets
Index: openafs/src/bucoord/ubik_db_if.c
diff -c openafs/src/bucoord/ubik_db_if.c:1.10.14.2 openafs/src/bucoord/ubik_db_if.c:1.10.14.5
*** openafs/src/bucoord/ubik_db_if.c:1.10.14.2	Tue Apr 10 14:39:50 2007
--- openafs/src/bucoord/ubik_db_if.c	Thu Jan 22 14:33:14 2009
***************
*** 13,19 ****
  #include <afs/stds.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/bucoord/ubik_db_if.c,v 1.10.14.2 2007/04/10 18:39:50 shadow Exp $");
  
  #include <sys/types.h>
  #include <fcntl.h>
--- 13,19 ----
  #include <afs/stds.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/bucoord/ubik_db_if.c,v 1.10.14.5 2009/01/22 19:33:14 shadow Exp $");
  
  #include <sys/types.h>
  #include <fcntl.h>
***************
*** 44,50 ****
  afs_int32 bcdb_CreateDump(register struct budb_dumpEntry *) ;
  afs_int32 bcdb_deleteDump(afs_int32, afs_int32, afs_int32, budb_dumpsList *);
  /*note the pinter to the function comes from ubik/ubikclient ubik_Call function.*/
! afs_int32 bcdb_listDumps (int (), afs_int32,afs_int32,afs_int32, budb_dumpsList *,
   budb_dumpsList *);
  afs_int32 bcdb_DeleteVDP(char *, char *, afs_int32 );
  afs_int32 bcdb_FindClone(afs_int32, char *, afs_int32 *);
--- 44,50 ----
  afs_int32 bcdb_CreateDump(register struct budb_dumpEntry *) ;
  afs_int32 bcdb_deleteDump(afs_int32, afs_int32, afs_int32, budb_dumpsList *);
  /*note the pinter to the function comes from ubik/ubikclient ubik_Call function.*/
! afs_int32 bcdb_listDumps (afs_int32, afs_int32,afs_int32,afs_int32, budb_dumpsList *,
   budb_dumpsList *);
  afs_int32 bcdb_DeleteVDP(char *, char *, afs_int32 );
  afs_int32 bcdb_FindClone(afs_int32, char *, afs_int32 *);
***************
*** 67,73 ****
  {
      afs_int32 code;
  
!     code = ubik_Call(BUDB_AddVolume, udbHandle.uh_client, 0, veptr);
      return (code);
  }
  
--- 67,73 ----
  {
      afs_int32 code;
  
!     code = ubik_BUDB_AddVolume(udbHandle.uh_client, 0, veptr);
      return (code);
  }
  
***************
*** 78,84 ****
  
      volumeList.budb_volumeList_len = count;
      volumeList.budb_volumeList_val = veptr;
!     code = ubik_Call(BUDB_AddVolumes, udbHandle.uh_client, 0, &volumeList);
      return (code);
  }
  
--- 78,84 ----
  
      volumeList.budb_volumeList_len = count;
      volumeList.budb_volumeList_val = veptr;
!     code = ubik_BUDB_AddVolumes(udbHandle.uh_client, 0, &volumeList);
      return (code);
  }
  
***************
*** 87,93 ****
  {
      afs_int32 code;
  
!     code = ubik_Call(BUDB_CreateDump, udbHandle.uh_client, 0, deptr);
      return (code);
  }
  
--- 87,93 ----
  {
      afs_int32 code;
  
!     code = ubik_BUDB_CreateDump(udbHandle.uh_client, 0, deptr);
      return (code);
  }
  
***************
*** 102,117 ****
      dumpsPtr = (dumps ? dumps : &dumpsList);
  
      code =
! 	ubik_Call(BUDB_DeleteDump, udbHandle.uh_client, 0, dumpID, fromTime,
  		  toTime, dumpsPtr);
      if (dumpsList.budb_dumpsList_val)
  	free(dumpsList.budb_dumpsList_val);
      return (code);
  }
  
! afs_int32 bcdb_listDumps (int (*sflags) (), afs_int32 groupId,afs_int32 fromTime, afs_int32 toTime,budb_dumpsList *dumps, budb_dumpsList *flags)
  {
!     afs_int32 code, sflag = 0;
      budb_dumpsList dumpsList, *dumpsPtr;
      budb_dumpsList flagsList, *flagsPtr;
  
--- 102,117 ----
      dumpsPtr = (dumps ? dumps : &dumpsList);
  
      code =
! 	ubik_BUDB_DeleteDump(udbHandle.uh_client, 0, dumpID, fromTime,
  		  toTime, dumpsPtr);
      if (dumpsList.budb_dumpsList_val)
  	free(dumpsList.budb_dumpsList_val);
      return (code);
  }
  
! afs_int32 bcdb_listDumps (afs_int32 sflags, afs_int32 groupId,afs_int32 fromTime, afs_int32 toTime,budb_dumpsList *dumps, budb_dumpsList *flags)
  {
!     afs_int32 code;
      budb_dumpsList dumpsList, *dumpsPtr;
      budb_dumpsList flagsList, *flagsPtr;
  
***************
*** 124,130 ****
      flagsPtr = (flags ? flags : &flagsList);
  
      code =
! 	ubik_Call(BUDB_ListDumps, udbHandle.uh_client, 0, sflags, "", groupId,
  		  fromTime, toTime, dumpsPtr, flagsPtr);
  
      if (dumpsList.budb_dumpsList_val)
--- 124,130 ----
      flagsPtr = (flags ? flags : &flagsList);
  
      code =
! 	ubik_BUDB_ListDumps(udbHandle.uh_client, 0, sflags, "", groupId,
  		  fromTime, toTime, dumpsPtr, flagsPtr);
  
      if (dumpsList.budb_dumpsList_val)
***************
*** 140,146 ****
      afs_int32 code;
  
      code =
! 	ubik_Call(BUDB_DeleteVDP, udbHandle.uh_client, 0, dumpSetName,
  		  dumpPath, dumpID);
      return (code);
  }
--- 140,146 ----
      afs_int32 code;
  
      code =
! 	ubik_BUDB_DeleteVDP(udbHandle.uh_client, 0, dumpSetName,
  		  dumpPath, dumpID);
      return (code);
  }
***************
*** 163,169 ****
  {
      afs_int32 code;
      code =
! 	ubik_Call(BUDB_FindClone, udbHandle.uh_client, 0, dumpID, volName,
  		  clonetime);
      return (code);
  }
--- 163,169 ----
  {
      afs_int32 code;
      code =
! 	ubik_BUDB_FindClone(udbHandle.uh_client, 0, dumpID, volName,
  		  clonetime);
      return (code);
  }
***************
*** 192,198 ****
  {
      afs_int32 code;
      code =
! 	ubik_Call(BUDB_FindDump, udbHandle.uh_client, 0, volumeName,
  		  beforeDate, deptr);
      return (code);
  }
--- 192,198 ----
  {
      afs_int32 code;
      code =
! 	ubik_BUDB_FindDump(udbHandle.uh_client, 0, volumeName,
  		  beforeDate, deptr);
      return (code);
  }
***************
*** 217,223 ****
      dl.budb_dumpList_val = 0;
  
      /* outline algorithm */
!     code = ubik_Call(BUDB_GetDumps, udbHandle.uh_client, 0, BUDB_MAJORVERSION, BUDB_OP_DUMPID, "",	/* no name */
  		     dumpID,	/* start */
  		     0,		/* end */
  		     0,		/* index */
--- 217,223 ----
      dl.budb_dumpList_val = 0;
  
      /* outline algorithm */
!     code = ubik_BUDB_GetDumps(udbHandle.uh_client, 0, BUDB_MAJORVERSION, BUDB_OP_DUMPID, "",	/* no name */
  		     dumpID,	/* start */
  		     0,		/* end */
  		     0,		/* index */
***************
*** 303,309 ****
  {
      afs_int32 code;
      code =
! 	ubik_Call(BUDB_FindLatestDump, udbHandle.uh_client, 0, volSetName,
  		  dumpPath, deptr);
      return (code);
  }
--- 303,309 ----
  {
      afs_int32 code;
      code =
! 	ubik_BUDB_FindLatestDump(udbHandle.uh_client, 0, volSetName,
  		  dumpPath, deptr);
      return (code);
  }
***************
*** 331,337 ****
      tl.budb_tapeList_val = 0;
  
      code =
! 	ubik_Call(BUDB_GetTapes, udbHandle.uh_client, 0, BUDB_MAJORVERSION,
  		  BUDB_OP_TAPENAME | BUDB_OP_DUMPID, tapeName, dumpid, 0, 0,
  		  &next, &dbTime, &tl);
  
--- 331,337 ----
      tl.budb_tapeList_val = 0;
  
      code =
! 	ubik_BUDB_GetTapes(udbHandle.uh_client, 0, BUDB_MAJORVERSION,
  		  BUDB_OP_TAPENAME | BUDB_OP_DUMPID, tapeName, dumpid, 0, 0,
  		  &next, &dbTime, &tl);
  
***************
*** 364,370 ****
      tl.budb_tapeList_val = 0;
  
      code =
! 	ubik_Call(BUDB_GetTapes, udbHandle.uh_client, 0, BUDB_MAJORVERSION,
  		  BUDB_OP_TAPESEQ | BUDB_OP_DUMPID, "", dumpid, tapeSeq, 0,
  		  &next, &dbTime, &tl);
      if (code)
--- 364,370 ----
      tl.budb_tapeList_val = 0;
  
      code =
! 	ubik_BUDB_GetTapes(udbHandle.uh_client, 0, BUDB_MAJORVERSION,
  		  BUDB_OP_TAPESEQ | BUDB_OP_DUMPID, "", dumpid, tapeSeq, 0,
  		  &next, &dbTime, &tl);
      if (code)
***************
*** 412,418 ****
      vl.budb_volumeList_val = returnArray;
  
      /* outline algorithm */
!     code = ubik_Call(BUDB_GetVolumes, udbHandle.uh_client, 0, BUDB_MAJORVERSION, BUDB_OP_VOLUMENAME | BUDB_OP_DUMPID, volumeName,	/* name */
  		     dumpID,	/* start */
  		     0,		/* end */
  		     last,	/* index */
--- 412,418 ----
      vl.budb_volumeList_val = returnArray;
  
      /* outline algorithm */
!     code = ubik_BUDB_GetVolumes(udbHandle.uh_client, 0, BUDB_MAJORVERSION, BUDB_OP_VOLUMENAME | BUDB_OP_DUMPID, volumeName,	/* name */
  		     dumpID,	/* start */
  		     0,		/* end */
  		     last,	/* index */
***************
*** 428,434 ****
       register struct budb_dumpEntry *deptr;
  {
      afs_int32 code;
!     code = ubik_Call(BUDB_FinishDump, udbHandle.uh_client, 0, deptr);
      return (code);
  }
  
--- 428,434 ----
       register struct budb_dumpEntry *deptr;
  {
      afs_int32 code;
!     code = ubik_BUDB_FinishDump(udbHandle.uh_client, 0, deptr);
      return (code);
  }
  
***************
*** 436,442 ****
       register struct budb_tapeEntry *teptr;
  {
      afs_int32 code;
!     code = ubik_Call(BUDB_FinishTape, udbHandle.uh_client, 0, teptr);
      return (code);
  
  }
--- 436,442 ----
       register struct budb_tapeEntry *teptr;
  {
      afs_int32 code;
!     code = ubik_BUDB_FinishTape(udbHandle.uh_client, 0, teptr);
      return (code);
  
  }
***************
*** 461,467 ****
      vl.budb_volumeList_val = returnArray;
  
      /* outline algorithm */
!     code = ubik_Call(BUDB_GetVolumes, udbHandle.uh_client, 0, BUDB_MAJORVERSION, BUDB_OP_VOLUMENAME, volumeName,	/* name */
  		     0,		/* start */
  		     0,		/* end */
  		     last,	/* index */
--- 461,467 ----
      vl.budb_volumeList_val = returnArray;
  
      /* outline algorithm */
!     code = ubik_BUDB_GetVolumes(udbHandle.uh_client, 0, BUDB_MAJORVERSION, BUDB_OP_VOLUMENAME, volumeName,	/* name */
  		     0,		/* start */
  		     0,		/* end */
  		     last,	/* index */
***************
*** 481,487 ****
       afs_int32 *newFlag;
  {
      afs_int32 code;
!     code = ubik_Call(BUDB_UseTape, udbHandle.uh_client, 0, teptr, newFlag);
      return (code);
  }
  
--- 481,487 ----
       afs_int32 *newFlag;
  {
      afs_int32 code;
!     code = ubik_BUDB_UseTape(udbHandle.uh_client, 0, teptr, newFlag);
      return (code);
  }
  
***************
*** 532,538 ****
  	offset = nextOffset;
  	charList.charListT_len = bufferSize;
  	code =
! 	    ubik_Call(BUDB_GetText, udbHandle.uh_client, 0, ctPtr->lockHandle,
  		      ctPtr->textType, bufferSize, offset, &nextOffset,
  		      &charList);
  
--- 532,538 ----
  	offset = nextOffset;
  	charList.charListT_len = bufferSize;
  	code =
! 	    ubik_BUDB_GetText(udbHandle.uh_client, 0, ctPtr->lockHandle,
  		      ctPtr->textType, bufferSize, offset, &nextOffset,
  		      &charList);
  
***************
*** 550,556 ****
  
      /* get text version */
      code =
! 	ubik_Call(BUDB_GetTextVersion, udbHandle.uh_client, 0,
  		  ctPtr->textType, &ctPtr->textVersion);
      if (code)
  	ERROR(code);
--- 550,556 ----
  
      /* get text version */
      code =
! 	ubik_BUDB_GetTextVersion(udbHandle.uh_client, 0,
  		  ctPtr->textType, &ctPtr->textVersion);
      if (code)
  	ERROR(code);
***************
*** 609,615 ****
      if (fileSize == 0) {
  	charList.charListT_len = 0;
  	code =
! 	    ubik_Call(BUDB_SaveText, udbHandle.uh_client, 0,
  		      ctPtr->lockHandle, ctPtr->textType, 0,
  		      BUDB_TEXT_COMPLETE, &charList);
  	goto error_exit;
--- 609,615 ----
      if (fileSize == 0) {
  	charList.charListT_len = 0;
  	code =
! 	    ubik_BUDB_SaveText(udbHandle.uh_client, 0,
  		      ctPtr->lockHandle, ctPtr->textType, 0,
  		      BUDB_TEXT_COMPLETE, &charList);
  	goto error_exit;
***************
*** 629,635 ****
  
  	charList.charListT_len = chunkSize;
  	code =
! 	    ubik_Call(BUDB_SaveText, udbHandle.uh_client, 0,
  		      ctPtr->lockHandle, ctPtr->textType, offset,
  		      (chunkSize == fileSize) ? BUDB_TEXT_COMPLETE : 0,
  		      &charList);
--- 629,635 ----
  
  	charList.charListT_len = chunkSize;
  	code =
! 	    ubik_BUDB_SaveText(udbHandle.uh_client, 0,
  		      ctPtr->lockHandle, ctPtr->textType, offset,
  		      (chunkSize == fileSize) ? BUDB_TEXT_COMPLETE : 0,
  		      &charList);
***************
*** 654,661 ****
       struct budb_tapeEntry *tapeEntry;
       struct budb_volumeEntry *volEntry;
  {
!     return (ubik_Call
! 	    (BUDB_FindLastTape, udbHandle.uh_client, 0, dumpID, dumpEntry,
  	     tapeEntry, volEntry));
  }
  
--- 654,660 ----
       struct budb_tapeEntry *tapeEntry;
       struct budb_volumeEntry *volEntry;
  {
!     return (ubik_BUDB_FindLastTape(udbHandle.uh_client, 0, dumpID, dumpEntry,
  	     tapeEntry, volEntry));
  }
  
***************
*** 664,671 ****
       afs_int32 initialDumpID;
       afs_int32 startTapeSeq;
  {
!     return (ubik_Call
! 	    (BUDB_MakeDumpAppended, udbHandle.uh_client, 0, appendedDumpID,
  	     initialDumpID, startTapeSeq));
  }
  
--- 663,669 ----
       afs_int32 initialDumpID;
       afs_int32 startTapeSeq;
  {
!     return (ubik_BUDB_MakeDumpAppended(udbHandle.uh_client, 0, appendedDumpID,
  	     initialDumpID, startTapeSeq));
  }
  
***************
*** 719,725 ****
  
      while (1) {
  	code =
! 	    ubik_Call(BUDB_GetLock, udbHandle.uh_client, 0,
  		      udbHandle.uh_instanceId, ctPtr->textType, timeout,
  		      &ctPtr->lockHandle);
  	if ((code != BUDB_LOCKED) && (code != BUDB_SELFLOCKED)) {
--- 717,723 ----
  
      while (1) {
  	code =
! 	    ubik_BUDB_GetLock(udbHandle.uh_client, 0,
  		      udbHandle.uh_instanceId, ctPtr->textType, timeout,
  		      &ctPtr->lockHandle);
  	if ((code != BUDB_LOCKED) && (code != BUDB_SELFLOCKED)) {
***************
*** 763,769 ****
  	return (0);
  
      code =
! 	ubik_Call(BUDB_FreeLock, udbHandle.uh_client, 0, ctPtr->lockHandle);
      ctPtr->lockHandle = 0;
  
      /* Don't try to analyse the error. Let the lock timeout */
--- 761,767 ----
  	return (0);
  
      code =
! 	ubik_BUDB_FreeLock(udbHandle.uh_client, 0, ctPtr->lockHandle);
      ctPtr->lockHandle = 0;
  
      /* Don't try to analyse the error. Let the lock timeout */
***************
*** 786,792 ****
  	return (BC_VERSIONMISMATCH);
  
      code =
! 	ubik_Call(BUDB_GetTextVersion, udbHandle.uh_client, 0,
  		  ctPtr->textType, &tversion);
      if (code)
  	return (code);
--- 784,790 ----
  	return (BC_VERSIONMISMATCH);
  
      code =
! 	ubik_BUDB_GetTextVersion(udbHandle.uh_client, 0,
  		  ctPtr->textType, &tversion);
      if (code)
  	return (code);
***************
*** 1088,1094 ****
      for (i = 0; i < info.numServers; i++)
  	rx_SetConnDeadTime(udbHandle.uh_client->conns[i], 1);
      code =
! 	ubik_Call(BUDB_GetInstanceId, udbHandle.uh_client, 0,
  		  &udbHandle.uh_instanceId);
  
      /* Reset dead time back up to default */
--- 1086,1092 ----
      for (i = 0; i < info.numServers; i++)
  	rx_SetConnDeadTime(udbHandle.uh_client->conns[i], 1);
      code =
! 	ubik_BUDB_GetInstanceId(udbHandle.uh_client, 0,
  		  &udbHandle.uh_instanceId);
  
      /* Reset dead time back up to default */
***************
*** 1098,1104 ****
      /* If did not find a site on first quick pass, try again */
      if (code == -1)
  	code =
! 	    ubik_Call(BUDB_GetInstanceId, udbHandle.uh_client, 0,
  		      &udbHandle.uh_instanceId);
      if (code) {
  	afs_com_err(whoami, code, "; Can't access backup database");
--- 1096,1102 ----
      /* If did not find a site on first quick pass, try again */
      if (code == -1)
  	code =
! 	    ubik_BUDB_GetInstanceId(udbHandle.uh_client, 0,
  		      &udbHandle.uh_instanceId);
      if (code) {
  	afs_com_err(whoami, code, "; Can't access backup database");
***************
*** 1340,1346 ****
      }
  
      code =
! 	ubik_Call(BUDB_GetInstanceId, udbHandle.uh_client, 0,
  		  &udbHandle.uh_instanceId);
      if (code) {
  	afs_com_err(whoami, code, "; Can't estblish instance Id");
--- 1338,1344 ----
      }
  
      code =
! 	ubik_BUDB_GetInstanceId(udbHandle.uh_client, 0,
  		  &udbHandle.uh_instanceId);
      if (code) {
  	afs_com_err(whoami, code, "; Can't estblish instance Id");
Index: openafs/src/cf/linux-test4.m4
diff -c openafs/src/cf/linux-test4.m4:1.29.2.47 openafs/src/cf/linux-test4.m4:1.29.2.49
*** openafs/src/cf/linux-test4.m4:1.29.2.47	Sat Nov  8 11:49:43 2008
--- openafs/src/cf/linux-test4.m4	Thu Jan 15 08:27:29 2009
***************
*** 825,830 ****
--- 825,846 ----
      AC_DEFINE([GENERIC_FILE_AIO_READ], 1, [define if your kernel has generic_file_aio_read()])
    fi])
  
+ AC_DEFUN([LINUX_HAVE_I_SIZE_READ], [
+   AC_MSG_CHECKING([for linux i_size_read()])
+   AC_CACHE_VAL([ac_cv_linux_i_size_read], [
+     save_CPPFLAGS="$CPPFLAGS"
+     CPPFLAGS="$CPPFLAGS -Werror-implicit-function-declaration"
+     AC_TRY_KBUILD(
+ [#include <linux/fs.h>],
+ [i_size_read(NULL);],
+       ac_cv_linux_i_size_read=yes,
+       ac_cv_linux_i_size_read=no)
+     CPPFLAGS="$save_CPPFLAGS"])
+   AC_MSG_RESULT($ac_cv_linux_i_size_read)
+   if test "x$ac_cv_linux_i_size_read" = "xyes"; then
+     AC_DEFINE([HAVE_LINUX_I_SIZE_READ], 1, [define if your kernel has i_size_read()])
+   fi])
+ 
  AC_DEFUN([LINUX_FREEZER_H_EXISTS], [
    AC_MSG_CHECKING([for linux/freezer.h existance])
    AC_CACHE_VAL([ac_cv_linux_freezer_h_exists], [
***************
*** 1117,1119 ****
--- 1133,1164 ----
    if test "x$ac_cv_linux_write_begin" = "xyes"; then
      AC_DEFINE([HAVE_WRITE_BEGIN], 1, [define if your kernel has a write_begin() address space op])
    fi])
+ 
+ AC_DEFUN([LINUX_HAVE_GRAB_CACHE_PAGE_WRITE_BEGIN], [
+   AC_MSG_CHECKING([for linux grab_cache_page_write_begin()])
+   AC_CACHE_VAL([ac_cv_linux_grab_cache_page_write_begin], [
+     AC_TRY_KBUILD(
+ [#include <linux/pagemap.h>],
+ [grab_cache_page_write_begin(NULL, 0, 0);],
+       ac_cv_linux_grab_cache_page_write_begin=yes,
+       ac_cv_linux_grab_cache_page_write_begin=no)])
+   AC_MSG_RESULT($ac_cv_linux_grab_cache_page_write_begin)
+   if test "x$ac_cv_linux_grab_cache_page_write_begin" = "xyes"; then
+     AC_DEFINE([HAVE_GRAB_CACHE_PAGE_WRITE_BEGIN], 1, [define if your kernel has grab_cache_page_write_begin()])
+   fi])
+ 
+ AC_DEFUN([LINUX_STRUCT_TASK_HAS_CRED], [
+   AC_MSG_CHECKING([if struct task has cred])
+   AC_CACHE_VAL([ac_cv_linux_struct_task_has_cred], [
+     AC_TRY_KBUILD(
+ [#include <linux/sched.h>
+ #include <linux/cred.h>],
+ [struct task_struct _t;
+ uid_t _u;
+ _u =_t.cred->uid ;],
+       ac_cv_linux_struct_task_has_cred=yes,
+       ac_cv_linux_struct_task_has_cred=no)])
+   AC_MSG_RESULT($ac_cv_linux_struct_task_has_cred)
+   if test "x$ac_cv_linux_struct_task_has_cred" = "xyes"; then
+     AC_DEFINE([STRUCT_TASK_HAS_CRED], 1, [define if struct task has a cred pointer])
+   fi])
Index: openafs/src/cf/osconf.m4
diff -c openafs/src/cf/osconf.m4:1.83.2.14 openafs/src/cf/osconf.m4:1.83.2.15
*** openafs/src/cf/osconf.m4:1.83.2.14	Mon Dec 29 12:29:17 2008
--- openafs/src/cf/osconf.m4	Tue Jan 13 11:26:16 2009
***************
*** 4,9 ****
--- 4,10 ----
  dnl defaults, override in case below as needed
  CFLAGS=
  XCFLAGS='${DBG} ${OPTMZ}'
+ RXDEBUG="-DRXDEBUG"
  SHLIB_SUFFIX="so"
  CC="cc"
  CCOBJ="cc"
Index: openafs/src/config/NTMakefile.amd64_w2k
diff -c openafs/src/config/NTMakefile.amd64_w2k:1.24.2.51 openafs/src/config/NTMakefile.amd64_w2k:1.24.2.52
*** openafs/src/config/NTMakefile.amd64_w2k:1.24.2.51	Mon Dec 29 23:27:54 2008
--- openafs/src/config/NTMakefile.amd64_w2k	Thu Jan 22 12:05:50 2009
***************
*** 84,90 ****
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=5600
  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=5700
  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.49 openafs/src/config/NTMakefile.i386_nt40:1.84.2.50
*** openafs/src/config/NTMakefile.i386_nt40:1.84.2.49	Mon Dec 29 23:27:54 2008
--- openafs/src/config/NTMakefile.i386_nt40	Thu Jan 22 12:05:50 2009
***************
*** 84,90 ****
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=5600
  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=5700
  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.53 openafs/src/config/NTMakefile.i386_w2k:1.23.2.54
*** openafs/src/config/NTMakefile.i386_w2k:1.23.2.53	Mon Dec 29 23:27:54 2008
--- openafs/src/config/NTMakefile.i386_w2k	Thu Jan 22 12:05:50 2009
***************
*** 88,94 ****
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=5600
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
--- 88,94 ----
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=5700
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
Index: openafs/src/config/afs_sysnames.h
diff -c openafs/src/config/afs_sysnames.h:1.77.2.8 openafs/src/config/afs_sysnames.h:1.77.2.9
*** openafs/src/config/afs_sysnames.h:1.77.2.8	Mon Dec 15 15:38:07 2008
--- openafs/src/config/afs_sysnames.h	Thu Jan 22 16:29:09 2009
***************
*** 245,250 ****
--- 245,254 ----
  #define SYS_NAME_ID_i386_obsd38		2607
  #define SYS_NAME_ID_i386_obsd39		2608
  #define SYS_NAME_ID_i386_obsd40         2609
+ #define SYS_NAME_ID_i386_obsd41         2610
+ #define SYS_NAME_ID_i386_obsd42         2611
+ #define SYS_NAME_ID_i386_obsd43         2612
+ #define SYS_NAME_ID_i386_obsd44         2613
  
  #define SYS_NAME_ID_amd64_linux2        2700
  #define SYS_NAME_ID_amd64_linux22       2701
Index: openafs/src/kauth/user.c
diff -c openafs/src/kauth/user.c:1.12.8.2 openafs/src/kauth/user.c:1.12.8.3
*** openafs/src/kauth/user.c:1.12.8.2	Tue Oct 30 11:16:39 2007
--- openafs/src/kauth/user.c	Thu Jan 22 16:38:55 2009
***************
*** 18,24 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/kauth/user.c,v 1.12.8.2 2007/10/30 15:16:39 shadow Exp $");
  
  #if defined(UKERNEL)
  #include "afs/sysincludes.h"
--- 18,24 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/kauth/user.c,v 1.12.8.3 2009/01/22 21:38:55 shadow Exp $");
  
  #if defined(UKERNEL)
  #include "afs/sysincludes.h"
***************
*** 185,191 ****
      }
  #endif
  
! #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_USR_LINUX20_ENV) && !defined(AFS_XBSD_ENV)
      /* handle smoothly the case where no AFS system calls exists (yet) */
      old = (int (*)())signal(SIGSYS, SIG_IGN);
  #endif
--- 185,191 ----
      }
  #endif
  
! #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_USR_LINUX20_ENV) && (!defined(AFS_XBSD_ENV) || defined(AFS_FBSD_ENV))
      /* handle smoothly the case where no AFS system calls exists (yet) */
      old = (int (*)())signal(SIGSYS, SIG_IGN);
  #endif
Index: openafs/src/libafs/MakefileProto.FBSD.in
diff -c openafs/src/libafs/MakefileProto.FBSD.in:1.27.4.4 openafs/src/libafs/MakefileProto.FBSD.in:1.27.4.5
*** openafs/src/libafs/MakefileProto.FBSD.in:1.27.4.4	Mon Dec 15 15:51:09 2008
--- openafs/src/libafs/MakefileProto.FBSD.in	Mon Jan 12 09:33:27 2009
***************
*** 30,35 ****
--- 30,39 ----
  # System specific build commands and flags
  KSRC = @BSD_KERNEL_PATH@
  KBLD = @BSD_KERNEL_BUILD@
+ <amd64_fbsd_70 amd64_fbsd_71 amd64_fbsd_80>
+ KOPTS = -fPIC
+ <all>
+ 
  KDEFS=-Wall -nostdinc -I/usr/include -D_KERNEL -DKLD_MODULE \
  	-elf \
  <i386_fbsd_42 i386_fbsd_43 i386_fbsd_44 i386_fbsd_45 i386_fbsd_46 i386_fbsd_47>
***************
*** 42,50 ****
  	-mno-mmx -mno-3dnow -mno-sse -mno-sse2 \
  <all -i386_fbsd_42 -i386_fbsd_43 -i386_fbsd_44 -i386_fbsd_45 -i386_fbsd_46 -i386_fbsd_47>
  	-mno-align-long-strings -fno-common -ffreestanding \
! 	-I${KBLD} -include opt_global.h -fno-strict-aliasing \
! <amd64_fbsd_70 amd64_fbsd_71 amd64_fbsd_80>
! KOPTS=-fPIC
  <all>
  
  DBUG = -O2
--- 46,52 ----
  	-mno-mmx -mno-3dnow -mno-sse -mno-sse2 \
  <all -i386_fbsd_42 -i386_fbsd_43 -i386_fbsd_44 -i386_fbsd_45 -i386_fbsd_46 -i386_fbsd_47>
  	-mno-align-long-strings -fno-common -ffreestanding \
! 	-I${KBLD} -include opt_global.h -fno-strict-aliasing
  <all>
  
  DBUG = -O2
Index: openafs/src/libafsrpc/afsrpc.def
diff -c openafs/src/libafsrpc/afsrpc.def:1.11.4.11 openafs/src/libafsrpc/afsrpc.def:1.11.4.12
*** openafs/src/libafsrpc/afsrpc.def:1.11.4.11	Mon Dec 29 17:38:29 2008
--- openafs/src/libafsrpc/afsrpc.def	Sun Jan 11 00:56:07 2009
***************
*** 237,242 ****
--- 237,244 ----
          rx_GetMinUdpBufSize                     @242
          rx_SetUdpBufSize                        @243        
          rx_getAllAddrMaskMtu                    @244        
+         rx_stats_active                         @245 DATA
+         rx_StatsOnOff                           @246
  
  ; for performance testing
          rx_TSFPQGlobSize                        @2001 DATA
Index: openafs/src/rx/Makefile.in
diff -c openafs/src/rx/Makefile.in:1.16 openafs/src/rx/Makefile.in:1.16.2.1
*** openafs/src/rx/Makefile.in:1.16	Thu Mar  9 01:34:48 2006
--- openafs/src/rx/Makefile.in	Tue Jan 13 11:26:16 2009
***************
*** 8,14 ****
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=${COMMON_CFLAGS} ${XCFLAGS} ${ARCHFLAGS} -DRXDEBUG
  
  #
  # Generic xdr objects (or, at least, xdr stuff that's not newly defined for rx).
--- 8,14 ----
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=${COMMON_CFLAGS} ${XCFLAGS} ${ARCHFLAGS} ${RXDEBUG}
  
  #
  # Generic xdr objects (or, at least, xdr stuff that's not newly defined for rx).
Index: openafs/src/rx/rx.c
diff -c openafs/src/rx/rx.c:1.97.2.42 openafs/src/rx/rx.c:1.97.2.48
*** openafs/src/rx/rx.c:1.97.2.42	Mon Dec 29 17:38:29 2008
--- openafs/src/rx/rx.c	Wed Jan 14 01:34:19 2009
***************
*** 17,23 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx.c,v 1.97.2.42 2008/12/29 22:38:29 jaltman Exp $");
  
  #ifdef KERNEL
  #include "afs/sysincludes.h"
--- 17,23 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx.c,v 1.97.2.48 2009/01/14 06:34:19 jaltman Exp $");
  
  #ifdef KERNEL
  #include "afs/sysincludes.h"
***************
*** 162,224 ****
   * to ease NT porting
   */
  
! extern pthread_mutex_t rx_stats_mutex;
! extern pthread_mutex_t des_init_mutex;
! extern pthread_mutex_t des_random_mutex;
! extern pthread_mutex_t rx_clock_mutex;
! extern pthread_mutex_t rxi_connCacheMutex;
! extern pthread_mutex_t rx_event_mutex;
! extern pthread_mutex_t osi_malloc_mutex;
! extern pthread_mutex_t event_handler_mutex;
! extern pthread_mutex_t listener_mutex;
! extern pthread_mutex_t rx_if_init_mutex;
! extern pthread_mutex_t rx_if_mutex;
! extern pthread_mutex_t rxkad_client_uid_mutex;
! extern pthread_mutex_t rxkad_random_mutex;
! 
! extern pthread_cond_t rx_event_handler_cond;
! extern pthread_cond_t rx_listener_cond;
! 
! static pthread_mutex_t epoch_mutex;
! static pthread_mutex_t rx_init_mutex;
! static pthread_mutex_t rx_debug_mutex;
! static pthread_mutex_t rx_rpc_stats;
  
  static void
  rxi_InitPthread(void)
  {
!     assert(pthread_mutex_init(&rx_clock_mutex, (const pthread_mutexattr_t *)0)
! 	   == 0);
!     assert(pthread_mutex_init(&rx_stats_mutex, (const pthread_mutexattr_t *)0)
! 	   == 0);
!     assert(pthread_mutex_init
! 	   (&rxi_connCacheMutex, (const pthread_mutexattr_t *)0) == 0);
!     assert(pthread_mutex_init(&rx_init_mutex, (const pthread_mutexattr_t *)0)
! 	   == 0);
!     assert(pthread_mutex_init(&epoch_mutex, (const pthread_mutexattr_t *)0) ==
! 	   0);
!     assert(pthread_mutex_init(&rx_event_mutex, (const pthread_mutexattr_t *)0)
! 	   == 0);
!     assert(pthread_mutex_init(&des_init_mutex, (const pthread_mutexattr_t *)0)
! 	   == 0);
!     assert(pthread_mutex_init
! 	   (&des_random_mutex, (const pthread_mutexattr_t *)0) == 0);
!     assert(pthread_mutex_init
! 	   (&osi_malloc_mutex, (const pthread_mutexattr_t *)0) == 0);
!     assert(pthread_mutex_init
! 	   (&event_handler_mutex, (const pthread_mutexattr_t *)0) == 0);
!     assert(pthread_mutex_init(&listener_mutex, (const pthread_mutexattr_t *)0)
! 	   == 0);
!     assert(pthread_mutex_init
! 	   (&rx_if_init_mutex, (const pthread_mutexattr_t *)0) == 0);
!     assert(pthread_mutex_init(&rx_if_mutex, (const pthread_mutexattr_t *)0) ==
! 	   0);
!     assert(pthread_mutex_init
! 	   (&rxkad_client_uid_mutex, (const pthread_mutexattr_t *)0) == 0);
!     assert(pthread_mutex_init
! 	   (&rxkad_random_mutex, (const pthread_mutexattr_t *)0) == 0);
!     assert(pthread_mutex_init(&rx_debug_mutex, (const pthread_mutexattr_t *)0)
! 	   == 0);
  
      assert(pthread_cond_init
  	   (&rx_event_handler_cond, (const pthread_condattr_t *)0) == 0);
--- 162,216 ----
   * to ease NT porting
   */
  
! extern afs_kmutex_t rx_stats_mutex;
! extern afs_kmutex_t rx_waiting_mutex;
! extern afs_kmutex_t rx_quota_mutex;
! extern afs_kmutex_t rx_pthread_mutex;
! extern afs_kmutex_t rx_packets_mutex;
! extern afs_kmutex_t des_init_mutex;
! extern afs_kmutex_t des_random_mutex;
! extern afs_kmutex_t rx_clock_mutex;
! extern afs_kmutex_t rxi_connCacheMutex;
! extern afs_kmutex_t rx_event_mutex;
! extern afs_kmutex_t osi_malloc_mutex;
! extern afs_kmutex_t event_handler_mutex;
! extern afs_kmutex_t listener_mutex;
! extern afs_kmutex_t rx_if_init_mutex;
! extern afs_kmutex_t rx_if_mutex;
! extern afs_kmutex_t rxkad_client_uid_mutex;
! extern afs_kmutex_t rxkad_random_mutex;
! 
! extern afs_kcondvar_t rx_event_handler_cond;
! extern afs_kcondvar_t rx_listener_cond;
! 
! static afs_kmutex_t epoch_mutex;
! static afs_kmutex_t rx_init_mutex;
! static afs_kmutex_t rx_debug_mutex;
! static afs_kmutex_t rx_rpc_stats;
  
  static void
  rxi_InitPthread(void)
  {
!     MUTEX_INIT(&rx_clock_mutex, "clock", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&rx_stats_mutex, "stats", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&rx_waiting_mutex, "waiting", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&rx_quota_mutex, "quota", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&rx_pthread_mutex, "pthread", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&rx_packets_mutex, "packets", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&epoch_mutex, "epoch", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&rx_init_mutex, "init", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&rx_event_mutex, "event", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&des_init_mutex, "des", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&des_random_mutex, "random", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&osi_malloc_mutex, "malloc", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&event_handler_mutex, "event handler", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&rxi_connCacheMutex, "conn cache", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&listener_mutex, "listener", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&rx_if_init_mutex, "if init", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&rx_if_mutex, "if", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&rxkad_client_uid_mutex, "uid", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&rxkad_random_mutex, "rxkad random", MUTEX_DEFAULT, 0);
!     MUTEX_INIT(&rx_debug_mutex, "debug", MUTEX_DEFAULT, 0);
  
      assert(pthread_cond_init
  	   (&rx_event_handler_cond, (const pthread_condattr_t *)0) == 0);
***************
*** 254,272 ****
  assert(pthread_once(&rx_once_init, rxi_InitPthread)==0)
  /*
   * The rx_stats_mutex mutex protects the following global variables:
-  * rxi_dataQuota
-  * rxi_minDeficit
-  * rxi_availProcs
-  * rxi_totalMin
   * rxi_lowConnRefCount
   * rxi_lowPeerRefCount
   * rxi_nCalls
   * rxi_Alloccnt
   * rxi_Allocsize
-  * rx_nFreePackets
   * rx_tq_debug
   * rx_stats
   */
  #else
  #define INIT_PTHREAD_LOCKS
  #endif
--- 246,285 ----
  assert(pthread_once(&rx_once_init, rxi_InitPthread)==0)
  /*
   * The rx_stats_mutex mutex protects the following global variables:
   * rxi_lowConnRefCount
   * rxi_lowPeerRefCount
   * rxi_nCalls
   * rxi_Alloccnt
   * rxi_Allocsize
   * rx_tq_debug
   * rx_stats
   */
+ 
+ /*
+  * The rx_quota_mutex mutex protects the following global variables:
+  * rxi_dataQuota
+  * rxi_minDeficit
+  * rxi_availProcs
+  * rxi_totalMin
+  */
+ 
+ /* 
+  * The rx_freePktQ_lock protects the following global variables:
+  * rx_nFreePackets 
+  */
+ 
+ /*
+  * The rx_packets_mutex mutex protects the following global variables:
+  * rx_nPackets
+  * rx_TSFPQLocalMax
+  * rx_TSFPQGlobSize
+  * rx_TSFPQMaxProcs
+  */
+ 
+ /*
+  * The rx_pthread_mutex mutex protects the following global variables:
+  * rxi_pthread_hinum
+  */
  #else
  #define INIT_PTHREAD_LOCKS
  #endif
***************
*** 368,375 ****
   * rx_epoch
   */
  
! #define LOCK_EPOCH assert(pthread_mutex_lock(&epoch_mutex)==0)
! #define UNLOCK_EPOCH assert(pthread_mutex_unlock(&epoch_mutex)==0)
  #else
  #define LOCK_EPOCH
  #define UNLOCK_EPOCH
--- 381,388 ----
   * rx_epoch
   */
  
! #define LOCK_EPOCH MUTEX_ENTER(&epoch_mutex)
! #define UNLOCK_EPOCH MUTEX_EXIT(&epoch_mutex)
  #else
  #define LOCK_EPOCH
  #define UNLOCK_EPOCH
***************
*** 399,406 ****
   * rxinit_status
   */
  
! #define LOCK_RX_INIT assert(pthread_mutex_lock(&rx_init_mutex)==0)
! #define UNLOCK_RX_INIT assert(pthread_mutex_unlock(&rx_init_mutex)==0)
  #else
  #define LOCK_RX_INIT
  #define UNLOCK_RX_INIT
--- 412,419 ----
   * rxinit_status
   */
  
! #define LOCK_RX_INIT MUTEX_ENTER(&rx_init_mutex)
! #define UNLOCK_RX_INIT MUTEX_EXIT(&rx_init_mutex)
  #else
  #define LOCK_RX_INIT
  #define UNLOCK_RX_INIT
***************
*** 459,464 ****
--- 472,481 ----
      rxdb_init();
  #endif /* RX_LOCKS_DB */
      MUTEX_INIT(&rx_stats_mutex, "rx_stats_mutex", MUTEX_DEFAULT, 0);
+     MUTEX_INIT(&rx_waiting_mutex, "rx_waiting_mutex", MUTEX_DEFAULT, 0);
+     MUTEX_INIT(&rx_quota_mutex, "rx_quota_mutex", MUTEX_DEFAULT, 0);
+     MUTEX_INIT(&rx_pthread_mutex, "rx_pthread_mutex", MUTEX_DEFAULT, 0);
+     MUTEX_INIT(&rx_packets_mutex, "rx_packets_mutex", MUTEX_DEFAULT, 0);
      MUTEX_INIT(&rx_rpc_stats, "rx_rpc_stats", MUTEX_DEFAULT, 0);
      MUTEX_INIT(&rx_freePktQ_lock, "rx_freePktQ_lock", MUTEX_DEFAULT, 0);
      MUTEX_INIT(&freeSQEList_lock, "freeSQEList lock", MUTEX_DEFAULT, 0);
***************
*** 540,548 ****
      rx_SetEpoch(tv.tv_sec);	/* Start time of this package, rxkad
  				 * will provide a randomer value. */
  #endif
!     MUTEX_ENTER(&rx_stats_mutex);
!     rxi_dataQuota += rx_extraQuota;	/* + extra pkts caller asked to rsrv */
!     MUTEX_EXIT(&rx_stats_mutex);
      /* *Slightly* random start time for the cid.  This is just to help
       * out with the hashing function at the peer */
      rx_nextCid = ((tv.tv_sec ^ tv.tv_usec) << RX_CIDSHIFT);
--- 557,565 ----
      rx_SetEpoch(tv.tv_sec);	/* Start time of this package, rxkad
  				 * will provide a randomer value. */
  #endif
!     MUTEX_ENTER(&rx_quota_mutex);
!     rxi_dataQuota += rx_extraQuota; /* + extra pkts caller asked to rsrv */
!     MUTEX_EXIT(&rx_quota_mutex);
      /* *Slightly* random start time for the cid.  This is just to help
       * out with the hashing function at the peer */
      rx_nextCid = ((tv.tv_sec ^ tv.tv_usec) << RX_CIDSHIFT);
***************
*** 604,610 ****
      /* otherwise, can use only if there are enough to allow everyone
       * to go to their min quota after this guy starts.
       */
!     MUTEX_ENTER(&rx_stats_mutex);
      if ((aservice->nRequestsRunning < aservice->minProcs)
  	|| (rxi_availProcs > rxi_minDeficit)) {
  	aservice->nRequestsRunning++;
--- 621,628 ----
      /* otherwise, can use only if there are enough to allow everyone
       * to go to their min quota after this guy starts.
       */
! 
!     MUTEX_ENTER(&rx_quota_mutex);
      if ((aservice->nRequestsRunning < aservice->minProcs)
  	|| (rxi_availProcs > rxi_minDeficit)) {
  	aservice->nRequestsRunning++;
***************
*** 613,622 ****
  	if (aservice->nRequestsRunning <= aservice->minProcs)
  	    rxi_minDeficit--;
  	rxi_availProcs--;
! 	MUTEX_EXIT(&rx_stats_mutex);
  	return 1;
      }
!     MUTEX_EXIT(&rx_stats_mutex);
  
      return 0;
  }
--- 631,640 ----
  	if (aservice->nRequestsRunning <= aservice->minProcs)
  	    rxi_minDeficit--;
  	rxi_availProcs--;
! 	MUTEX_EXIT(&rx_quota_mutex);
  	return 1;
      }
!     MUTEX_EXIT(&rx_quota_mutex);
  
      return 0;
  }
***************
*** 625,635 ****
  ReturnToServerPool(register struct rx_service *aservice)
  {
      aservice->nRequestsRunning--;
!     MUTEX_ENTER(&rx_stats_mutex);
      if (aservice->nRequestsRunning < aservice->minProcs)
  	rxi_minDeficit++;
      rxi_availProcs++;
!     MUTEX_EXIT(&rx_stats_mutex);
  }
  
  #else /* RX_ENABLE_LOCKS */
--- 643,653 ----
  ReturnToServerPool(register struct rx_service *aservice)
  {
      aservice->nRequestsRunning--;
!     MUTEX_ENTER(&rx_quota_mutex);
      if (aservice->nRequestsRunning < aservice->minProcs)
  	rxi_minDeficit++;
      rxi_availProcs++;
!     MUTEX_EXIT(&rx_quota_mutex);
  }
  
  #else /* RX_ENABLE_LOCKS */
***************
*** 730,742 ****
  	service = rx_services[i];
  	if (service == (struct rx_service *)0)
  	    break;
! 	MUTEX_ENTER(&rx_stats_mutex);
  	rxi_totalMin += service->minProcs;
  	/* below works even if a thread is running, since minDeficit would
  	 * still have been decremented and later re-incremented.
  	 */
  	rxi_minDeficit += service->minProcs;
! 	MUTEX_EXIT(&rx_stats_mutex);
      }
  
      /* Turn on reaping of idle server connections */
--- 748,760 ----
  	service = rx_services[i];
  	if (service == (struct rx_service *)0)
  	    break;
! 	MUTEX_ENTER(&rx_quota_mutex);
  	rxi_totalMin += service->minProcs;
  	/* below works even if a thread is running, since minDeficit would
  	 * still have been decremented and later re-incremented.
  	 */
  	rxi_minDeficit += service->minProcs;
! 	MUTEX_EXIT(&rx_quota_mutex);
      }
  
      /* Turn on reaping of idle server connections */
***************
*** 829,835 ****
      conn->refCount++;		/* no lock required since only this thread knows... */
      conn->next = rx_connHashTable[hashindex];
      rx_connHashTable[hashindex] = conn;
!     rx_MutexIncrement(rx_stats.nClientConns, rx_stats_mutex);
      MUTEX_EXIT(&rx_connHashTable_lock);
      USERPRI;
      return conn;
--- 847,854 ----
      conn->refCount++;		/* no lock required since only this thread knows... */
      conn->next = rx_connHashTable[hashindex];
      rx_connHashTable[hashindex] = conn;
!     if (rx_stats_active)
!         rx_MutexIncrement(rx_stats.nClientConns, rx_stats_mutex);
      MUTEX_EXIT(&rx_connHashTable_lock);
      USERPRI;
      return conn;
***************
*** 871,888 ****
  	conn->peer->idleWhen = clock_Sec();
  	if (conn->peer->refCount < 1) {
  	    conn->peer->refCount = 1;
! 	    MUTEX_ENTER(&rx_stats_mutex);
! 	    rxi_lowPeerRefCount++;
! 	    MUTEX_EXIT(&rx_stats_mutex);
  	}
      }
      conn->peer->refCount--;
      MUTEX_EXIT(&rx_peerHashTable_lock);
  
!     if (conn->type == RX_SERVER_CONNECTION)
! 	rx_MutexDecrement(rx_stats.nServerConns, rx_stats_mutex);
!     else
! 	rx_MutexDecrement(rx_stats.nClientConns, rx_stats_mutex);
  #ifndef KERNEL
      if (conn->specific) {
  	int i;
--- 890,912 ----
  	conn->peer->idleWhen = clock_Sec();
  	if (conn->peer->refCount < 1) {
  	    conn->peer->refCount = 1;
!             if (rx_stats_active) {
!                 MUTEX_ENTER(&rx_stats_mutex);
!                 rxi_lowPeerRefCount++;
!                 MUTEX_EXIT(&rx_stats_mutex);
!             }
  	}
      }
      conn->peer->refCount--;
      MUTEX_EXIT(&rx_peerHashTable_lock);
  
!     if (rx_stats_active)
!     {
!         if (conn->type == RX_SERVER_CONNECTION)
!             rx_MutexDecrement(rx_stats.nServerConns, rx_stats_mutex);
!         else
!             rx_MutexDecrement(rx_stats.nClientConns, rx_stats_mutex);
!     }
  #ifndef KERNEL
      if (conn->specific) {
  	int i;
***************
*** 939,947 ****
      if (conn->refCount > 0)
  	conn->refCount--;
      else {
! 	MUTEX_ENTER(&rx_stats_mutex);
! 	rxi_lowConnRefCount++;
! 	MUTEX_EXIT(&rx_stats_mutex);
      }
  
      if ((conn->refCount > 0) || (conn->flags & RX_CONN_BUSY)) {
--- 963,973 ----
      if (conn->refCount > 0)
  	conn->refCount--;
      else {
!         if (rx_stats_active) {
!             MUTEX_ENTER(&rx_stats_mutex);
!             rxi_lowConnRefCount++;
!             MUTEX_EXIT(&rx_stats_mutex);
!         }
      }
  
      if ((conn->refCount > 0) || (conn->flags & RX_CONN_BUSY)) {
***************
*** 1477,1485 ****
  	    (*tservice->afterProc) (call, code);
  
  	rx_EndCall(call, code);
! 	MUTEX_ENTER(&rx_stats_mutex);
! 	rxi_nCalls++;
! 	MUTEX_EXIT(&rx_stats_mutex);
      }
  }
  
--- 1503,1513 ----
  	    (*tservice->afterProc) (call, code);
  
  	rx_EndCall(call, code);
!         if (rx_stats_active) {
!             MUTEX_ENTER(&rx_stats_mutex);
!             rxi_nCalls++;
!             MUTEX_EXIT(&rx_stats_mutex);
!         }
      }
  }
  
***************
*** 1631,1639 ****
  
  	    if (call->flags & RX_CALL_WAIT_PROC) {
  		call->flags &= ~RX_CALL_WAIT_PROC;
! 		MUTEX_ENTER(&rx_stats_mutex);
! 		rx_nWaiting--;
! 		MUTEX_EXIT(&rx_stats_mutex);
  	    }
  
  	    if (call->state != RX_STATE_PRECALL || call->error) {
--- 1659,1667 ----
  
  	    if (call->flags & RX_CALL_WAIT_PROC) {
  		call->flags &= ~RX_CALL_WAIT_PROC;
!                 MUTEX_ENTER(&rx_waiting_mutex);
!                 rx_nWaiting--;
!                 MUTEX_EXIT(&rx_waiting_mutex);
  	    }
  
  	    if (call->state != RX_STATE_PRECALL || call->error) {
***************
*** 2013,2021 ****
      call->nLeft = call->nFree = call->curlen = 0;
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
! #ifdef DEBUG
      call->iovqc -=
! #endif /* DEBUG */
          rxi_FreePackets(0, &call->iovq);
  
      CALL_RELE(call, RX_CALL_REFCOUNT_BEGIN);
--- 2041,2049 ----
      call->nLeft = call->nFree = call->curlen = 0;
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
! #ifdef RXDEBUG_PACKET
      call->iovqc -=
! #endif /* RXDEBUG_PACKET */
          rxi_FreePackets(0, &call->iovq);
  
      CALL_RELE(call, RX_CALL_REFCOUNT_BEGIN);
***************
*** 2178,2184 ****
  	call = queue_First(&rx_freeCallQueue, rx_call);
  #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
  	queue_Remove(call);
!         rx_MutexDecrement(rx_stats.nFreeCallStructs, rx_stats_mutex);
  	MUTEX_EXIT(&rx_freeCallQueue_lock);
  	MUTEX_ENTER(&call->lock);
  	CLEAR_CALL_QUEUE_LOCK(call);
--- 2206,2213 ----
  	call = queue_First(&rx_freeCallQueue, rx_call);
  #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
  	queue_Remove(call);
!         if (rx_stats_active)
!             rx_MutexDecrement(rx_stats.nFreeCallStructs, rx_stats_mutex);
  	MUTEX_EXIT(&rx_freeCallQueue_lock);
  	MUTEX_ENTER(&call->lock);
  	CLEAR_CALL_QUEUE_LOCK(call);
***************
*** 2195,2205 ****
      } else {
  
  	call = (struct rx_call *)rxi_Alloc(sizeof(struct rx_call));
! #ifdef DEBUG
          call->allNextp = rx_allCallsp;
          rx_allCallsp = call;
          call->call_id = 
! #endif /* DEBUG */
              rx_MutexIncrement(rx_stats.nCallStructs, rx_stats_mutex);
          
          MUTEX_EXIT(&rx_freeCallQueue_lock);
--- 2224,2234 ----
      } else {
  
  	call = (struct rx_call *)rxi_Alloc(sizeof(struct rx_call));
! #ifdef RXDEBUG_PACKET
          call->allNextp = rx_allCallsp;
          rx_allCallsp = call;
          call->call_id = 
! #endif /* RXDEBUG_PACKET */
              rx_MutexIncrement(rx_stats.nCallStructs, rx_stats_mutex);
          
          MUTEX_EXIT(&rx_freeCallQueue_lock);
***************
*** 2213,2221 ****
  	queue_Init(&call->tq);
  	queue_Init(&call->rq);
  	queue_Init(&call->iovq);
! #ifdef DEBUG
          call->rqc = call->tqc = call->iovqc = 0;
! #endif /* DEBUG */
  	/* Bind the call to its connection structure (prereq for reset) */
  	call->conn = conn;
  	rxi_ResetCall(call, 1);
--- 2242,2250 ----
  	queue_Init(&call->tq);
  	queue_Init(&call->rq);
  	queue_Init(&call->iovq);
! #ifdef RXDEBUG_PACKET
          call->rqc = call->tqc = call->iovqc = 0;
! #endif /* RXDEBUG_PACKET */
  	/* Bind the call to its connection structure (prereq for reset) */
  	call->conn = conn;
  	rxi_ResetCall(call, 1);
***************
*** 2273,2279 ****
  #else /* AFS_GLOBAL_RXLOCK_KERNEL */
      queue_Append(&rx_freeCallQueue, call);
  #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
!     rx_MutexIncrement(rx_stats.nFreeCallStructs, rx_stats_mutex);
      MUTEX_EXIT(&rx_freeCallQueue_lock);
  
      /* Destroy the connection if it was previously slated for
--- 2302,2309 ----
  #else /* AFS_GLOBAL_RXLOCK_KERNEL */
      queue_Append(&rx_freeCallQueue, call);
  #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
!     if (rx_stats_active)
!         rx_MutexIncrement(rx_stats.nFreeCallStructs, rx_stats_mutex);
      MUTEX_EXIT(&rx_freeCallQueue_lock);
  
      /* Destroy the connection if it was previously slated for
***************
*** 2309,2315 ****
  {
      register char *p;
  
!     rx_MutexAdd1Increment2(rxi_Allocsize, (afs_int32)size, rxi_Alloccnt, rx_stats_mutex);
  
  p = (char *)
  #if defined(KERNEL) && !defined(UKERNEL) && defined(AFS_FBSD80_ENV)
--- 2339,2346 ----
  {
      register char *p;
  
!     if (rx_stats_active)
!         rx_MutexAdd1Increment2(rxi_Allocsize, (afs_int32)size, rxi_Alloccnt, rx_stats_mutex);
  
  p = (char *)
  #if defined(KERNEL) && !defined(UKERNEL) && defined(AFS_FBSD80_ENV)
***************
*** 2326,2332 ****
  void
  rxi_Free(void *addr, register size_t size)
  {
!     rx_MutexAdd1Decrement2(rxi_Allocsize, -(afs_int32)size, rxi_Alloccnt, rx_stats_mutex);
      osi_Free(addr, size);
  }
  
--- 2357,2364 ----
  void
  rxi_Free(void *addr, register size_t size)
  {
!     if (rx_stats_active)
!         rx_MutexAdd1Decrement2(rxi_Allocsize, -(afs_int32)size, rxi_Alloccnt, rx_stats_mutex);
      osi_Free(addr, size);
  }
  
***************
*** 2396,2402 ****
  	    pp->next = rx_peerHashTable[hashIndex];
  	    rx_peerHashTable[hashIndex] = pp;
  	    rxi_InitPeerParams(pp);
! 	    rx_MutexIncrement(rx_stats.nPeerStructs, rx_stats_mutex);
  	}
      }
      if (pp && create) {
--- 2428,2435 ----
  	    pp->next = rx_peerHashTable[hashIndex];
  	    rx_peerHashTable[hashIndex] = pp;
  	    rxi_InitPeerParams(pp);
!             if (rx_stats_active)
!                 rx_MutexIncrement(rx_stats.nPeerStructs, rx_stats_mutex);
  	}
      }
      if (pp && create) {
***************
*** 2506,2512 ****
  	/* XXXX Connection timeout? */
  	if (service->newConnProc)
  	    (*service->newConnProc) (conn);
!         rx_MutexIncrement(rx_stats.nServerConns, rx_stats_mutex);
      }
  
      MUTEX_ENTER(&conn->conn_data_lock);
--- 2539,2546 ----
  	/* XXXX Connection timeout? */
  	if (service->newConnProc)
  	    (*service->newConnProc) (conn);
!         if (rx_stats_active)
!             rx_MutexIncrement(rx_stats.nServerConns, rx_stats_mutex);
      }
  
      MUTEX_ENTER(&conn->conn_data_lock);
***************
*** 2704,2710 ****
  	     * then, since this is a client connection we're getting data for
  	     * it must be for the previous call.
  	     */
! 	    rx_MutexIncrement(rx_stats.spuriousPacketsRead, rx_stats_mutex);
  	    MUTEX_ENTER(&conn->conn_data_lock);
  	    conn->refCount--;
  	    MUTEX_EXIT(&conn->conn_data_lock);
--- 2738,2745 ----
  	     * then, since this is a client connection we're getting data for
  	     * it must be for the previous call.
  	     */
!             if (rx_stats_active)
!                 rx_MutexIncrement(rx_stats.spuriousPacketsRead, rx_stats_mutex);
  	    MUTEX_ENTER(&conn->conn_data_lock);
  	    conn->refCount--;
  	    MUTEX_EXIT(&conn->conn_data_lock);
***************
*** 2716,2722 ****
  
      if (type == RX_SERVER_CONNECTION) {	/* We're the server */
  	if (np->header.callNumber < currentCallNumber) {
! 	    rx_MutexIncrement(rx_stats.spuriousPacketsRead, rx_stats_mutex);
  #ifdef	RX_ENABLE_LOCKS
  	    if (call)
  		MUTEX_EXIT(&call->lock);
--- 2751,2758 ----
  
      if (type == RX_SERVER_CONNECTION) {	/* We're the server */
  	if (np->header.callNumber < currentCallNumber) {
!             if (rx_stats_active)
!                 rx_MutexIncrement(rx_stats.spuriousPacketsRead, rx_stats_mutex);
  #ifdef	RX_ENABLE_LOCKS
  	    if (call)
  		MUTEX_EXIT(&call->lock);
***************
*** 2731,2739 ****
  	    call = rxi_NewCall(conn, channel);
  	    MUTEX_EXIT(&conn->conn_call_lock);
  	    *call->callNumber = np->header.callNumber;
  	    if (np->header.callNumber == 0) 
  		dpf(("RecPacket call 0 %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %lx resend %d.%0.3d len %d", np->header.serial, rx_packetTypes[np->header.type - 1], ntohl(conn->peer->host), ntohs(conn->peer->port), np->header.serial, np->header.epoch, np->header.cid, np->header.callNumber, np->header.seq, np->header.flags, (unsigned long)np, np->retryTime.sec, np->retryTime.usec / 1000, np->length));
! 
  	    call->state = RX_STATE_PRECALL;
  	    clock_GetTime(&call->queueTime);
  	    hzero(call->bytesSent);
--- 2767,2776 ----
  	    call = rxi_NewCall(conn, channel);
  	    MUTEX_EXIT(&conn->conn_call_lock);
  	    *call->callNumber = np->header.callNumber;
+ #ifdef RXDEBUG
  	    if (np->header.callNumber == 0) 
  		dpf(("RecPacket call 0 %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %lx resend %d.%0.3d len %d", np->header.serial, rx_packetTypes[np->header.type - 1], ntohl(conn->peer->host), ntohs(conn->peer->port), np->header.serial, np->header.epoch, np->header.cid, np->header.callNumber, np->header.seq, np->header.flags, (unsigned long)np, np->retryTime.sec, np->retryTime.usec / 1000, np->length));
! #endif
  	    call->state = RX_STATE_PRECALL;
  	    clock_GetTime(&call->queueTime);
  	    hzero(call->bytesSent);
***************
*** 2751,2757 ****
  		MUTEX_ENTER(&conn->conn_data_lock);
  		conn->refCount--;
  		MUTEX_EXIT(&conn->conn_data_lock);
!                 rx_MutexIncrement(rx_stats.nBusies, rx_stats_mutex);
  		return tp;
  	    }
  	    rxi_KeepAliveOn(call);
--- 2788,2795 ----
  		MUTEX_ENTER(&conn->conn_data_lock);
  		conn->refCount--;
  		MUTEX_EXIT(&conn->conn_data_lock);
!                 if (rx_stats_active)
!                     rx_MutexIncrement(rx_stats.nBusies, rx_stats_mutex);
  		return tp;
  	    }
  	    rxi_KeepAliveOn(call);
***************
*** 2794,2802 ****
  	    }
  	    rxi_ResetCall(call, 0);
  	    *call->callNumber = np->header.callNumber;
  	    if (np->header.callNumber == 0) 
  		dpf(("RecPacket call 0 %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %lx resend %d.%0.3d len %d", np->header.serial, rx_packetTypes[np->header.type - 1], ntohl(conn->peer->host), ntohs(conn->peer->port), np->header.serial, np->header.epoch, np->header.cid, np->header.callNumber, np->header.seq, np->header.flags, (unsigned long)np, np->retryTime.sec, np->retryTime.usec / 1000, np->length));
! 
  	    call->state = RX_STATE_PRECALL;
  	    clock_GetTime(&call->queueTime);
  	    hzero(call->bytesSent);
--- 2832,2841 ----
  	    }
  	    rxi_ResetCall(call, 0);
  	    *call->callNumber = np->header.callNumber;
+ #ifdef RXDEBUG
  	    if (np->header.callNumber == 0) 
  		dpf(("RecPacket call 0 %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %lx resend %d.%0.3d len %d", np->header.serial, rx_packetTypes[np->header.type - 1], ntohl(conn->peer->host), ntohs(conn->peer->port), np->header.serial, np->header.epoch, np->header.cid, np->header.callNumber, np->header.seq, np->header.flags, (unsigned long)np, np->retryTime.sec, np->retryTime.usec / 1000, np->length));
! #endif
  	    call->state = RX_STATE_PRECALL;
  	    clock_GetTime(&call->queueTime);
  	    hzero(call->bytesSent);
***************
*** 2814,2820 ****
  		MUTEX_ENTER(&conn->conn_data_lock);
  		conn->refCount--;
  		MUTEX_EXIT(&conn->conn_data_lock);
!                 rx_MutexIncrement(rx_stats.nBusies, rx_stats_mutex);
  		return tp;
  	    }
  	    rxi_KeepAliveOn(call);
--- 2853,2860 ----
  		MUTEX_ENTER(&conn->conn_data_lock);
  		conn->refCount--;
  		MUTEX_EXIT(&conn->conn_data_lock);
!                 if (rx_stats_active)
!                     rx_MutexIncrement(rx_stats.nBusies, rx_stats_mutex);
  		return tp;
  	    }
  	    rxi_KeepAliveOn(call);
***************
*** 2825,2831 ****
  	/* Ignore all incoming acknowledgements for calls in DALLY state */
  	if (call && (call->state == RX_STATE_DALLY)
  	    && (np->header.type == RX_PACKET_TYPE_ACK)) {
! 	    rx_MutexIncrement(rx_stats.ignorePacketDally, rx_stats_mutex);
  #ifdef  RX_ENABLE_LOCKS
  	    if (call) {
  		MUTEX_EXIT(&call->lock);
--- 2865,2872 ----
  	/* Ignore all incoming acknowledgements for calls in DALLY state */
  	if (call && (call->state == RX_STATE_DALLY)
  	    && (np->header.type == RX_PACKET_TYPE_ACK)) {
!             if (rx_stats_active)
!                 rx_MutexIncrement(rx_stats.ignorePacketDally, rx_stats_mutex);
  #ifdef  RX_ENABLE_LOCKS
  	    if (call) {
  		MUTEX_EXIT(&call->lock);
***************
*** 2840,2846 ****
  	/* Ignore anything that's not relevant to the current call.  If there
  	 * isn't a current call, then no packet is relevant. */
  	if (!call || (np->header.callNumber != currentCallNumber)) {
! 	    rx_MutexIncrement(rx_stats.spuriousPacketsRead, rx_stats_mutex);
  #ifdef	RX_ENABLE_LOCKS
  	    if (call) {
  		MUTEX_EXIT(&call->lock);
--- 2881,2888 ----
  	/* Ignore anything that's not relevant to the current call.  If there
  	 * isn't a current call, then no packet is relevant. */
  	if (!call || (np->header.callNumber != currentCallNumber)) {
!             if (rx_stats_active)
!                 rx_MutexIncrement(rx_stats.spuriousPacketsRead, rx_stats_mutex);
  #ifdef	RX_ENABLE_LOCKS
  	    if (call) {
  		MUTEX_EXIT(&call->lock);
***************
*** 2905,2911 ****
  		 * XXX interact badly with the server-restart detection 
  		 * XXX code in receiveackpacket.  */
  		if (ntohl(rx_GetInt32(np, FIRSTACKOFFSET)) < call->tfirst) {
!                     rx_MutexIncrement(rx_stats.spuriousPacketsRead, rx_stats_mutex);
  		    MUTEX_EXIT(&call->lock);
  		    MUTEX_ENTER(&conn->conn_data_lock);
  		    conn->refCount--;
--- 2947,2954 ----
  		 * XXX interact badly with the server-restart detection 
  		 * XXX code in receiveackpacket.  */
  		if (ntohl(rx_GetInt32(np, FIRSTACKOFFSET)) < call->tfirst) {
!                     if (rx_stats_active)
!                         rx_MutexIncrement(rx_stats.spuriousPacketsRead, rx_stats_mutex);
  		    MUTEX_EXIT(&call->lock);
  		    MUTEX_ENTER(&conn->conn_data_lock);
  		    conn->refCount--;
***************
*** 3063,3069 ****
  TooLow(struct rx_packet *ap, struct rx_call *acall)
  {
      int rc = 0;
!     MUTEX_ENTER(&rx_stats_mutex);
      if (((ap->header.seq != 1) && (acall->flags & RX_CALL_CLEARED)
  	 && (acall->state == RX_STATE_PRECALL))
  	|| ((rx_nFreePackets < rxi_dataQuota + 2)
--- 3106,3113 ----
  TooLow(struct rx_packet *ap, struct rx_call *acall)
  {
      int rc = 0;
! 
!     MUTEX_ENTER(&rx_quota_mutex);
      if (((ap->header.seq != 1) && (acall->flags & RX_CALL_CLEARED)
  	 && (acall->state == RX_STATE_PRECALL))
  	|| ((rx_nFreePackets < rxi_dataQuota + 2)
***************
*** 3071,3077 ****
  		 && (acall->flags & RX_CALL_READER_WAIT)))) {
  	rc = 1;
      }
!     MUTEX_EXIT(&rx_stats_mutex);
      return rc;
  }
  #endif /* KERNEL */
--- 3115,3121 ----
  		 && (acall->flags & RX_CALL_READER_WAIT)))) {
  	rc = 1;
      }
!     MUTEX_EXIT(&rx_quota_mutex);
      return rc;
  }
  #endif /* KERNEL */
***************
*** 3207,3213 ****
      int isFirst;
      struct rx_packet *tnp;
      struct clock when, now;
!     rx_MutexIncrement(rx_stats.dataPacketsRead, rx_stats_mutex);
  
  #ifdef KERNEL
      /* If there are no packet buffers, drop this new packet, unless we can find
--- 3251,3258 ----
      int isFirst;
      struct rx_packet *tnp;
      struct clock when, now;
!     if (rx_stats_active)
!         rx_MutexIncrement(rx_stats.dataPacketsRead, rx_stats_mutex);
  
  #ifdef KERNEL
      /* If there are no packet buffers, drop this new packet, unless we can find
***************
*** 3217,3223 ****
  	MUTEX_ENTER(&rx_freePktQ_lock);
  	rxi_NeedMorePackets = TRUE;
  	MUTEX_EXIT(&rx_freePktQ_lock);
!         rx_MutexIncrement(rx_stats.noPacketBuffersOnRead, rx_stats_mutex);
  	call->rprev = np->header.serial;
  	rxi_calltrace(RX_TRACE_DROP, call);
  	dpf(("packet %x dropped on receipt - quota problems", np));
--- 3262,3269 ----
  	MUTEX_ENTER(&rx_freePktQ_lock);
  	rxi_NeedMorePackets = TRUE;
  	MUTEX_EXIT(&rx_freePktQ_lock);
!         if (rx_stats_active)
!             rx_MutexIncrement(rx_stats.noPacketBuffersOnRead, rx_stats_mutex);
  	call->rprev = np->header.serial;
  	rxi_calltrace(RX_TRACE_DROP, call);
  	dpf(("packet %x dropped on receipt - quota problems", np));
***************
*** 3282,3288 ****
  	    /* Check to make sure it is not a duplicate of one already queued */
  	    if (queue_IsNotEmpty(&call->rq)
  		&& queue_First(&call->rq, rx_packet)->header.seq == seq) {
!                 rx_MutexIncrement(rx_stats.dupPacketsRead, rx_stats_mutex);
  		dpf(("packet %x dropped on receipt - duplicate", np));
  		rxevent_Cancel(call->delayedAckEvent, call,
  			       RX_CALL_REFCOUNT_DELAY);
--- 3328,3335 ----
  	    /* Check to make sure it is not a duplicate of one already queued */
  	    if (queue_IsNotEmpty(&call->rq)
  		&& queue_First(&call->rq, rx_packet)->header.seq == seq) {
!                 if (rx_stats_active)
!                     rx_MutexIncrement(rx_stats.dupPacketsRead, rx_stats_mutex);
  		dpf(("packet %x dropped on receipt - duplicate", np));
  		rxevent_Cancel(call->delayedAckEvent, call,
  			       RX_CALL_REFCOUNT_DELAY);
***************
*** 3297,3305 ****
  	     * the reader once all packets have been processed */
  	    np->flags |= RX_PKTFLAG_RQ;
  	    queue_Prepend(&call->rq, np);
! #ifdef DEBUG
              call->rqc++;
! #endif /* DEBUG */
  	    call->nSoftAcks++;
  	    np = NULL;		/* We can't use this anymore */
  	    newPackets = 1;
--- 3344,3352 ----
  	     * the reader once all packets have been processed */
  	    np->flags |= RX_PKTFLAG_RQ;
  	    queue_Prepend(&call->rq, np);
! #ifdef RXDEBUG_PACKET
              call->rqc++;
! #endif /* RXDEBUG_PACKET */
  	    call->nSoftAcks++;
  	    np = NULL;		/* We can't use this anymore */
  	    newPackets = 1;
***************
*** 3370,3376 ****
  	    /* If the new packet's sequence number has been sent to the
  	     * application already, then this is a duplicate */
  	    if (seq < call->rnext) {
!                 rx_MutexIncrement(rx_stats.dupPacketsRead, rx_stats_mutex);
  		rxevent_Cancel(call->delayedAckEvent, call,
  			       RX_CALL_REFCOUNT_DELAY);
  		np = rxi_SendAck(call, np, serial, RX_ACK_DUPLICATE, istack);
--- 3417,3424 ----
  	    /* If the new packet's sequence number has been sent to the
  	     * application already, then this is a duplicate */
  	    if (seq < call->rnext) {
!                 if (rx_stats_active)
!                     rx_MutexIncrement(rx_stats.dupPacketsRead, rx_stats_mutex);
  		rxevent_Cancel(call->delayedAckEvent, call,
  			       RX_CALL_REFCOUNT_DELAY);
  		np = rxi_SendAck(call, np, serial, RX_ACK_DUPLICATE, istack);
***************
*** 3397,3403 ****
  		 0, queue_Scan(&call->rq, tp, nxp, rx_packet)) {
  		/*Check for duplicate packet */
  		if (seq == tp->header.seq) {
!                     rx_MutexIncrement(rx_stats.dupPacketsRead, rx_stats_mutex);
  		    rxevent_Cancel(call->delayedAckEvent, call,
  				   RX_CALL_REFCOUNT_DELAY);
  		    np = rxi_SendAck(call, np, serial, RX_ACK_DUPLICATE,
--- 3445,3452 ----
  		 0, queue_Scan(&call->rq, tp, nxp, rx_packet)) {
  		/*Check for duplicate packet */
  		if (seq == tp->header.seq) {
!                     if (rx_stats_active)
!                         rx_MutexIncrement(rx_stats.dupPacketsRead, rx_stats_mutex);
  		    rxevent_Cancel(call->delayedAckEvent, call,
  				   RX_CALL_REFCOUNT_DELAY);
  		    np = rxi_SendAck(call, np, serial, RX_ACK_DUPLICATE,
***************
*** 3429,3437 ****
  	     * queue head if the queue is empty or the packet should be
  	     * appended. */
              np->flags |= RX_PKTFLAG_RQ;
! #ifdef DEBUG
              call->rqc++;
! #endif /* DEBUG */
  	    queue_InsertBefore(tp, np);
  	    call->nSoftAcks++;
  	    np = NULL;
--- 3478,3486 ----
  	     * queue head if the queue is empty or the packet should be
  	     * appended. */
              np->flags |= RX_PKTFLAG_RQ;
! #ifdef RXDEBUG_PACKET
              call->rqc++;
! #endif /* RXDEBUG_PACKET */
  	    queue_InsertBefore(tp, np);
  	    call->nSoftAcks++;
  	    np = NULL;
***************
*** 3641,3647 ****
      u_short maxMTU = 0;		/* Set if peer supports AFS 3.4a jumbo datagrams */
      int maxDgramPackets = 0;	/* Set if peer supports AFS 3.5 jumbo datagrams */
  
!     rx_MutexIncrement(rx_stats.ackPacketsRead, rx_stats_mutex);
      ap = (struct rx_ackPacket *)rx_DataOf(np);
      nbytes = rx_Contiguous(np) - (int)((ap->acks) - (u_char *) ap);
      if (nbytes < 0)
--- 3690,3697 ----
      u_short maxMTU = 0;		/* Set if peer supports AFS 3.4a jumbo datagrams */
      int maxDgramPackets = 0;	/* Set if peer supports AFS 3.5 jumbo datagrams */
  
!     if (rx_stats_active)
!         rx_MutexIncrement(rx_stats.ackPacketsRead, rx_stats_mutex);
      ap = (struct rx_ackPacket *)rx_DataOf(np);
      nbytes = rx_Contiguous(np) - (int)((ap->acks) - (u_char *) ap);
      if (nbytes < 0)
***************
*** 3750,3758 ****
  	{
  	    queue_Remove(tp);
  	    tp->flags &= ~RX_PKTFLAG_TQ;
! #ifdef DEBUG
              call->tqc--;
! #endif /* DEBUG */
  	    rxi_FreePacket(tp);	/* rxi_FreePacket mustn't wake up anyone, preemptively. */
  	}
      }
--- 3800,3808 ----
  	{
  	    queue_Remove(tp);
  	    tp->flags &= ~RX_PKTFLAG_TQ;
! #ifdef RXDEBUG_PACKET
              call->tqc--;
! #endif /* RXDEBUG_PACKET */
  	    rxi_FreePacket(tp);	/* rxi_FreePacket mustn't wake up anyone, preemptively. */
  	}
      }
***************
*** 4199,4208 ****
  
  	if (!(call->flags & RX_CALL_WAIT_PROC)) {
  	    call->flags |= RX_CALL_WAIT_PROC;
! 	    MUTEX_ENTER(&rx_stats_mutex);
! 	    rx_nWaiting++;
! 	    rx_nWaited++;
! 	    MUTEX_EXIT(&rx_stats_mutex);
  	    rxi_calltrace(RX_CALL_ARRIVAL, call);
  	    SET_CALL_QUEUE_LOCK(call, &rx_serverPool_lock);
  	    queue_Append(&rx_incomingCallQueue, call);
--- 4249,4258 ----
  
  	if (!(call->flags & RX_CALL_WAIT_PROC)) {
  	    call->flags |= RX_CALL_WAIT_PROC;
!             MUTEX_ENTER(&rx_waiting_mutex);
!             rx_nWaiting++;
!             rx_nWaited++;
!             MUTEX_EXIT(&rx_waiting_mutex);
  	    rxi_calltrace(RX_CALL_ARRIVAL, call);
  	    SET_CALL_QUEUE_LOCK(call, &rx_serverPool_lock);
  	    queue_Append(&rx_incomingCallQueue, call);
***************
*** 4229,4237 ****
  	    call->flags &= ~RX_CALL_WAIT_PROC;
  	    if (queue_IsOnQueue(call)) {
  		queue_Remove(call);
! 		MUTEX_ENTER(&rx_stats_mutex);
! 		rx_nWaiting--;
! 		MUTEX_EXIT(&rx_stats_mutex);
  	    }
  	}
  	call->state = RX_STATE_ACTIVE;
--- 4279,4288 ----
  	    call->flags &= ~RX_CALL_WAIT_PROC;
  	    if (queue_IsOnQueue(call)) {
  		queue_Remove(call);
!                 
!                 MUTEX_ENTER(&rx_waiting_mutex);
!                 rx_nWaiting--;
!                 MUTEX_EXIT(&rx_waiting_mutex);
  	    }
  	}
  	call->state = RX_STATE_ACTIVE;
***************
*** 4366,4374 ****
  	}
      } else {
  #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
! #ifdef DEBUG
          call->tqc -=
! #endif /* DEBUG */
              rxi_FreePackets(0, &call->tq);
  #ifdef	AFS_GLOBAL_RXLOCK_KERNEL
  	call->flags &= ~RX_CALL_TQ_CLEARME;
--- 4417,4425 ----
  	}
      } else {
  #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
! #ifdef RXDEBUG_PACKET
          call->tqc -=
! #endif /* RXDEBUG_PACKET */
              rxi_FreePackets(0, &call->tq);
  #ifdef	AFS_GLOBAL_RXLOCK_KERNEL
  	call->flags &= ~RX_CALL_TQ_CLEARME;
***************
*** 4398,4404 ****
          
          count = rxi_FreePackets(0, &call->rq);
  	rx_packetReclaims += count;
! #ifdef DEBUG
          call->rqc -= count;
          if ( call->rqc != 0 ) 
              dpf(("rxi_ClearReceiveQueue call %x rqc %u != 0", call, call->rqc));
--- 4449,4455 ----
          
          count = rxi_FreePackets(0, &call->rq);
  	rx_packetReclaims += count;
! #ifdef RXDEBUG_PACKET
          call->rqc -= count;
          if ( call->rqc != 0 ) 
              dpf(("rxi_ClearReceiveQueue call %x rqc %u != 0", call, call->rqc));
***************
*** 4531,4537 ****
  	    }
  	}
  	conn->error = error;
!         rx_MutexIncrement(rx_stats.fatalErrors, rx_stats_mutex);
      }
  }
  
--- 4582,4589 ----
  	    }
  	}
  	conn->error = error;
!         if (rx_stats_active)
!             rx_MutexIncrement(rx_stats.fatalErrors, rx_stats_mutex);
      }
  }
  
***************
*** 4654,4667 ****
          call->currentPacket->flags &= ~RX_PKTFLAG_CP;
          call->currentPacket->flags |= RX_PKTFLAG_IOVQ;
          queue_Prepend(&call->iovq, call->currentPacket);
! #ifdef DEBUG
          call->iovqc++;
! #endif /* DEBUG */
          call->currentPacket = (struct rx_packet *)0;
      }
      call->curlen = call->nLeft = call->nFree = 0;
  
! #ifdef DEBUG
      call->iovqc -= 
  #endif
          rxi_FreePackets(0, &call->iovq);
--- 4706,4719 ----
          call->currentPacket->flags &= ~RX_PKTFLAG_CP;
          call->currentPacket->flags |= RX_PKTFLAG_IOVQ;
          queue_Prepend(&call->iovq, call->currentPacket);
! #ifdef RXDEBUG_PACKET
          call->iovqc++;
! #endif /* RXDEBUG_PACKET */
          call->currentPacket = (struct rx_packet *)0;
      }
      call->curlen = call->nLeft = call->nFree = 0;
  
! #ifdef RXDEBUG_PACKET
      call->iovqc -= 
  #endif
          rxi_FreePackets(0, &call->iovq);
***************
*** 4716,4724 ****
  	if (queue_IsOnQueue(call)) {
  	    queue_Remove(call);
  	    if (flags & RX_CALL_WAIT_PROC) {
! 		MUTEX_ENTER(&rx_stats_mutex);
! 		rx_nWaiting--;
! 		MUTEX_EXIT(&rx_stats_mutex);
  	    }
  	}
  	MUTEX_EXIT(call->call_queue_lock);
--- 4768,4777 ----
  	if (queue_IsOnQueue(call)) {
  	    queue_Remove(call);
  	    if (flags & RX_CALL_WAIT_PROC) {
!                 
!                 MUTEX_ENTER(&rx_waiting_mutex);
!                 rx_nWaiting--;
!                 MUTEX_EXIT(&rx_waiting_mutex);
  	    }
  	}
  	MUTEX_EXIT(call->call_queue_lock);
***************
*** 4968,4974 ****
  		nbytes -= p->wirevec[i].iov_len;
  	}
      }
!     rx_MutexIncrement(rx_stats.ackPacketsSent, rx_stats_mutex);
  #ifndef RX_ENABLE_TSFPQ
      if (!optionalPacket)
  	rxi_FreePacket(p);
--- 5021,5028 ----
  		nbytes -= p->wirevec[i].iov_len;
  	}
      }
!     if (rx_stats_active)
!         rx_MutexIncrement(rx_stats.ackPacketsSent, rx_stats_mutex);
  #ifndef RX_ENABLE_TSFPQ
      if (!optionalPacket)
  	rxi_FreePacket(p);
***************
*** 4992,4998 ****
      peer->nSent += len;
      if (resending)
  	peer->reSends += len;
!     rx_MutexIncrement(rx_stats.dataPacketsSent, rx_stats_mutex);
      MUTEX_EXIT(&peer->peer_lock);
  
      if (list[len - 1]->header.flags & RX_LAST_PACKET) {
--- 5046,5053 ----
      peer->nSent += len;
      if (resending)
  	peer->reSends += len;
!     if (rx_stats_active)
!         rx_MutexIncrement(rx_stats.dataPacketsSent, rx_stats_mutex);
      MUTEX_EXIT(&peer->peer_lock);
  
      if (list[len - 1]->header.flags & RX_LAST_PACKET) {
***************
*** 5027,5033 ****
  	 * packet until the congestion window reaches the ack rate. */
  	if (list[i]->header.serial) {
  	    requestAck = 1;
! 	    rx_MutexIncrement(rx_stats.dataPacketsReSent, rx_stats_mutex);
  	} else {
  	    /* improved RTO calculation- not Karn */
  	    list[i]->firstSent = *now;
--- 5082,5089 ----
  	 * packet until the congestion window reaches the ack rate. */
  	if (list[i]->header.serial) {
  	    requestAck = 1;
!             if (rx_stats_active)
!                 rx_MutexIncrement(rx_stats.dataPacketsReSent, rx_stats_mutex);
  	} else {
  	    /* improved RTO calculation- not Karn */
  	    list[i]->firstSent = *now;
***************
*** 5042,5048 ****
  	peer->nSent++;
  	if (resending)
  	    peer->reSends++;
!         rx_MutexIncrement(rx_stats.dataPacketsSent, rx_stats_mutex);
  	MUTEX_EXIT(&peer->peer_lock);
  
  	/* Tag this packet as not being the last in this group,
--- 5098,5105 ----
  	peer->nSent++;
  	if (resending)
  	    peer->reSends++;
!         if (rx_stats_active)
!             rx_MutexIncrement(rx_stats.dataPacketsSent, rx_stats_mutex);
  	MUTEX_EXIT(&peer->peer_lock);
  
  	/* Tag this packet as not being the last in this group,
***************
*** 5266,5272 ****
      }
      if (call->error) {
  #ifdef	AFS_GLOBAL_RXLOCK_KERNEL
!         rx_MutexIncrement(rx_tq_debug.rxi_start_in_error, rx_stats_mutex);
  #endif
  	return;
      }
--- 5323,5330 ----
      }
      if (call->error) {
  #ifdef	AFS_GLOBAL_RXLOCK_KERNEL
!         if (rx_stats_active)
!             rx_MutexIncrement(rx_tq_debug.rxi_start_in_error, rx_stats_mutex);
  #endif
  	return;
      }
***************
*** 5341,5347 ****
  		    if (p->flags & RX_PKTFLAG_ACKED) {
  			/* Since we may block, don't trust this */
  			usenow.sec = usenow.usec = 0;
!                         rx_MutexIncrement(rx_stats.ignoreAckedPacket, rx_stats_mutex);
  			continue;	/* Ignore this packet if it has been acknowledged */
  		    }
  
--- 5399,5406 ----
  		    if (p->flags & RX_PKTFLAG_ACKED) {
  			/* Since we may block, don't trust this */
  			usenow.sec = usenow.usec = 0;
!                         if (rx_stats_active)
!                             rx_MutexIncrement(rx_stats.ignoreAckedPacket, rx_stats_mutex);
  			continue;	/* Ignore this packet if it has been acknowledged */
  		    }
  
***************
*** 5408,5414 ****
  		     * the time to reset the call. This will also inform the using
  		     * process that the call is in an error state.
  		     */
!                     rx_MutexIncrement(rx_tq_debug.rxi_start_aborted, rx_stats_mutex);
  		    call->flags &= ~RX_CALL_TQ_BUSY;
  		    if (call->tqWaiters || (call->flags & RX_CALL_TQ_WAIT)) {
  			dpf(("call %x has %d waiters and flags %d\n", call, call->tqWaiters, call->flags));
--- 5467,5474 ----
  		     * the time to reset the call. This will also inform the using
  		     * process that the call is in an error state.
  		     */
!                     if (rx_stats_active)
!                         rx_MutexIncrement(rx_tq_debug.rxi_start_aborted, rx_stats_mutex);
  		    call->flags &= ~RX_CALL_TQ_BUSY;
  		    if (call->tqWaiters || (call->flags & RX_CALL_TQ_WAIT)) {
  			dpf(("call %x has %d waiters and flags %d\n", call, call->tqWaiters, call->flags));
***************
*** 5435,5441 ****
  			    && (p->flags & RX_PKTFLAG_ACKED)) {
  			    queue_Remove(p);
  			    p->flags &= ~RX_PKTFLAG_TQ;
! #ifdef DEBUG
                              call->tqc--;
  #endif
  			    rxi_FreePacket(p);
--- 5495,5501 ----
  			    && (p->flags & RX_PKTFLAG_ACKED)) {
  			    queue_Remove(p);
  			    p->flags &= ~RX_PKTFLAG_TQ;
! #ifdef RXDEBUG_PACKET
                              call->tqc--;
  #endif
  			    rxi_FreePacket(p);
***************
*** 5892,5910 ****
  	return;			/* somebody set the clock back, don't count this time. */
      }
      clock_Sub(rttp, sentp);
!     MUTEX_ENTER(&rx_stats_mutex);
!     if (clock_Lt(rttp, &rx_stats.minRtt))
! 	rx_stats.minRtt = *rttp;
!     if (clock_Gt(rttp, &rx_stats.maxRtt)) {
! 	if (rttp->sec > 60) {
! 	    MUTEX_EXIT(&rx_stats_mutex);
! 	    return;		/* somebody set the clock ahead */
! 	}
! 	rx_stats.maxRtt = *rttp;
      }
-     clock_Add(&rx_stats.totalRtt, rttp);
-     rx_stats.nRttSamples++;
-     MUTEX_EXIT(&rx_stats_mutex);
  
      /* better rtt calculation courtesy of UMich crew (dave,larry,peter,?) */
  
--- 5952,5972 ----
  	return;			/* somebody set the clock back, don't count this time. */
      }
      clock_Sub(rttp, sentp);
!     if (rx_stats_active) {
!         MUTEX_ENTER(&rx_stats_mutex);
!         if (clock_Lt(rttp, &rx_stats.minRtt))
!             rx_stats.minRtt = *rttp;
!         if (clock_Gt(rttp, &rx_stats.maxRtt)) {
!             if (rttp->sec > 60) {
!                 MUTEX_EXIT(&rx_stats_mutex);
!                 return;		/* somebody set the clock ahead */
!             }
!             rx_stats.maxRtt = *rttp;
!         }
!         clock_Add(&rx_stats.totalRtt, rttp);
!         rx_stats.nRttSamples++;
!         MUTEX_EXIT(&rx_stats_mutex);
      }
  
      /* better rtt calculation courtesy of UMich crew (dave,larry,peter,?) */
  
***************
*** 6087,6093 ****
  			rxi_rpc_peer_stat_cnt -= num_funcs;
  		    }
  		    rxi_FreePeer(peer);
!                     rx_MutexDecrement(rx_stats.nPeerStructs, rx_stats_mutex);
  		    if (peer == *peer_ptr) {
  			*peer_ptr = next;
  			prev = next;
--- 6149,6156 ----
  			rxi_rpc_peer_stat_cnt -= num_funcs;
  		    }
  		    rxi_FreePeer(peer);
!                     if (rx_stats_active)
!                         rx_MutexDecrement(rx_stats.nPeerStructs, rx_stats_mutex);
  		    if (peer == *peer_ptr) {
  			*peer_ptr = next;
  			prev = next;
***************
*** 6292,6301 ****
  #endif /* ADAPT_WINDOW */
  
  
- #ifdef RXDEBUG
  void
  rxi_DebugInit(void)
  {
  #ifdef AFS_NT40_ENV
  #define TRACE_OPTION_DEBUGLOG 4
      HKEY parmKey;
--- 6355,6364 ----
  #endif /* ADAPT_WINDOW */
  
  
  void
  rxi_DebugInit(void)
  {
+ #ifdef RXDEBUG
  #ifdef AFS_NT40_ENV
  #define TRACE_OPTION_DEBUGLOG 4
      HKEY parmKey;
***************
*** 6318,6338 ****
      }
      RegCloseKey (parmKey);
  #endif /* AFS_NT40_ENV */
  }
  
- #ifdef AFS_NT40_ENV
  void
  rx_DebugOnOff(int on)
  {
      rxdebug_active = on;
  }
- #endif /* AFS_NT40_ENV */
  
  
  /* Don't call this debugging routine directly; use dpf */
  void
  rxi_DebugPrint(char *format, ...)
  {
      va_list ap;
  #ifdef AFS_NT40_ENV
      char msg[512];
--- 6381,6413 ----
      }
      RegCloseKey (parmKey);
  #endif /* AFS_NT40_ENV */
+ #endif
  }
  
  void
  rx_DebugOnOff(int on)
  {
+ #ifdef RXDEBUG
+ #ifdef AFS_NT40_ENV
      rxdebug_active = on;
+ #endif
+ #endif
+ }
+ 
+ void
+ rx_StatsOnOff(int on)
+ {
+ #ifdef RXDEBUG
+     rx_stats_active = on;
+ #endif
  }
  
  
  /* Don't call this debugging routine directly; use dpf */
  void
  rxi_DebugPrint(char *format, ...)
  {
+ #ifdef RXDEBUG
      va_list ap;
  #ifdef AFS_NT40_ENV
      char msg[512];
***************
*** 6366,6373 ****
--- 6441,6450 ----
      putc('\n', rx_Log);
      va_end(ap);
  #endif
+ #endif
  }
  
+ #ifndef KERNEL
  /*
   * This function is used to process the rx_stats structure that is local
   * to a process as well as an rx_stats structure received from a remote
***************
*** 6378,6383 ****
--- 6455,6461 ----
  rx_PrintTheseStats(FILE * file, struct rx_statistics *s, int size,
  		   afs_int32 freePackets, char version)
  {
+ #ifdef RXDEBUG
      int i;
  
      if (size != sizeof(struct rx_statistics)) {
***************
*** 6452,6458 ****
  #if	!defined(AFS_PTHREAD_ENV) && !defined(AFS_USE_GETTIMEOFDAY)
      fprintf(file, "   %d clock updates\n", clock_nUpdates);
  #endif
! 
  }
  
  /* for backward compatibility */
--- 6530,6538 ----
  #if	!defined(AFS_PTHREAD_ENV) && !defined(AFS_USE_GETTIMEOFDAY)
      fprintf(file, "   %d clock updates\n", clock_nUpdates);
  #endif
! #else
!     fprintf(file, "ERROR: compiled without RXDEBUG\n");
! #endif
  }
  
  /* for backward compatibility */
***************
*** 6482,6501 ****
  	    "max out packet skew %d\n", peer->ifMTU, (int)peer->inPacketSkew,
  	    (int)peer->outPacketSkew);
  }
  
! #ifdef AFS_PTHREAD_ENV
  /*
   * This mutex protects the following static variables:
   * counter
   */
  
! #define LOCK_RX_DEBUG assert(pthread_mutex_lock(&rx_debug_mutex)==0)
! #define UNLOCK_RX_DEBUG assert(pthread_mutex_unlock(&rx_debug_mutex)==0)
  #else
  #define LOCK_RX_DEBUG
  #define UNLOCK_RX_DEBUG
  #endif /* AFS_PTHREAD_ENV */
  
  static int
  MakeDebugCall(osi_socket socket, afs_uint32 remoteAddr, afs_uint16 remotePort,
  	      u_char type, void *inputData, size_t inputLength,
--- 6562,6583 ----
  	    "max out packet skew %d\n", peer->ifMTU, (int)peer->inPacketSkew,
  	    (int)peer->outPacketSkew);
  }
+ #endif
  
! #if defined(AFS_PTHREAD_ENV) && defined(RXDEBUG)
  /*
   * This mutex protects the following static variables:
   * counter
   */
  
! #define LOCK_RX_DEBUG MUTEX_ENTER(&rx_debug_mutex)
! #define UNLOCK_RX_DEBUG MUTEX_EXIT(&rx_debug_mutex)
  #else
  #define LOCK_RX_DEBUG
  #define UNLOCK_RX_DEBUG
  #endif /* AFS_PTHREAD_ENV */
  
+ #ifdef RXDEBUG
  static int
  MakeDebugCall(osi_socket socket, afs_uint32 remoteAddr, afs_uint16 remotePort,
  	      u_char type, void *inputData, size_t inputLength,
***************
*** 6601,6615 ****
      memcpy(outputData, tp, code);
      return code;
  }
  
  afs_int32
  rx_GetServerDebug(osi_socket socket, afs_uint32 remoteAddr,
  		  afs_uint16 remotePort, struct rx_debugStats * stat,
  		  afs_uint32 * supportedValues)
  {
      struct rx_debugIn in;
      afs_int32 *lp = (afs_int32 *) stat;
-     afs_int32 rc = 0;
  
      *supportedValues = 0;
      in.type = htonl(RX_DEBUGI_GETSTATS);
--- 6683,6701 ----
      memcpy(outputData, tp, code);
      return code;
  }
+ #endif /* RXDEBUG */
  
  afs_int32
  rx_GetServerDebug(osi_socket socket, afs_uint32 remoteAddr,
  		  afs_uint16 remotePort, struct rx_debugStats * stat,
  		  afs_uint32 * supportedValues)
  {
+ #ifndef RXDEBUG
+      afs_int32 rc = -1;
+ #else
+     afs_int32 rc = 0;
      struct rx_debugIn in;
      afs_int32 *lp = (afs_int32 *) stat;
  
      *supportedValues = 0;
      in.type = htonl(RX_DEBUGI_GETSTATS);
***************
*** 6660,6666 ****
          stat->nWaited = ntohl(stat->nWaited);
          stat->nPackets = ntohl(stat->nPackets);
      }
! 
      return rc;
  }
  
--- 6746,6752 ----
          stat->nWaited = ntohl(stat->nWaited);
          stat->nPackets = ntohl(stat->nPackets);
      }
! #endif
      return rc;
  }
  
***************
*** 6669,6678 ****
  		  afs_uint16 remotePort, struct rx_statistics * stat,
  		  afs_uint32 * supportedValues)
  {
      struct rx_debugIn in;
      afs_int32 *lp = (afs_int32 *) stat;
      int i;
-     afs_int32 rc = 0;
  
      /*
       * supportedValues is currently unused, but added to allow future
--- 6755,6767 ----
  		  afs_uint16 remotePort, struct rx_statistics * stat,
  		  afs_uint32 * supportedValues)
  {
+ #ifndef RXDEBUG
+      afs_int32 rc = -1;
+ #else
+     afs_int32 rc = 0;
      struct rx_debugIn in;
      afs_int32 *lp = (afs_int32 *) stat;
      int i;
  
      /*
       * supportedValues is currently unused, but added to allow future
***************
*** 6697,6703 ****
  	    *lp = ntohl(*lp);
  	}
      }
! 
      return rc;
  }
  
--- 6786,6792 ----
  	    *lp = ntohl(*lp);
  	}
      }
! #endif
      return rc;
  }
  
***************
*** 6706,6715 ****
--- 6795,6808 ----
  		    afs_uint16 remotePort, size_t version_length,
  		    char *version)
  {
+ #ifdef RXDEBUG
      char a[1] = { 0 };
      return MakeDebugCall(socket, remoteAddr, remotePort,
  			 RX_PACKET_TYPE_VERSION, a, 1, version,
  			 version_length);
+ #else
+     return -1;
+ #endif
  }
  
  afs_int32
***************
*** 6719,6726 ****
  			struct rx_debugConn * conn,
  			afs_uint32 * supportedValues)
  {
!     struct rx_debugIn in;
      afs_int32 rc = 0;
      int i;
  
      /*
--- 6812,6822 ----
  			struct rx_debugConn * conn,
  			afs_uint32 * supportedValues)
  {
! #ifndef RXDEBUG
!     afs_int32 rc = -1;
! #else
      afs_int32 rc = 0;
+     struct rx_debugIn in;
      int i;
  
      /*
***************
*** 6792,6798 ****
  	conn->epoch = ntohl(conn->epoch);
  	conn->natMTU = ntohl(conn->natMTU);
      }
! 
      return rc;
  }
  
--- 6888,6894 ----
  	conn->epoch = ntohl(conn->epoch);
  	conn->natMTU = ntohl(conn->natMTU);
      }
! #endif
      return rc;
  }
  
***************
*** 6802,6809 ****
  		  afs_uint32 debugSupportedValues, struct rx_debugPeer * peer,
  		  afs_uint32 * supportedValues)
  {
!     struct rx_debugIn in;
      afs_int32 rc = 0;
  
      /*
       * supportedValues is currently unused, but added to allow future
--- 6898,6908 ----
  		  afs_uint32 debugSupportedValues, struct rx_debugPeer * peer,
  		  afs_uint32 * supportedValues)
  {
! #ifndef RXDEBUG
!     afs_int32 rc = -1;
! #else
      afs_int32 rc = 0;
+     struct rx_debugIn in;
  
      /*
       * supportedValues is currently unused, but added to allow future
***************
*** 6854,6863 ****
  	peer->bytesReceived.high = ntohl(peer->bytesReceived.high);
  	peer->bytesReceived.low = ntohl(peer->bytesReceived.low);
      }
! 
      return rc;
  }
- #endif /* RXDEBUG */
  
  void
  shutdown_rx(void)
--- 6953,6961 ----
  	peer->bytesReceived.high = ntohl(peer->bytesReceived.high);
  	peer->bytesReceived.low = ntohl(peer->bytesReceived.low);
      }
! #endif
      return rc;
  }
  
  void
  shutdown_rx(void)
***************
*** 6933,6939 ****
  		}
  		next = peer->next;
  		rxi_FreePeer(peer);
!                 rx_MutexDecrement(rx_stats.nPeerStructs, rx_stats_mutex);
  	    }
  	}
      }
--- 7031,7038 ----
  		}
  		next = peer->next;
  		rxi_FreePeer(peer);
!                 if (rx_stats_active)
!                     rx_MutexDecrement(rx_stats.nPeerStructs, rx_stats_mutex);
  	    }
  	}
      }
***************
*** 6981,6991 ****
  
      rxi_FreeAllPackets();
  
!     MUTEX_ENTER(&rx_stats_mutex);
      rxi_dataQuota = RX_MAX_QUOTA;
      rxi_availProcs = rxi_totalMin = rxi_minDeficit = 0;
!     MUTEX_EXIT(&rx_stats_mutex);
! 
      rxinit_status = 1;
      UNLOCK_RX_INIT;
  }
--- 7080,7089 ----
  
      rxi_FreeAllPackets();
  
!     MUTEX_ENTER(&rx_quota_mutex);
      rxi_dataQuota = RX_MAX_QUOTA;
      rxi_availProcs = rxi_totalMin = rxi_minDeficit = 0;
!     MUTEX_EXIT(&rx_quota_mutex);
      rxinit_status = 1;
      UNLOCK_RX_INIT;
  }
***************
*** 7987,7993 ****
  #ifdef AFS_NT40_ENV
  int rx_DumpCalls(FILE *outputFile, char *cookie)
  {
! #ifdef DEBUG
      int zilch;
  #ifdef KDUMP_RX_LOCK
      struct rx_call_rx_lock *c;
--- 8085,8091 ----
  #ifdef AFS_NT40_ENV
  int rx_DumpCalls(FILE *outputFile, char *cookie)
  {
! #ifdef RXDEBUG_PACKET
      int zilch;
  #ifdef KDUMP_RX_LOCK
      struct rx_call_rx_lock *c;
***************
*** 8040,8046 ****
      }
      sprintf(output, "%s - End dumping all Rx Calls\r\n", cookie);
      WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
! #endif /* DEBUG */
      return 0;
  }
  #endif /* AFS_NT40_ENV */
--- 8138,8144 ----
      }
      sprintf(output, "%s - End dumping all Rx Calls\r\n", cookie);
      WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
! #endif /* RXDEBUG_PACKET */
      return 0;
  }
  #endif /* AFS_NT40_ENV */
Index: openafs/src/rx/rx.h
diff -c openafs/src/rx/rx.h:1.28.4.14 openafs/src/rx/rx.h:1.28.4.15
*** openafs/src/rx/rx.h:1.28.4.14	Mon Dec 29 17:38:30 2008
--- openafs/src/rx/rx.h	Sun Jan  4 19:00:21 2009
***************
*** 547,553 ****
      afs_hyper_t bytesRcvd;	/* Number bytes received */
      u_short tqWaiters;
  
! #ifdef DEBUG
      u_short tqc;                /* packet count in tq */
      u_short rqc;                /* packet count in rq */
      u_short iovqc;              /* packet count in iovq */
--- 547,553 ----
      afs_hyper_t bytesRcvd;	/* Number bytes received */
      u_short tqWaiters;
  
! #ifdef RXDEBUG_PACKET
      u_short tqc;                /* packet count in tq */
      u_short rqc;                /* packet count in rq */
      u_short iovqc;              /* packet count in iovq */
Index: openafs/src/rx/rx_conncache.c
diff -c openafs/src/rx/rx_conncache.c:1.10 openafs/src/rx/rx_conncache.c:1.10.8.1
*** openafs/src/rx/rx_conncache.c:1.10	Wed Aug 18 20:41:54 2004
--- openafs/src/rx/rx_conncache.c	Wed Jan 14 01:34:19 2009
***************
*** 19,25 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_conncache.c,v 1.10 2004/08/19 00:41:54 kolya Exp $");
  
  #ifdef UKERNEL
  #include "afs/sysincludes.h"
--- 19,25 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_conncache.c,v 1.10.8.1 2009/01/14 06:34:19 jaltman Exp $");
  
  #ifdef UKERNEL
  #include "afs/sysincludes.h"
***************
*** 47,55 ****
   * rxi_connectionCache
   */
  
! pthread_mutex_t rxi_connCacheMutex;
! #define LOCK_CONN_CACHE assert(pthread_mutex_lock(&rxi_connCacheMutex)==0)
! #define UNLOCK_CONN_CACHE assert(pthread_mutex_unlock(&rxi_connCacheMutex)==0)
  #else
  #define LOCK_CONN_CACHE
  #define UNLOCK_CONN_CACHE
--- 47,55 ----
   * rxi_connectionCache
   */
  
! afs_kmutex_t rxi_connCacheMutex;
! #define LOCK_CONN_CACHE MUTEX_ENTER(&rxi_connCacheMutex)
! #define UNLOCK_CONN_CACHE MUTEX_EXIT(&rxi_connCacheMutex)
  #else
  #define LOCK_CONN_CACHE
  #define UNLOCK_CONN_CACHE
Index: openafs/src/rx/rx_event.c
diff -c openafs/src/rx/rx_event.c:1.18.4.3 openafs/src/rx/rx_event.c:1.18.4.4
*** openafs/src/rx/rx_event.c:1.18.4.3	Wed Sep 24 17:36:53 2008
--- openafs/src/rx/rx_event.c	Wed Jan 14 01:34:19 2009
***************
*** 19,25 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_event.c,v 1.18.4.3 2008/09/24 21:36:53 shadow Exp $");
  
  #ifdef KERNEL
  #ifndef UKERNEL
--- 19,25 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_event.c,v 1.18.4.4 2009/01/14 06:34:19 jaltman Exp $");
  
  #ifdef KERNEL
  #ifndef UKERNEL
***************
*** 109,117 ****
   */
  
  #include <assert.h>
! pthread_mutex_t rx_event_mutex;
! #define LOCK_EV_INIT assert(pthread_mutex_lock(&rx_event_mutex)==0)
! #define UNLOCK_EV_INIT assert(pthread_mutex_unlock(&rx_event_mutex)==0)
  #else
  #define LOCK_EV_INIT
  #define UNLOCK_EV_INIT
--- 109,117 ----
   */
  
  #include <assert.h>
! afs_kmutex_t rx_event_mutex;
! #define LOCK_EV_INIT MUTEX_ENTER(&rx_event_mutex)
! #define UNLOCK_EV_INIT MUTEX_EXIT(&rx_event_mutex)
  #else
  #define LOCK_EV_INIT
  #define UNLOCK_EV_INIT
Index: openafs/src/rx/rx_globals.h
diff -c openafs/src/rx/rx_globals.h:1.21.2.22 openafs/src/rx/rx_globals.h:1.21.2.25
*** openafs/src/rx/rx_globals.h:1.21.2.22	Wed Oct  8 17:15:10 2008
--- openafs/src/rx/rx_globals.h	Tue Jan 13 11:26:16 2009
***************
*** 265,270 ****
--- 265,271 ----
   * by each call to AllocPacketBufs() will increase indefinitely without a cap on the transfer
   * glob size.  A cap of 64 is selected because that will produce an allocation of greater than
   * three times that amount which is greater than half of ncalls * maxReceiveWindow. 
+  * Must be called under rx_packets_mutex.
   */
  #define RX_TS_FPQ_COMPUTE_LIMITS \
      do { \
***************
*** 306,314 ****
          (rx_ts_info_p)->_FPQ.ltog_ops++; \
          (rx_ts_info_p)->_FPQ.ltog_xfer += tsize; \
          if ((rx_ts_info_p)->_FPQ.delta) { \
!             MUTEX_ENTER(&rx_stats_mutex); \
              RX_TS_FPQ_COMPUTE_LIMITS; \
!             MUTEX_EXIT(&rx_stats_mutex); \
             (rx_ts_info_p)->_FPQ.delta = 0; \
          } \
      } while(0)
--- 307,315 ----
          (rx_ts_info_p)->_FPQ.ltog_ops++; \
          (rx_ts_info_p)->_FPQ.ltog_xfer += tsize; \
          if ((rx_ts_info_p)->_FPQ.delta) { \
!             MUTEX_ENTER(&rx_packets_mutex); \
              RX_TS_FPQ_COMPUTE_LIMITS; \
!             MUTEX_EXIT(&rx_packets_mutex); \
             (rx_ts_info_p)->_FPQ.delta = 0; \
          } \
      } while(0)
***************
*** 326,334 ****
          (rx_ts_info_p)->_FPQ.ltog_ops++; \
          (rx_ts_info_p)->_FPQ.ltog_xfer += (num_transfer); \
          if ((rx_ts_info_p)->_FPQ.delta) { \
!             MUTEX_ENTER(&rx_stats_mutex); \
              RX_TS_FPQ_COMPUTE_LIMITS; \
!             MUTEX_EXIT(&rx_stats_mutex); \
              (rx_ts_info_p)->_FPQ.delta = 0; \
          } \
      } while(0)
--- 327,335 ----
          (rx_ts_info_p)->_FPQ.ltog_ops++; \
          (rx_ts_info_p)->_FPQ.ltog_xfer += (num_transfer); \
          if ((rx_ts_info_p)->_FPQ.delta) { \
!             MUTEX_ENTER(&rx_packets_mutex); \
              RX_TS_FPQ_COMPUTE_LIMITS; \
!             MUTEX_EXIT(&rx_packets_mutex); \
              (rx_ts_info_p)->_FPQ.delta = 0; \
          } \
      } while(0)
***************
*** 542,552 ****
  #define	rxi_AllocConnection()	(struct rx_connection *) rxi_Alloc(sizeof(struct rx_connection))
  #define rxi_FreeConnection(conn) (rxi_Free(conn, sizeof(struct rx_connection)))
  
! #ifdef RXDEBUG
  /* Some debugging stuff */
  EXT FILE *rx_debugFile;		/* Set by the user to a stdio file for debugging output */
  EXT FILE *rxevent_debugFile;	/* Set to an stdio descriptor for event logging to that file */
  
  #define rx_Log rx_debugFile
  #ifdef AFS_NT40_ENV
  EXT int rxdebug_active;
--- 543,557 ----
  #define	rxi_AllocConnection()	(struct rx_connection *) rxi_Alloc(sizeof(struct rx_connection))
  #define rxi_FreeConnection(conn) (rxi_Free(conn, sizeof(struct rx_connection)))
  
! EXT afs_int32 rx_stats_active GLOBALSINIT(1);	/* boolean - rx statistics gathering */
! 
! #ifndef KERNEL
  /* Some debugging stuff */
  EXT FILE *rx_debugFile;		/* Set by the user to a stdio file for debugging output */
  EXT FILE *rxevent_debugFile;	/* Set to an stdio descriptor for event logging to that file */
+ #endif
  
+ #ifdef RXDEBUG
  #define rx_Log rx_debugFile
  #ifdef AFS_NT40_ENV
  EXT int rxdebug_active;
***************
*** 561,566 ****
--- 566,574 ----
  #define rx_Log_event rxevent_debugFile
  
  EXT char *rx_packetTypes[RX_N_PACKET_TYPES] GLOBALSINIT(RX_PACKET_TYPES);	/* Strings defined in rx.h */
+ #else
+ #define dpf(args)
+ #endif /* RXDEBUG */
  
  #ifndef KERNEL
  /*
***************
*** 576,585 ****
  #endif /* RX_ENABLE_LOCKS */
  #endif /* !KERNEL */
  
- #else
- #define dpf(args)
- #endif /* RXDEBUG */
- 
  /*
   * SERVER ONLY: Threshholds used to throttle error replies to looping
   * clients. When consecutive calls are aborting with the same error, the
--- 584,589 ----
***************
*** 599,612 ****
  EXT int rxi_fcfs_thread_num GLOBALSINIT(0);
  EXT pthread_key_t rx_thread_id_key;
  /* keep track of pthread numbers - protected by rx_stats_mutex, 
!    except in rx_Init() before mutex exists! */
  EXT int rxi_pthread_hinum GLOBALSINIT(0);
  #else
  #define rxi_fcfs_thread_num (0)
  #endif
  
  #if defined(RX_ENABLE_LOCKS)
! EXT afs_kmutex_t rx_stats_mutex;	/* used to activate stats gathering */
  #endif
  
  EXT2 int rx_enable_stats GLOBALSINIT(0);
--- 603,620 ----
  EXT int rxi_fcfs_thread_num GLOBALSINIT(0);
  EXT pthread_key_t rx_thread_id_key;
  /* keep track of pthread numbers - protected by rx_stats_mutex, 
!  * except in rx_Init() before mutex exists! */
  EXT int rxi_pthread_hinum GLOBALSINIT(0);
  #else
  #define rxi_fcfs_thread_num (0)
  #endif
  
  #if defined(RX_ENABLE_LOCKS)
! EXT afs_kmutex_t rx_stats_mutex;	/* used to protect stats gathering */
! EXT afs_kmutex_t rx_waiting_mutex;	/* used to protect waiting counters */
! EXT afs_kmutex_t rx_quota_mutex;	/* used to protect quota counters */
! EXT afs_kmutex_t rx_pthread_mutex;	/* used to protect pthread counters */
! EXT afs_kmutex_t rx_packets_mutex;	/* used to protect packet counters */
  #endif
  
  EXT2 int rx_enable_stats GLOBALSINIT(0);
Index: openafs/src/rx/rx_kcommon.c
diff -c openafs/src/rx/rx_kcommon.c:1.56.2.11 openafs/src/rx/rx_kcommon.c:1.56.2.15
*** openafs/src/rx/rx_kcommon.c:1.56.2.11	Mon Dec 15 14:12:21 2008
--- openafs/src/rx/rx_kcommon.c	Thu Jan 22 16:29:08 2009
***************
*** 15,21 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_kcommon.c,v 1.56.2.11 2008/12/15 19:12:21 shadow Exp $");
  
  #include "rx/rx_kcommon.h"
  
--- 15,21 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_kcommon.c,v 1.56.2.15 2009/01/22 21:29:08 shadow Exp $");
  
  #include "rx/rx_kcommon.h"
  
***************
*** 136,141 ****
--- 136,153 ----
      if (!msg)
          msg = "Unknown AFS panic";
      printf(msg, a1, a2, a3);
+     panic(msg);
+ #elif defined(AFS_DARWIN80_ENV) && !defined(AFS_DARWIN90_ENV)
+     char buf[256];
+     va_list ap;
+     if (!msg)
+ 	msg = "Unknown AFS panic";
+ 
+     va_start(ap, msg);
+     vsnprintf(buf, sizeof(buf), msg, ap);
+     va_end(ap);
+     printf(buf);
+     panic(buf);
  #else
      va_list ap;
      if (!msg)
***************
*** 143,153 ****
  
      va_start(ap, msg);
      vprintf(msg, ap);
! #endif
! #ifdef AFS_LINUX20_ENV
      * ((char *) 0) = 0; 
! #else
      panic(msg);
  #endif
  }
  
--- 155,166 ----
  
      va_start(ap, msg);
      vprintf(msg, ap);
!     va_end(ap);
! # ifdef AFS_LINUX20_ENV
      * ((char *) 0) = 0; 
! # else
      panic(msg);
+ # endif
  #endif
  }
  
***************
*** 289,294 ****
--- 302,308 ----
  {
      int threadID;
  
+ /* jaltman - rxi_dataQuota is protected by a mutex everywhere else */
      rxi_MorePackets(rx_maxReceiveWindow + 2);	/* alloc more packets */
      rxi_dataQuota += rx_initSendWindow;	/* Reserve some pkts for hard times */
      /* threadID is used for making decisions in GetCall.  Get it by bumping
***************
*** 327,335 ****
  				 RX_PACKET_CLASS_RECV_CBUF)) {
  		rxi_FreePacket(tp);
  		tp = NULL;
! 		MUTEX_ENTER(&rx_stats_mutex);
! 		rx_stats.noPacketBuffersOnRead++;
! 		MUTEX_EXIT(&rx_stats_mutex);
  	    }
  	}
      } else {
--- 341,351 ----
  				 RX_PACKET_CLASS_RECV_CBUF)) {
  		rxi_FreePacket(tp);
  		tp = NULL;
!                 if (rx_stats_active) {
!                     MUTEX_ENTER(&rx_stats_mutex);
!                     rx_stats.noPacketBuffersOnRead++;
!                     MUTEX_EXIT(&rx_stats_mutex);
!                 }
  	    }
  	}
      } else {
***************
*** 338,346 ****
  	 * should do this at a higher layer and let other
  	 * end know we're losing.
  	 */
! 	MUTEX_ENTER(&rx_stats_mutex);
! 	rx_stats.bogusPacketOnRead++;
! 	MUTEX_EXIT(&rx_stats_mutex);
  	/* I DON"T LIKE THIS PRINTF -- PRINTFS MAKE THINGS VERY VERY SLOOWWW */
  	dpf(("rx: packet dropped: bad ulen=%d\n", asize));
  	tp = NULL;
--- 354,364 ----
  	 * should do this at a higher layer and let other
  	 * end know we're losing.
  	 */
!         if (rx_stats_active) {
!             MUTEX_ENTER(&rx_stats_mutex);
!             rx_stats.bogusPacketOnRead++;
!             MUTEX_EXIT(&rx_stats_mutex);
!         }
  	/* I DON"T LIKE THIS PRINTF -- PRINTFS MAKE THINGS VERY VERY SLOOWWW */
  	dpf(("rx: packet dropped: bad ulen=%d\n", asize));
  	tp = NULL;
***************
*** 1003,1012 ****
      }
      nam->m_len = sizeof(myaddr);
      memcpy(mtod(nam, caddr_t), &myaddr, sizeof(myaddr));
! #ifdef AFS_SGI65_ENV
      BHV_PDATA(&bhv) = (void *)newSocket;
      code = sobind(&bhv, nam);
      m_freem(nam);
  #else
      code = sobind(newSocket, nam);
  #endif
--- 1021,1032 ----
      }
      nam->m_len = sizeof(myaddr);
      memcpy(mtod(nam, caddr_t), &myaddr, sizeof(myaddr));
! #if defined(AFS_SGI65_ENV)
      BHV_PDATA(&bhv) = (void *)newSocket;
      code = sobind(&bhv, nam);
      m_freem(nam);
+ #elif defined(AFS_OBSD44_ENV)
+     code = sobind(newSocket, nam, osi_curproc());
  #else
      code = sobind(newSocket, nam);
  #endif
***************
*** 1175,1184 ****
  	p->length = nbytes - RX_HEADER_SIZE;;
  	if ((nbytes > tlen) || (p->length & 0x8000)) {	/* Bogus packet */
  	    if (nbytes <= 0) {
! 		MUTEX_ENTER(&rx_stats_mutex);
! 		rx_stats.bogusPacketOnRead++;
! 		rx_stats.bogusHost = from.sin_addr.s_addr;
! 		MUTEX_EXIT(&rx_stats_mutex);
  		dpf(("B: bogus packet from [%x,%d] nb=%d",
  		     from.sin_addr.s_addr, from.sin_port, nbytes));
  	    }
--- 1195,1206 ----
  	p->length = nbytes - RX_HEADER_SIZE;;
  	if ((nbytes > tlen) || (p->length & 0x8000)) {	/* Bogus packet */
  	    if (nbytes <= 0) {
!                 if (rx_stats_active) {
!                     MUTEX_ENTER(&rx_stats_mutex);
!                     rx_stats.bogusPacketOnRead++;
!                     rx_stats.bogusHost = from.sin_addr.s_addr;
!                     MUTEX_EXIT(&rx_stats_mutex);
!                 }
  		dpf(("B: bogus packet from [%x,%d] nb=%d",
  		     from.sin_addr.s_addr, from.sin_port, nbytes));
  	    }
***************
*** 1190,1198 ****
  	    *host = from.sin_addr.s_addr;
  	    *port = from.sin_port;
  	    if (p->header.type > 0 && p->header.type < RX_N_PACKET_TYPES) {
! 		MUTEX_ENTER(&rx_stats_mutex);
! 		rx_stats.packetsRead[p->header.type - 1]++;
! 		MUTEX_EXIT(&rx_stats_mutex);
  	    }
  
  	    /* Free any empty packet buffers at the end of this packet */
--- 1212,1222 ----
  	    *host = from.sin_addr.s_addr;
  	    *port = from.sin_port;
  	    if (p->header.type > 0 && p->header.type < RX_N_PACKET_TYPES) {
!                 if (rx_stats_active) {
!                     MUTEX_ENTER(&rx_stats_mutex);
!                     rx_stats.packetsRead[p->header.type - 1]++;
!                     MUTEX_EXIT(&rx_stats_mutex);
!                 }
  	    }
  
  	    /* Free any empty packet buffers at the end of this packet */
Index: openafs/src/rx/rx_misc.c
diff -c openafs/src/rx/rx_misc.c:1.13.8.3 openafs/src/rx/rx_misc.c:1.13.8.4
*** openafs/src/rx/rx_misc.c:1.13.8.3	Thu Jan 31 02:31:59 2008
--- openafs/src/rx/rx_misc.c	Wed Jan 14 01:34:19 2009
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_misc.c,v 1.13.8.3 2008/01/31 07:31:59 jaltman Exp $");
  
  #ifdef	KERNEL
  #include <afs/sysincludes.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_misc.c,v 1.13.8.4 2009/01/14 06:34:19 jaltman Exp $");
  
  #ifdef	KERNEL
  #include <afs/sysincludes.h>
***************
*** 106,114 ****
   */
  
  #include <assert.h>
! pthread_mutex_t osi_malloc_mutex;
! #define LOCK_MALLOC_STATS assert(pthread_mutex_lock(&osi_malloc_mutex)==0)
! #define UNLOCK_MALLOC_STATS assert(pthread_mutex_unlock(&osi_malloc_mutex)==0)
  #else
  #define LOCK_MALLOC_STATS
  #define UNLOCK_MALLOC_STATS
--- 106,114 ----
   */
  
  #include <assert.h>
! afs_kmutex_t osi_malloc_mutex;
! #define LOCK_MALLOC_STATS MUTEX_ENTER(&osi_malloc_mutex);
! #define UNLOCK_MALLOC_STATS MUTEX_EXIT(&osi_malloc_mutex);
  #else
  #define LOCK_MALLOC_STATS
  #define UNLOCK_MALLOC_STATS
Index: openafs/src/rx/rx_packet.c
diff -c openafs/src/rx/rx_packet.c:1.62.2.19 openafs/src/rx/rx_packet.c:1.62.2.22
*** openafs/src/rx/rx_packet.c:1.62.2.19	Mon Dec 29 17:38:30 2008
--- openafs/src/rx/rx_packet.c	Sat Jan 10 23:59:49 2009
***************
*** 15,21 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_packet.c,v 1.62.2.19 2008/12/29 22:38:30 jaltman Exp $");
  
  #ifdef KERNEL
  #if defined(UKERNEL)
--- 15,21 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_packet.c,v 1.62.2.22 2009/01/11 04:59:49 jaltman Exp $");
  
  #ifdef KERNEL
  #if defined(UKERNEL)
***************
*** 99,105 ****
  static int rxdb_fileID = RXDB_FILE_RX_PACKET;
  #endif /* RX_LOCKS_DB */
  static struct rx_packet *rx_mallocedP = 0;
! #ifdef DEBUG
  static afs_uint32       rx_packet_id = 0;
  #endif
  
--- 99,105 ----
  static int rxdb_fileID = RXDB_FILE_RX_PACKET;
  #endif /* RX_LOCKS_DB */
  static struct rx_packet *rx_mallocedP = 0;
! #ifdef RXDEBUG_PACKET
  static afs_uint32       rx_packet_id = 0;
  #endif
  
***************
*** 316,337 ****
  
      if (overq) {
  	rxi_NeedMorePackets = TRUE;
! 	switch (class) {
! 	case RX_PACKET_CLASS_RECEIVE:
! 	    rx_MutexIncrement(rx_stats.receivePktAllocFailures, rx_stats_mutex);
! 	    break;
! 	case RX_PACKET_CLASS_SEND:
! 	    rx_MutexIncrement(rx_stats.sendPktAllocFailures, rx_stats_mutex);
! 	    break;
! 	case RX_PACKET_CLASS_SPECIAL:
!             rx_MutexIncrement(rx_stats.specialPktAllocFailures, rx_stats_mutex);
! 	    break;
! 	case RX_PACKET_CLASS_RECV_CBUF:
! 	    rx_MutexIncrement(rx_stats.receiveCbufPktAllocFailures, rx_stats_mutex);
! 	    break;
! 	case RX_PACKET_CLASS_SEND_CBUF:
! 	    rx_MutexIncrement(rx_stats.sendCbufPktAllocFailures, rx_stats_mutex);
! 	    break;
  	}
      }
  
--- 316,339 ----
  
      if (overq) {
  	rxi_NeedMorePackets = TRUE;
!         if (rx_stats_active) {
!             switch (class) {
!             case RX_PACKET_CLASS_RECEIVE:
!                 rx_MutexIncrement(rx_stats.receivePktAllocFailures, rx_stats_mutex);
!                 break;
!             case RX_PACKET_CLASS_SEND:
!                 rx_MutexIncrement(rx_stats.sendPktAllocFailures, rx_stats_mutex);
!                 break;
!             case RX_PACKET_CLASS_SPECIAL:
!                 rx_MutexIncrement(rx_stats.specialPktAllocFailures, rx_stats_mutex);
!                 break;
!             case RX_PACKET_CLASS_RECV_CBUF:
!                 rx_MutexIncrement(rx_stats.receiveCbufPktAllocFailures, rx_stats_mutex);
!                 break;
!             case RX_PACKET_CLASS_SEND_CBUF:
!                 rx_MutexIncrement(rx_stats.sendCbufPktAllocFailures, rx_stats_mutex);
!                 break;
!             }
  	}
      }
  
***************
*** 552,561 ****
  
      RX_TS_FPQ_LOCAL_ALLOC(rx_ts_info,apackets);
      /* TSFPQ patch also needs to keep track of total packets */
!     MUTEX_ENTER(&rx_stats_mutex);
      rx_nPackets += apackets;
      RX_TS_FPQ_COMPUTE_LIMITS;
!     MUTEX_EXIT(&rx_stats_mutex);
  
      for (e = p + apackets; p < e; p++) {
          RX_PACKET_IOV_INIT(p);
--- 554,564 ----
  
      RX_TS_FPQ_LOCAL_ALLOC(rx_ts_info,apackets);
      /* TSFPQ patch also needs to keep track of total packets */
! 
!     MUTEX_ENTER(&rx_packets_mutex);
      rx_nPackets += apackets;
      RX_TS_FPQ_COMPUTE_LIMITS;
!     MUTEX_EXIT(&rx_packets_mutex);
  
      for (e = p + apackets; p < e; p++) {
          RX_PACKET_IOV_INIT(p);
***************
*** 565,574 ****
  
          NETPRI;
          MUTEX_ENTER(&rx_freePktQ_lock);
! #ifdef DEBUG
          p->packetId = rx_packet_id++;
          p->allNextp = rx_mallocedP;
! #endif /* DEBUG */
          rx_mallocedP = p;
          MUTEX_EXIT(&rx_freePktQ_lock);
          USERPRI;
--- 568,577 ----
  
          NETPRI;
          MUTEX_ENTER(&rx_freePktQ_lock);
! #ifdef RXDEBUG_PACKET
          p->packetId = rx_packet_id++;
          p->allNextp = rx_mallocedP;
! #endif /* RXDEBUG_PACKET */
          rx_mallocedP = p;
          MUTEX_EXIT(&rx_freePktQ_lock);
          USERPRI;
***************
*** 610,619 ****
  	p->niovecs = 2;
  
  	queue_Append(&rx_freePacketQueue, p);
! #ifdef DEBUG
          p->packetId = rx_packet_id++;
          p->allNextp = rx_mallocedP;
! #endif /* DEBUG */
  	rx_mallocedP = p;
      }
  
--- 613,622 ----
  	p->niovecs = 2;
  
  	queue_Append(&rx_freePacketQueue, p);
! #ifdef RXDEBUG_PACKET
          p->packetId = rx_packet_id++;
          p->allNextp = rx_mallocedP;
! #endif /* RXDEBUG_PACKET */
  	rx_mallocedP = p;
      }
  
***************
*** 644,653 ****
  
      RX_TS_FPQ_LOCAL_ALLOC(rx_ts_info,apackets);
      /* TSFPQ patch also needs to keep track of total packets */
!     MUTEX_ENTER(&rx_stats_mutex);
      rx_nPackets += apackets;
      RX_TS_FPQ_COMPUTE_LIMITS;
!     MUTEX_EXIT(&rx_stats_mutex);
  
      for (e = p + apackets; p < e; p++) {
          RX_PACKET_IOV_INIT(p);
--- 647,656 ----
  
      RX_TS_FPQ_LOCAL_ALLOC(rx_ts_info,apackets);
      /* TSFPQ patch also needs to keep track of total packets */
!     MUTEX_ENTER(&rx_packets_mutex);
      rx_nPackets += apackets;
      RX_TS_FPQ_COMPUTE_LIMITS;
!     MUTEX_EXIT(&rx_packets_mutex);
  
      for (e = p + apackets; p < e; p++) {
          RX_PACKET_IOV_INIT(p);
***************
*** 656,665 ****
  	
          NETPRI;
          MUTEX_ENTER(&rx_freePktQ_lock);
! #ifdef DEBUG
          p->packetId = rx_packet_id++;
          p->allNextp = rx_mallocedP;
! #endif /* DEBUG */
          rx_mallocedP = p;
          MUTEX_EXIT(&rx_freePktQ_lock);
          USERPRI;
--- 659,668 ----
  	
          NETPRI;
          MUTEX_ENTER(&rx_freePktQ_lock);
! #ifdef RXDEBUG_PACKET
          p->packetId = rx_packet_id++;
          p->allNextp = rx_mallocedP;
! #endif /* RXDEBUG_PACKET */
          rx_mallocedP = p;
          MUTEX_EXIT(&rx_freePktQ_lock);
          USERPRI;
***************
*** 717,736 ****
  	p->niovecs = 2;
  
  	queue_Append(&rx_freePacketQueue, p);
! #ifdef DEBUG
          p->packetId = rx_packet_id++;
          p->allNextp = rx_mallocedP;
! #endif /* DEBUG */
  	rx_mallocedP = p;
      }
  
      rx_nFreePackets += apackets;
  #ifdef RX_ENABLE_TSFPQ
      /* TSFPQ patch also needs to keep track of total packets */
!     MUTEX_ENTER(&rx_stats_mutex);
      rx_nPackets += apackets;
      RX_TS_FPQ_COMPUTE_LIMITS;
!     MUTEX_EXIT(&rx_stats_mutex);
  #endif /* RX_ENABLE_TSFPQ */
      rxi_NeedMorePackets = FALSE;
      rxi_PacketsUnWait();
--- 720,739 ----
  	p->niovecs = 2;
  
  	queue_Append(&rx_freePacketQueue, p);
! #ifdef RXDEBUG_PACKET
          p->packetId = rx_packet_id++;
          p->allNextp = rx_mallocedP;
! #endif /* RXDEBUG_PACKET */
  	rx_mallocedP = p;
      }
  
      rx_nFreePackets += apackets;
  #ifdef RX_ENABLE_TSFPQ
      /* TSFPQ patch also needs to keep track of total packets */
!     MUTEX_ENTER(&rx_packets_mutex);
      rx_nPackets += apackets;
      RX_TS_FPQ_COMPUTE_LIMITS;
!     MUTEX_EXIT(&rx_packets_mutex);
  #endif /* RX_ENABLE_TSFPQ */
      rxi_NeedMorePackets = FALSE;
      rxi_PacketsUnWait();
***************
*** 1124,1151 ****
  #ifdef KERNEL
      if (rxi_OverQuota(class)) {
  	rxi_NeedMorePackets = TRUE;
! 	switch (class) {
! 	case RX_PACKET_CLASS_RECEIVE:
! 	    rx_MutexIncrement(rx_stats.receivePktAllocFailures, rx_stats_mutex);
! 	    break;
! 	case RX_PACKET_CLASS_SEND:
! 	    rx_MutexIncrement(rx_stats.sendPktAllocFailures, rx_stats_mutex);
! 	    break;
! 	case RX_PACKET_CLASS_SPECIAL:
!             rx_MutexIncrement(rx_stats.specialPktAllocFailures, rx_stats_mutex);
! 	    break;
! 	case RX_PACKET_CLASS_RECV_CBUF:
! 	    rx_MutexIncrement(rx_stats.receiveCbufPktAllocFailures, rx_stats_mutex);
! 	    break;
! 	case RX_PACKET_CLASS_SEND_CBUF:
! 	    rx_MutexIncrement(rx_stats.sendCbufPktAllocFailures, rx_stats_mutex);
! 	    break;
  	}
          return (struct rx_packet *)0;
      }
  #endif /* KERNEL */
  
!     rx_MutexIncrement(rx_stats.packetRequests, rx_stats_mutex);
      if (queue_IsEmpty(&rx_ts_info->_FPQ)) {
  
  #ifdef KERNEL
--- 1127,1157 ----
  #ifdef KERNEL
      if (rxi_OverQuota(class)) {
  	rxi_NeedMorePackets = TRUE;
!         if (rx_stats_active) {
!             switch (class) {
!             case RX_PACKET_CLASS_RECEIVE:
!                 rx_MutexIncrement(rx_stats.receivePktAllocFailures, rx_stats_mutex);
!                 break;
!             case RX_PACKET_CLASS_SEND:
!                 rx_MutexIncrement(rx_stats.sendPktAllocFailures, rx_stats_mutex);
!                 break;
!             case RX_PACKET_CLASS_SPECIAL:
!                 rx_MutexIncrement(rx_stats.specialPktAllocFailures, rx_stats_mutex);
!                 break;
!             case RX_PACKET_CLASS_RECV_CBUF:
!                 rx_MutexIncrement(rx_stats.receiveCbufPktAllocFailures, rx_stats_mutex);
!                 break;
!             case RX_PACKET_CLASS_SEND_CBUF:
!                 rx_MutexIncrement(rx_stats.sendCbufPktAllocFailures, rx_stats_mutex);
!                 break;
!             }
  	}
          return (struct rx_packet *)0;
      }
  #endif /* KERNEL */
  
!     if (rx_stats_active)
!         rx_MutexIncrement(rx_stats.packetRequests, rx_stats_mutex);
      if (queue_IsEmpty(&rx_ts_info->_FPQ)) {
  
  #ifdef KERNEL
***************
*** 1181,1208 ****
  #ifdef KERNEL
      if (rxi_OverQuota(class)) {
  	rxi_NeedMorePackets = TRUE;
! 	switch (class) {
! 	case RX_PACKET_CLASS_RECEIVE:
! 	    rx_MutexIncrement(rx_stats.receivePktAllocFailures, rx_stats_mutex);
! 	    break;
! 	case RX_PACKET_CLASS_SEND:
! 	    rx_MutexIncrement(rx_stats.sendPktAllocFailures, rx_stats_mutex);
! 	    break;
! 	case RX_PACKET_CLASS_SPECIAL:
!             rx_MutexIncrement(rx_stats.specialPktAllocFailures, rx_stats_mutex);
! 	    break;
! 	case RX_PACKET_CLASS_RECV_CBUF:
! 	    rx_MutexIncrement(rx_stats.receiveCbufPktAllocFailures, rx_stats_mutex);
! 	    break;
! 	case RX_PACKET_CLASS_SEND_CBUF:
! 	    rx_MutexIncrement(rx_stats.sendCbufPktAllocFailures, rx_stats_mutex);
! 	    break;
! 	}
  	return (struct rx_packet *)0;
      }
  #endif /* KERNEL */
  
!     rx_MutexIncrement(rx_stats.packetRequests, rx_stats_mutex);
  
  #ifdef KERNEL
      if (queue_IsEmpty(&rx_freePacketQueue))
--- 1187,1217 ----
  #ifdef KERNEL
      if (rxi_OverQuota(class)) {
  	rxi_NeedMorePackets = TRUE;
!         if (rx_stats_active) {
!             switch (class) {
!             case RX_PACKET_CLASS_RECEIVE:
!                 rx_MutexIncrement(rx_stats.receivePktAllocFailures, rx_stats_mutex);
!                 break;
!             case RX_PACKET_CLASS_SEND:
!                 rx_MutexIncrement(rx_stats.sendPktAllocFailures, rx_stats_mutex);
!                 break;
!             case RX_PACKET_CLASS_SPECIAL:
!                 rx_MutexIncrement(rx_stats.specialPktAllocFailures, rx_stats_mutex);
!                 break;
!             case RX_PACKET_CLASS_RECV_CBUF:
!                 rx_MutexIncrement(rx_stats.receiveCbufPktAllocFailures, rx_stats_mutex);
!                 break;
!             case RX_PACKET_CLASS_SEND_CBUF:
!                 rx_MutexIncrement(rx_stats.sendCbufPktAllocFailures, rx_stats_mutex);
!                 break;
!             }
!         }
  	return (struct rx_packet *)0;
      }
  #endif /* KERNEL */
  
!     if (rx_stats_active)
!         rx_MutexIncrement(rx_stats.packetRequests, rx_stats_mutex);
  
  #ifdef KERNEL
      if (queue_IsEmpty(&rx_freePacketQueue))
***************
*** 1238,1244 ****
  
      RX_TS_INFO_GET(rx_ts_info);
  
!     rx_MutexIncrement(rx_stats.packetRequests, rx_stats_mutex);
      if (pull_global && queue_IsEmpty(&rx_ts_info->_FPQ)) {
          MUTEX_ENTER(&rx_freePktQ_lock);
  
--- 1247,1254 ----
  
      RX_TS_INFO_GET(rx_ts_info);
  
!     if (rx_stats_active)
!         rx_MutexIncrement(rx_stats.packetRequests, rx_stats_mutex);
      if (pull_global && queue_IsEmpty(&rx_ts_info->_FPQ)) {
          MUTEX_ENTER(&rx_freePktQ_lock);
  
***************
*** 1458,1469 ****
      p->length = (nbytes - RX_HEADER_SIZE);
      if ((nbytes > tlen) || (p->length & 0x8000)) {	/* Bogus packet */
  	if (nbytes < 0 && errno == EWOULDBLOCK) {
!             rx_MutexIncrement(rx_stats.noPacketOnRead, rx_stats_mutex);
  	} else if (nbytes <= 0) {
! 	    MUTEX_ENTER(&rx_stats_mutex);
! 	    rx_stats.bogusPacketOnRead++;
! 	    rx_stats.bogusHost = from.sin_addr.s_addr;
! 	    MUTEX_EXIT(&rx_stats_mutex);
  	    dpf(("B: bogus packet from [%x,%d] nb=%d", ntohl(from.sin_addr.s_addr),
  		 ntohs(from.sin_port), nbytes));
  	}
--- 1468,1482 ----
      p->length = (nbytes - RX_HEADER_SIZE);
      if ((nbytes > tlen) || (p->length & 0x8000)) {	/* Bogus packet */
  	if (nbytes < 0 && errno == EWOULDBLOCK) {
!             if (rx_stats_active)
!                 rx_MutexIncrement(rx_stats.noPacketOnRead, rx_stats_mutex);
  	} else if (nbytes <= 0) {
!             if (rx_stats_active) {
!                 MUTEX_ENTER(&rx_stats_mutex);
!                 rx_stats.bogusPacketOnRead++;
!                 rx_stats.bogusHost = from.sin_addr.s_addr;
!                 MUTEX_EXIT(&rx_stats_mutex);
!             }
  	    dpf(("B: bogus packet from [%x,%d] nb=%d", ntohl(from.sin_addr.s_addr),
  		 ntohs(from.sin_port), nbytes));
  	}
***************
*** 1493,1499 ****
  	*port = from.sin_port;
  	if (p->header.type > 0 && p->header.type < RX_N_PACKET_TYPES) {
  	    struct rx_peer *peer;
!             rx_MutexIncrement(rx_stats.packetsRead[p->header.type - 1], rx_stats_mutex);
  	    /*
  	     * Try to look up this peer structure.  If it doesn't exist,
  	     * don't create a new one - 
--- 1506,1513 ----
  	*port = from.sin_port;
  	if (p->header.type > 0 && p->header.type < RX_N_PACKET_TYPES) {
  	    struct rx_peer *peer;
!             if (rx_stats_active)
!                 rx_MutexIncrement(rx_stats.packetsRead[p->header.type - 1], rx_stats_mutex);
  	    /*
  	     * Try to look up this peer structure.  If it doesn't exist,
  	     * don't create a new one - 
***************
*** 2037,2042 ****
--- 2051,2057 ----
  		return ap;
  
  	    /* Since its all int32s convert to network order with a loop. */
+         if (rx_stats_active)
  	    MUTEX_ENTER(&rx_stats_mutex);
  	    s = (afs_int32 *) & rx_stats;
  	    for (i = 0; i < sizeof(rx_stats) / sizeof(afs_int32); i++, s++)
***************
*** 2044,2049 ****
--- 2059,2065 ----
  
  	    tl = ap->length;
  	    ap->length = sizeof(rx_stats);
+         if (rx_stats_active)
  	    MUTEX_EXIT(&rx_stats_mutex);
  	    rxi_SendDebugPacket(ap, asocket, ahost, aport, istack);
  	    ap->length = tl;
***************
*** 2259,2265 ****
  	     osi_NetSend(socket, &addr, p->wirevec, p->niovecs,
  			 p->length + RX_HEADER_SIZE, istack)) != 0) {
  	    /* send failed, so let's hurry up the resend, eh? */
!             rx_MutexIncrement(rx_stats.netSendFailures, rx_stats_mutex);
  	    p->retryTime = p->timeSent;	/* resend it very soon */
  	    clock_Addmsec(&(p->retryTime),
  			  10 + (((afs_uint32) p->backoff) << 8));
--- 2275,2282 ----
  	     osi_NetSend(socket, &addr, p->wirevec, p->niovecs,
  			 p->length + RX_HEADER_SIZE, istack)) != 0) {
  	    /* send failed, so let's hurry up the resend, eh? */
!             if (rx_stats_active)
!                 rx_MutexIncrement(rx_stats.netSendFailures, rx_stats_mutex);
  	    p->retryTime = p->timeSent;	/* resend it very soon */
  	    clock_Addmsec(&(p->retryTime),
  			  10 + (((afs_uint32) p->backoff) << 8));
***************
*** 2299,2305 ****
      }
      dpf(("%c %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %lx resend %d.%0.3d len %d", deliveryType, p->header.serial, rx_packetTypes[p->header.type - 1], ntohl(peer->host), ntohs(peer->port), p->header.serial, p->header.epoch, p->header.cid, p->header.callNumber, p->header.seq, p->header.flags, (unsigned long)p, p->retryTime.sec, p->retryTime.usec / 1000, p->length));
  #endif
!     rx_MutexIncrement(rx_stats.packetsSent[p->header.type - 1], rx_stats_mutex);
      MUTEX_ENTER(&peer->peer_lock);
      hadd32(peer->bytesSent, p->length);
      MUTEX_EXIT(&peer->peer_lock);
--- 2316,2323 ----
      }
      dpf(("%c %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %lx resend %d.%0.3d len %d", deliveryType, p->header.serial, rx_packetTypes[p->header.type - 1], ntohl(peer->host), ntohs(peer->port), p->header.serial, p->header.epoch, p->header.cid, p->header.callNumber, p->header.seq, p->header.flags, (unsigned long)p, p->retryTime.sec, p->retryTime.usec / 1000, p->length));
  #endif
!     if (rx_stats_active)
!         rx_MutexIncrement(rx_stats.packetsSent[p->header.type - 1], rx_stats_mutex);
      MUTEX_ENTER(&peer->peer_lock);
      hadd32(peer->bytesSent, p->length);
      MUTEX_EXIT(&peer->peer_lock);
***************
*** 2444,2450 ****
  	     osi_NetSend(socket, &addr, &wirevec[0], len + 1, length,
  			 istack)) != 0) {
  	    /* send failed, so let's hurry up the resend, eh? */
!             rx_MutexIncrement(rx_stats.netSendFailures, rx_stats_mutex);
  	    for (i = 0; i < len; i++) {
  		p = list[i];
  		p->retryTime = p->timeSent;	/* resend it very soon */
--- 2462,2469 ----
  	     osi_NetSend(socket, &addr, &wirevec[0], len + 1, length,
  			 istack)) != 0) {
  	    /* send failed, so let's hurry up the resend, eh? */
!             if (rx_stats_active)
!                 rx_MutexIncrement(rx_stats.netSendFailures, rx_stats_mutex);
  	    for (i = 0; i < len; i++) {
  		p = list[i];
  		p->retryTime = p->timeSent;	/* resend it very soon */
***************
*** 2481,2487 ****
      dpf(("%c %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %lx resend %d.%0.3d len %d", deliveryType, p->header.serial, rx_packetTypes[p->header.type - 1], ntohl(peer->host), ntohs(peer->port), p->header.serial, p->header.epoch, p->header.cid, p->header.callNumber, p->header.seq, p->header.flags, (unsigned long)p, p->retryTime.sec, p->retryTime.usec / 1000, p->length));
  
  #endif
!     rx_MutexIncrement(rx_stats.packetsSent[p->header.type - 1], rx_stats_mutex);
      MUTEX_ENTER(&peer->peer_lock);
      hadd32(peer->bytesSent, p->length);
      MUTEX_EXIT(&peer->peer_lock);
--- 2500,2507 ----
      dpf(("%c %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %lx resend %d.%0.3d len %d", deliveryType, p->header.serial, rx_packetTypes[p->header.type - 1], ntohl(peer->host), ntohs(peer->port), p->header.serial, p->header.epoch, p->header.cid, p->header.callNumber, p->header.seq, p->header.flags, (unsigned long)p, p->retryTime.sec, p->retryTime.usec / 1000, p->length));
  
  #endif
!     if (rx_stats_active)
!         rx_MutexIncrement(rx_stats.packetsSent[p->header.type - 1], rx_stats_mutex);
      MUTEX_ENTER(&peer->peer_lock);
      hadd32(peer->bytesSent, p->length);
      MUTEX_EXIT(&peer->peer_lock);
***************
*** 2749,2755 ****
   */
  int rx_DumpPackets(FILE *outputFile, char *cookie)
  {
! #ifdef DEBUG
      int zilch;
      struct rx_packet *p;
      char output[2048];
--- 2769,2775 ----
   */
  int rx_DumpPackets(FILE *outputFile, char *cookie)
  {
! #ifdef RXDEBUG_PACKET
      int zilch;
      struct rx_packet *p;
      char output[2048];
***************
*** 2774,2780 ****
  
      MUTEX_EXIT(&rx_freePktQ_lock);
      USERPRI;
! #endif /* DEBUG */
      return 0;
  }
  #endif /* AFS_NT40_ENV */
--- 2794,2800 ----
  
      MUTEX_EXIT(&rx_freePktQ_lock);
      USERPRI;
! #endif /* RXDEBUG_PACKET */
      return 0;
  }
  #endif /* AFS_NT40_ENV */
Index: openafs/src/rx/rx_packet.h
diff -c openafs/src/rx/rx_packet.h:1.14.4.4 openafs/src/rx/rx_packet.h:1.14.4.5
*** openafs/src/rx/rx_packet.h:1.14.4.4	Mon Dec 29 17:38:30 2008
--- openafs/src/rx/rx_packet.h	Sun Jan  4 19:00:21 2009
***************
*** 271,277 ****
      afs_uint32 wirehead[RX_HEADER_SIZE / sizeof(afs_int32)];
      afs_uint32 localdata[RX_CBUFFERSIZE / sizeof(afs_int32)];
      afs_uint32 extradata[RX_EXTRABUFFERSIZE / sizeof(afs_int32)];
! #ifdef DEBUG
      /* For debugging */
      struct rx_packet *allNextp; /* A list of all packets */
      afs_uint32  packetId;       /* An unique id number for debugging */
--- 271,277 ----
      afs_uint32 wirehead[RX_HEADER_SIZE / sizeof(afs_int32)];
      afs_uint32 localdata[RX_CBUFFERSIZE / sizeof(afs_int32)];
      afs_uint32 extradata[RX_EXTRABUFFERSIZE / sizeof(afs_int32)];
! #ifdef RXDEBUG_PACKET
      /* For debugging */
      struct rx_packet *allNextp; /* A list of all packets */
      afs_uint32  packetId;       /* An unique id number for debugging */
Index: openafs/src/rx/rx_prototypes.h
diff -c openafs/src/rx/rx_prototypes.h:1.29.4.15 openafs/src/rx/rx_prototypes.h:1.29.4.17
*** openafs/src/rx/rx_prototypes.h:1.29.4.15	Mon Dec 15 14:12:21 2008
--- openafs/src/rx/rx_prototypes.h	Wed Jan 14 01:34:19 2009
***************
*** 26,31 ****
--- 26,32 ----
  extern int rx_InitHost(u_int host, u_int port);
  #ifdef AFS_NT40_ENV
  extern void rx_DebugOnOff(int on);
+ extern void rx_StatsOnOff(int on);
  #endif
  #ifndef KERNEL
  extern void rxi_StartServerProcs(int nExistingProcs);
***************
*** 595,602 ****
  
  /* rx_user.c */
  #ifdef AFS_PTHREAD_ENV
! extern pthread_mutex_t rx_if_init_mutex;
! extern pthread_mutex_t rx_if_mutex;
  #endif
  extern osi_socket rxi_GetUDPSocket(u_short port);
  extern void osi_AssertFailU(const char *expr, const char *file, int line);
--- 596,603 ----
  
  /* rx_user.c */
  #ifdef AFS_PTHREAD_ENV
! extern afs_kmutex_t rx_if_init_mutex;
! extern afs_kmutex_t rx_if_mutex;
  #endif
  extern osi_socket rxi_GetUDPSocket(u_short port);
  extern void osi_AssertFailU(const char *expr, const char *file, int line);
Index: openafs/src/rx/rx_pthread.c
diff -c openafs/src/rx/rx_pthread.c:1.24.4.6 openafs/src/rx/rx_pthread.c:1.24.4.8
*** openafs/src/rx/rx_pthread.c:1.24.4.6	Tue May 20 17:59:02 2008
--- openafs/src/rx/rx_pthread.c	Wed Jan 14 01:34:19 2009
***************
*** 19,25 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_pthread.c,v 1.24.4.6 2008/05/20 21:59:02 shadow Exp $");
  
  #include <sys/types.h>
  #include <errno.h>
--- 19,25 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_pthread.c,v 1.24.4.8 2009/01/14 06:34:19 jaltman Exp $");
  
  #include <sys/types.h>
  #include <errno.h>
***************
*** 65,76 ****
   * This thread is also responsible for keeping time.
   */
  static pthread_t event_handler_thread;
! pthread_cond_t rx_event_handler_cond;
! pthread_mutex_t event_handler_mutex;
! pthread_cond_t rx_listener_cond;
! pthread_mutex_t listener_mutex;
  static int listeners_started = 0;
! pthread_mutex_t rx_clock_mutex;
  struct clock rxi_clockNow;
  
  /*
--- 65,76 ----
   * This thread is also responsible for keeping time.
   */
  static pthread_t event_handler_thread;
! afs_kcondvar_t rx_event_handler_cond;
! afs_kmutex_t event_handler_mutex;
! afs_kcondvar_t rx_listener_cond;
! afs_kmutex_t listener_mutex;
  static int listeners_started = 0;
! afs_kmutex_t rx_clock_mutex;
  struct clock rxi_clockNow;
  
  /*
***************
*** 150,169 ****
      struct timespec rx_pthread_next_event_time = { 0, 0 };
      int error;
  
!     assert(pthread_mutex_lock(&event_handler_mutex) == 0);
  
      for (;;) {
  	struct clock cv;
  	struct clock next;
  
! 	assert(pthread_mutex_unlock(&event_handler_mutex) == 0);
  
  	next.sec = 30;		/* Time to sleep if there are no events scheduled */
  	next.usec = 0;
  	clock_GetTime(&cv);
  	rxevent_RaiseEvents(&next);
  
! 	assert(pthread_mutex_lock(&event_handler_mutex) == 0);
  	if (rx_pthread_event_rescheduled) {
  	    rx_pthread_event_rescheduled = 0;
  	    continue;
--- 150,169 ----
      struct timespec rx_pthread_next_event_time = { 0, 0 };
      int error;
  
!     MUTEX_ENTER(&event_handler_mutex);
  
      for (;;) {
  	struct clock cv;
  	struct clock next;
  
! 	MUTEX_EXIT(&event_handler_mutex);
  
  	next.sec = 30;		/* Time to sleep if there are no events scheduled */
  	next.usec = 0;
  	clock_GetTime(&cv);
  	rxevent_RaiseEvents(&next);
  
! 	MUTEX_ENTER(&event_handler_mutex);
  	if (rx_pthread_event_rescheduled) {
  	    rx_pthread_event_rescheduled = 0;
  	    continue;
***************
*** 173,181 ****
  	rx_pthread_next_event_time.tv_sec = cv.sec;
  	rx_pthread_next_event_time.tv_nsec = cv.usec * 1000;
  	rx_pthread_n_event_waits++;
! 	error = pthread_cond_timedwait
! 	    (&rx_event_handler_cond, &event_handler_mutex,
! 	     &rx_pthread_next_event_time);
          if (error == 0) {
  	    rx_pthread_n_event_woken++;
          } 
--- 173,179 ----
  	rx_pthread_next_event_time.tv_sec = cv.sec;
  	rx_pthread_next_event_time.tv_nsec = cv.usec * 1000;
  	rx_pthread_n_event_waits++;
! 	error = CV_TIMEDWAIT(&rx_event_handler_cond, &event_handler_mutex, &rx_pthread_next_event_time);
          if (error == 0) {
  	    rx_pthread_n_event_woken++;
          } 
***************
*** 203,212 ****
  void
  rxi_ReScheduleEvents(void)
  {
!     assert(pthread_mutex_lock(&event_handler_mutex) == 0);
!     pthread_cond_signal(&rx_event_handler_cond);
      rx_pthread_event_rescheduled = 1;
!     assert(pthread_mutex_unlock(&event_handler_mutex) == 0);
  }
  
  
--- 201,210 ----
  void
  rxi_ReScheduleEvents(void)
  {
!     MUTEX_ENTER(&event_handler_mutex);
!     CV_SIGNAL(&rx_event_handler_cond);
      rx_pthread_event_rescheduled = 1;
!     MUTEX_EXIT(&event_handler_mutex);
  }
  
  
***************
*** 219,229 ****
      u_short port;
      register struct rx_packet *p = (struct rx_packet *)0;
  
!     assert(pthread_mutex_lock(&listener_mutex) == 0);
      while (!listeners_started) {
! 	assert(pthread_cond_wait(&rx_listener_cond, &listener_mutex) == 0);
      }
!     assert(pthread_mutex_unlock(&listener_mutex) == 0);
  
      for (;;) {
  	/*
--- 217,227 ----
      u_short port;
      register struct rx_packet *p = (struct rx_packet *)0;
  
!     MUTEX_ENTER(&listener_mutex);
      while (!listeners_started) {
! 	CV_WAIT(&rx_listener_cond, &listener_mutex);
      }
!     MUTEX_EXIT(&listener_mutex);
  
      for (;;) {
  	/*
***************
*** 287,293 ****
      struct rx_call *newcall = NULL;
  
      rxi_MorePackets(rx_maxReceiveWindow + 2);	/* alloc more packets */
!     MUTEX_ENTER(&rx_stats_mutex);
      rxi_dataQuota += rx_initSendWindow;	/* Reserve some pkts for hard times */
      /* threadID is used for making decisions in GetCall.  Get it by bumping
       * number of threads handling incoming calls */
--- 285,291 ----
      struct rx_call *newcall = NULL;
  
      rxi_MorePackets(rx_maxReceiveWindow + 2);	/* alloc more packets */
!     MUTEX_ENTER(&rx_quota_mutex);
      rxi_dataQuota += rx_initSendWindow;	/* Reserve some pkts for hard times */
      /* threadID is used for making decisions in GetCall.  Get it by bumping
       * number of threads handling incoming calls */
***************
*** 302,312 ****
       * So either introduce yet another counter or flag the FCFS
       * thread... chose the latter.
       */
      threadID = ++rxi_pthread_hinum;
      if (rxi_fcfs_thread_num == 0 && rxi_fcfs_thread_num != threadID)
  	rxi_fcfs_thread_num = threadID;
      ++rxi_availProcs;
!     MUTEX_EXIT(&rx_stats_mutex);
  
      while (1) {
  	sock = OSI_NULLSOCKET;
--- 300,312 ----
       * So either introduce yet another counter or flag the FCFS
       * thread... chose the latter.
       */
+     MUTEX_ENTER(&rx_pthread_mutex);
      threadID = ++rxi_pthread_hinum;
      if (rxi_fcfs_thread_num == 0 && rxi_fcfs_thread_num != threadID)
  	rxi_fcfs_thread_num = threadID;
+     MUTEX_EXIT(&rx_pthread_mutex);
      ++rxi_availProcs;
!     MUTEX_EXIT(&rx_quota_mutex);
  
      while (1) {
  	sock = OSI_NULLSOCKET;
***************
*** 357,371 ****
  	dpf(("Unable to create Rx event handling thread\n"));
  	exit(1);
      }
!     MUTEX_ENTER(&rx_stats_mutex);
      ++rxi_pthread_hinum;
!     MUTEX_EXIT(&rx_stats_mutex);
      AFS_SIGSET_RESTORE();
  
!     assert(pthread_mutex_lock(&listener_mutex) == 0);
!     assert(pthread_cond_broadcast(&rx_listener_cond) == 0);
      listeners_started = 1;
!     assert(pthread_mutex_unlock(&listener_mutex) == 0);
  
  }
  
--- 357,371 ----
  	dpf(("Unable to create Rx event handling thread\n"));
  	exit(1);
      }
!     MUTEX_ENTER(&rx_pthread_mutex);
      ++rxi_pthread_hinum;
!     MUTEX_EXIT(&rx_pthread_mutex);
      AFS_SIGSET_RESTORE();
  
!     MUTEX_ENTER(&listener_mutex);
!     CV_BROADCAST(&rx_listener_cond);
      listeners_started = 1;
!     MUTEX_EXIT(&listener_mutex);
  
  }
  
***************
*** 396,404 ****
  	dpf(("Unable to create socket listener thread\n"));
  	exit(1);
      }
!     MUTEX_ENTER(&rx_stats_mutex);
      ++rxi_pthread_hinum;
!     MUTEX_EXIT(&rx_stats_mutex);
      AFS_SIGSET_RESTORE();
      return 0;
  }
--- 396,404 ----
  	dpf(("Unable to create socket listener thread\n"));
  	exit(1);
      }
!     MUTEX_ENTER(&rx_pthread_mutex);
      ++rxi_pthread_hinum;
!     MUTEX_EXIT(&rx_pthread_mutex);
      AFS_SIGSET_RESTORE();
      return 0;
  }
***************
*** 451,460 ****
  #ifdef RX_ENABLE_TSFPQ
      queue_Init(&rx_ts_info->_FPQ);
  
!     MUTEX_ENTER(&rx_stats_mutex);
      rx_TSFPQMaxProcs++;
      RX_TS_FPQ_COMPUTE_LIMITS;
!     MUTEX_EXIT(&rx_stats_mutex);
  #endif /* RX_ENABLE_TSFPQ */
      return rx_ts_info;
  }
--- 451,460 ----
  #ifdef RX_ENABLE_TSFPQ
      queue_Init(&rx_ts_info->_FPQ);
  
!     MUTEX_ENTER(&rx_packets_mutex);
      rx_TSFPQMaxProcs++;
      RX_TS_FPQ_COMPUTE_LIMITS;
!     MUTEX_EXIT(&rx_packets_mutex);
  #endif /* RX_ENABLE_TSFPQ */
      return rx_ts_info;
  }
Index: openafs/src/rx/rx_pthread.h
diff -c openafs/src/rx/rx_pthread.h:1.5.6.1 openafs/src/rx/rx_pthread.h:1.5.6.2
*** openafs/src/rx/rx_pthread.h:1.5.6.1	Thu Sep 25 07:50:58 2008
--- openafs/src/rx/rx_pthread.h	Wed Jan 14 01:34:19 2009
***************
*** 114,119 ****
--- 114,124 ----
  #endif
  #define CV_WAIT(cv, l) osi_Assert(pthread_cond_wait(cv, l) == 0)
  
+ #ifdef CV_TIMEDWAIT
+ #undef CV_TIMEDWAIT
+ #endif
+ #define CV_TIMEDWAIT(cv, l, t) pthread_cond_timedwait(cv, l, t)
+ 
  #ifdef CV_SIGNAL
  #undef CV_SIGNAL
  #endif
Index: openafs/src/rx/rx_rdwr.c
diff -c openafs/src/rx/rx_rdwr.c:1.29.2.12 openafs/src/rx/rx_rdwr.c:1.29.2.14
*** openafs/src/rx/rx_rdwr.c:1.29.2.12	Mon Dec 29 17:38:30 2008
--- openafs/src/rx/rx_rdwr.c	Mon Jan  5 18:13:08 2009
***************
*** 15,21 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_rdwr.c,v 1.29.2.12 2008/12/29 22:38:30 jaltman Exp $");
  
  #ifdef KERNEL
  #ifndef UKERNEL
--- 15,21 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_rdwr.c,v 1.29.2.14 2009/01/05 23:13:08 jaltman Exp $");
  
  #ifdef KERNEL
  #ifndef UKERNEL
***************
*** 114,122 ****
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
      if (queue_IsNotEmpty(&call->iovq)) {
! #ifdef DEBUG
          call->iovqc -=
! #endif /* DEBUG */
              rxi_FreePackets(0, &call->iovq);
      }
  
--- 114,122 ----
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
      if (queue_IsNotEmpty(&call->iovq)) {
! #ifdef RXDEBUG_PACKET
          call->iovqc -=
! #endif /* RXDEBUG_PACKET */
              rxi_FreePackets(0, &call->iovq);
      }
  
***************
*** 141,149 ****
  			register struct rx_connection *conn = call->conn;
  			queue_Remove(rp);
  			rp->flags &= ~RX_PKTFLAG_RQ;
! #ifdef DEBUG
                          call->rqc--;
! #endif /* DEBUG */
  
  			/* RXS_CheckPacket called to undo RXS_PreparePacket's
  			 * work.  It may reduce the length of the packet by up
--- 141,149 ----
  			register struct rx_connection *conn = call->conn;
  			queue_Remove(rp);
  			rp->flags &= ~RX_PKTFLAG_RQ;
! #ifdef RXDEBUG_PACKET
                          call->rqc--;
! #endif /* RXDEBUG_PACKET */
  
  			/* RXS_CheckPacket called to undo RXS_PreparePacket's
  			 * work.  It may reduce the length of the packet by up
***************
*** 241,246 ****
--- 241,248 ----
  		    osi_rxSleep(&call->rq);
  #endif
  		}
+                 /* cp is no longer valid since we may have given up the lock */
+                 cp = call->currentPacket;
  
  		call->startWait = 0;
  #ifdef RX_ENABLE_LOCKS
***************
*** 317,325 ****
       * ReadvProc/WritevProc.
       */
      if (!queue_IsEmpty(&call->iovq)) {
! #ifdef DEBUG
          call->iovqc -=
! #endif /* DEBUG */
              rxi_FreePackets(0, &call->iovq);
      }
  
--- 319,327 ----
       * ReadvProc/WritevProc.
       */
      if (!queue_IsEmpty(&call->iovq)) {
! #ifdef RXDEBUG_PACKET
          call->iovqc -=
! #endif /* RXDEBUG_PACKET */
              rxi_FreePackets(0, &call->iovq);
      }
  
***************
*** 377,385 ****
       * ReadvProc/WritevProc.
       */
      if (!queue_IsEmpty(&call->iovq)) {
! #ifdef DEBUG
          call->iovqc -=
! #endif /* DEBUG */
              rxi_FreePackets(0, &call->iovq);
      }
  
--- 379,387 ----
       * ReadvProc/WritevProc.
       */
      if (!queue_IsEmpty(&call->iovq)) {
! #ifdef RXDEBUG_PACKET
          call->iovqc -=
! #endif /* RXDEBUG_PACKET */
              rxi_FreePackets(0, &call->iovq);
      }
  
***************
*** 453,461 ****
  		    register struct rx_connection *conn = call->conn;
  		    queue_Remove(rp);
  		    rp->flags &= ~RX_PKTFLAG_RQ;
! #ifdef DEBUG
                      call->rqc--;
! #endif /* DEBUG */
  
  		    /* RXS_CheckPacket called to undo RXS_PreparePacket's
  		     * work.  It may reduce the length of the packet by up
--- 455,463 ----
  		    register struct rx_connection *conn = call->conn;
  		    queue_Remove(rp);
  		    rp->flags &= ~RX_PKTFLAG_RQ;
! #ifdef RXDEBUG_PACKET
                      call->rqc--;
! #endif /* RXDEBUG_PACKET */
  
  		    /* RXS_CheckPacket called to undo RXS_PreparePacket's
  		     * work.  It may reduce the length of the packet by up
***************
*** 537,545 ****
                  curp->flags &= ~RX_PKTFLAG_CP;
                  curp->flags |= RX_PKTFLAG_IOVQ;
  		queue_Append(&call->iovq, curp);
! #ifdef DEBUG
                  call->iovqc++;
! #endif /* DEBUG */
  		curp = call->currentPacket = (struct rx_packet *)0;
  	    } else if (!call->curlen) {
  		/* need to get another struct iov */
--- 539,547 ----
                  curp->flags &= ~RX_PKTFLAG_CP;
                  curp->flags |= RX_PKTFLAG_IOVQ;
  		queue_Append(&call->iovq, curp);
! #ifdef RXDEBUG_PACKET
                  call->iovqc++;
! #endif /* RXDEBUG_PACKET */
  		curp = call->currentPacket = (struct rx_packet *)0;
  	    } else if (!call->curlen) {
  		/* need to get another struct iov */
***************
*** 549,557 ****
  		    curp->flags &= ~RX_PKTFLAG_CP;
  		    curp->flags |= RX_PKTFLAG_IOVQ;
  		    queue_Append(&call->iovq, curp);
! #ifdef DEBUG
                      call->iovqc++;
! #endif /* DEBUG */
  		    curp = call->currentPacket = (struct rx_packet *)0;
  		    call->nLeft = 0;
  		} else {
--- 551,559 ----
  		    curp->flags &= ~RX_PKTFLAG_CP;
  		    curp->flags |= RX_PKTFLAG_IOVQ;
  		    queue_Append(&call->iovq, curp);
! #ifdef RXDEBUG_PACKET
                      call->iovqc++;
! #endif /* RXDEBUG_PACKET */
  		    curp = call->currentPacket = (struct rx_packet *)0;
  		    call->nLeft = 0;
  		} else {
***************
*** 611,619 ****
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
      if (queue_IsNotEmpty(&call->iovq)) {
! #ifdef DEBUG
          call->iovqc -=
! #endif /* DEBUG */
              rxi_FreePackets(0, &call->iovq);
      }
  
--- 613,621 ----
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
      if (queue_IsNotEmpty(&call->iovq)) {
! #ifdef RXDEBUG_PACKET
          call->iovqc -=
! #endif /* RXDEBUG_PACKET */
              rxi_FreePackets(0, &call->iovq);
      }
  
***************
*** 696,704 ****
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
      if (queue_IsNotEmpty(&call->iovq)) {
! #ifdef DEBUG
          call->iovqc -=
! #endif /* DEBUG */
              rxi_FreePackets(0, &call->iovq);
      }
  
--- 698,706 ----
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
      if (queue_IsNotEmpty(&call->iovq)) {
! #ifdef RXDEBUG_PACKET
          call->iovqc -=
! #endif /* RXDEBUG_PACKET */
              rxi_FreePackets(0, &call->iovq);
      }
  
***************
*** 754,762 ****
  		rxi_PrepareSendPacket(call, cp, 0);
  		cp->flags |= RX_PKTFLAG_TQ;
  		queue_Append(&call->tq, cp);
! #ifdef DEBUG
                  call->tqc++;
! #endif /* DEBUG */
                  cp = (struct rx_packet *)0;
  		if (!
  		    (call->
--- 756,764 ----
  		rxi_PrepareSendPacket(call, cp, 0);
  		cp->flags |= RX_PKTFLAG_TQ;
  		queue_Append(&call->tq, cp);
! #ifdef RXDEBUG_PACKET
                  call->tqc++;
! #endif /* RXDEBUG_PACKET */
                  cp = (struct rx_packet *)0;
  		if (!
  		    (call->
***************
*** 884,892 ****
       * ReadvProc/WritevProc.
       */
      if (queue_IsNotEmpty(&call->iovq)) {
! #ifdef DEBUG
          call->iovqc -=
! #endif /* DEBUG */
              rxi_FreePackets(0, &call->iovq);
      }
  
--- 886,894 ----
       * ReadvProc/WritevProc.
       */
      if (queue_IsNotEmpty(&call->iovq)) {
! #ifdef RXDEBUG_PACKET
          call->iovqc -=
! #endif /* RXDEBUG_PACKET */
              rxi_FreePackets(0, &call->iovq);
      }
  
***************
*** 934,942 ****
       * ReadvProc/WritevProc.
       */
      if (queue_IsNotEmpty(&call->iovq)) {
! #ifdef DEBUG
          call->iovqc -=
! #endif /* DEBUG */
              rxi_FreePackets(0, &call->iovq);
      }
  
--- 936,944 ----
       * ReadvProc/WritevProc.
       */
      if (queue_IsNotEmpty(&call->iovq)) {
! #ifdef RXDEBUG_PACKET
          call->iovqc -=
! #endif /* RXDEBUG_PACKET */
              rxi_FreePackets(0, &call->iovq);
      }
  
***************
*** 997,1005 ****
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
      if (queue_IsNotEmpty(&call->iovq)) {
! #ifdef DEBUG
          call->iovqc -=
! #endif /* DEBUG */
              rxi_FreePackets(0, &call->iovq);
      }
  
--- 999,1007 ----
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
      if (queue_IsNotEmpty(&call->iovq)) {
! #ifdef RXDEBUG_PACKET
          call->iovqc -=
! #endif /* RXDEBUG_PACKET */
              rxi_FreePackets(0, &call->iovq);
      }
  
***************
*** 1037,1045 ****
  	    }
  	    cp->flags |= RX_PKTFLAG_IOVQ;
  	    queue_Append(&call->iovq, cp);
! #ifdef DEBUG
              call->iovqc++;
! #endif /* DEBUG */
  	    tnFree = cp->length;
  	    tcurvec = 1;
  	    tcurpos =
--- 1039,1047 ----
  	    }
  	    cp->flags |= RX_PKTFLAG_IOVQ;
  	    queue_Append(&call->iovq, cp);
! #ifdef RXDEBUG_PACKET
              call->iovqc++;
! #endif /* RXDEBUG_PACKET */
  	    tnFree = cp->length;
  	    tcurvec = 1;
  	    tcurpos =
***************
*** 1116,1127 ****
  int
  rxi_WritevProc(struct rx_call *call, struct iovec *iov, int nio, int nbytes)
  {
!     struct rx_packet *cp = call->currentPacket;
      struct rx_call *p, *np;
      int nextio;
      int requestCount;
      struct rx_queue tmpq;
! #ifdef DEBUG
      u_short tmpqc;
  #endif
  
--- 1118,1129 ----
  int
  rxi_WritevProc(struct rx_call *call, struct iovec *iov, int nio, int nbytes)
  {
!     struct rx_packet *cp = NULL;
      struct rx_call *p, *np;
      int nextio;
      int requestCount;
      struct rx_queue tmpq;
! #ifdef RXDEBUG_PACKET
      u_short tmpqc;
  #endif
  
***************
*** 1143,1162 ****
  #endif /* RX_ENABLE_LOCKS */
      }
  #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
  
      if (call->error) {
  	if (cp) {
              cp->flags &= ~RX_PKTFLAG_CP;
              cp->flags |= RX_PKTFLAG_IOVQ;
  	    queue_Prepend(&call->iovq, cp);
! #ifdef DEBUG
              call->iovqc++;
! #endif /* DEBUG */
  	    cp = call->currentPacket = (struct rx_packet *)0;
  	}
! #ifdef DEBUG
          call->iovqc -=
! #endif /* DEBUG */
              rxi_FreePackets(0, &call->iovq);
  	return 0;
      }
--- 1145,1166 ----
  #endif /* RX_ENABLE_LOCKS */
      }
  #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
+     /* cp is no longer valid since we may have given up the lock */
+     cp = call->currentPacket;
  
      if (call->error) {
  	if (cp) {
              cp->flags &= ~RX_PKTFLAG_CP;
              cp->flags |= RX_PKTFLAG_IOVQ;
  	    queue_Prepend(&call->iovq, cp);
! #ifdef RXDEBUG_PACKET
              call->iovqc++;
! #endif /* RXDEBUG_PACKET */
  	    cp = call->currentPacket = (struct rx_packet *)0;
  	}
! #ifdef RXDEBUG_PACKET
          call->iovqc -=
! #endif /* RXDEBUG_PACKET */
              rxi_FreePackets(0, &call->iovq);
  	return 0;
      }
***************
*** 1168,1176 ****
       * a zero length write will push a short packet. */
      nextio = 0;
      queue_Init(&tmpq);
! #ifdef DEBUG
      tmpqc = 0;
! #endif /* DEBUG */
      do {
  	if (call->nFree == 0 && cp) {
  	    clock_NewTime();	/* Bogus:  need new time package */
--- 1172,1180 ----
       * a zero length write will push a short packet. */
      nextio = 0;
      queue_Init(&tmpq);
! #ifdef RXDEBUG_PACKET
      tmpqc = 0;
! #endif /* RXDEBUG_PACKET */
      do {
  	if (call->nFree == 0 && cp) {
  	    clock_NewTime();	/* Bogus:  need new time package */
***************
*** 1181,1207 ****
  	    hadd32(call->bytesSent, cp->length);
  	    rxi_PrepareSendPacket(call, cp, 0);
  	    queue_Append(&tmpq, cp);
! #ifdef DEBUG
              tmpqc++;
! #endif /* DEBUG */
              cp = call->currentPacket = (struct rx_packet *)0;
  
  	    /* The head of the iovq is now the current packet */
  	    if (nbytes) {
  		if (queue_IsEmpty(&call->iovq)) {
  		    call->error = RX_PROTOCOL_ERROR;
! #ifdef DEBUG
                      tmpqc -=
! #endif /* DEBUG */
                          rxi_FreePackets(0, &tmpq);
  		    return 0;
  		}
  		cp = queue_First(&call->iovq, rx_packet);
  		queue_Remove(cp);
                  cp->flags &= ~RX_PKTFLAG_IOVQ;
! #ifdef DEBUG
                  call->iovqc--;
! #endif /* DEBUG */
                  cp->flags |= RX_PKTFLAG_CP;
  		call->currentPacket = cp;
  		call->nFree = cp->length;
--- 1185,1211 ----
  	    hadd32(call->bytesSent, cp->length);
  	    rxi_PrepareSendPacket(call, cp, 0);
  	    queue_Append(&tmpq, cp);
! #ifdef RXDEBUG_PACKET
              tmpqc++;
! #endif /* RXDEBUG_PACKET */
              cp = call->currentPacket = (struct rx_packet *)0;
  
  	    /* The head of the iovq is now the current packet */
  	    if (nbytes) {
  		if (queue_IsEmpty(&call->iovq)) {
  		    call->error = RX_PROTOCOL_ERROR;
! #ifdef RXDEBUG_PACKET
                      tmpqc -=
! #endif /* RXDEBUG_PACKET */
                          rxi_FreePackets(0, &tmpq);
  		    return 0;
  		}
  		cp = queue_First(&call->iovq, rx_packet);
  		queue_Remove(cp);
                  cp->flags &= ~RX_PKTFLAG_IOVQ;
! #ifdef RXDEBUG_PACKET
                  call->iovqc--;
! #endif /* RXDEBUG_PACKET */
                  cp->flags |= RX_PKTFLAG_CP;
  		call->currentPacket = cp;
  		call->nFree = cp->length;
***************
*** 1222,1235 ****
  		if (cp) {
  		    cp->flags &= ~RX_PKTFLAG_CP;
                      queue_Prepend(&tmpq, cp);
! #ifdef DEBUG
                      tmpqc++;
! #endif /* DEBUG */
                      cp = call->currentPacket = (struct rx_packet *)0;
  		}
! #ifdef DEBUG
                  tmpqc -=
! #endif /* DEBUG */
                      rxi_FreePackets(0, &tmpq);
  		return 0;
  	    }
--- 1226,1239 ----
  		if (cp) {
  		    cp->flags &= ~RX_PKTFLAG_CP;
                      queue_Prepend(&tmpq, cp);
! #ifdef RXDEBUG_PACKET
                      tmpqc++;
! #endif /* RXDEBUG_PACKET */
                      cp = call->currentPacket = (struct rx_packet *)0;
  		}
! #ifdef RXDEBUG_PACKET
                  tmpqc -=
! #endif /* RXDEBUG_PACKET */
                      rxi_FreePackets(0, &tmpq);
  		return 0;
  	    }
***************
*** 1278,1283 ****
--- 1282,1289 ----
  #endif
  	call->startWait = 0;
      }
+     /* cp is no longer valid since we may have given up the lock */
+     cp = call->currentPacket;
  
      if (call->error) {
  	if (cp) {
***************
*** 1310,1322 ****
  void
  rxi_FlushWrite(register struct rx_call *call)
  {
!     register struct rx_packet *cp = call->currentPacket;
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
      if (queue_IsNotEmpty(&call->iovq)) {
! #ifdef DEBUG
          call->iovqc -=
! #endif /* DEBUG */
              rxi_FreePackets(0, &call->iovq);
      }
  
--- 1316,1328 ----
  void
  rxi_FlushWrite(register struct rx_call *call)
  {
!     register struct rx_packet *cp = NULL;
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
      if (queue_IsNotEmpty(&call->iovq)) {
! #ifdef RXDEBUG_PACKET
          call->iovqc -=
! #endif /* RXDEBUG_PACKET */
              rxi_FreePackets(0, &call->iovq);
      }
  
***************
*** 1353,1358 ****
--- 1359,1367 ----
  	}
  #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
  
+         /* cp is no longer valid since we may have given up the lock */
+         cp = call->currentPacket;
+ 
  	if (cp) {
  	    /* cp->length is only supposed to be the user's data */
  	    /* cp->length was already set to (then-current) 
***************
*** 1377,1385 ****
  	rxi_PrepareSendPacket(call, cp, 1);
  	cp->flags |= RX_PKTFLAG_TQ;
  	queue_Append(&call->tq, cp);
! #ifdef DEBUG
          call->tqc++;
! #endif /* DEBUG */
  	if (!
  	    (call->
  	     flags & (RX_CALL_FAST_RECOVER | RX_CALL_FAST_RECOVER_WAIT))) {
--- 1386,1394 ----
  	rxi_PrepareSendPacket(call, cp, 1);
  	cp->flags |= RX_PKTFLAG_TQ;
  	queue_Append(&call->tq, cp);
! #ifdef RXDEBUG_PACKET
          call->tqc++;
! #endif /* RXDEBUG_PACKET */
  	if (!
  	    (call->
  	     flags & (RX_CALL_FAST_RECOVER | RX_CALL_FAST_RECOVER_WAIT))) {
Index: openafs/src/rx/rx_trace.c
diff -c openafs/src/rx/rx_trace.c:1.11.14.3 openafs/src/rx/rx_trace.c:1.11.14.4
*** openafs/src/rx/rx_trace.c:1.11.14.3	Wed Sep 24 17:36:53 2008
--- openafs/src/rx/rx_trace.c	Tue Jan 13 11:26:16 2009
***************
*** 11,19 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_trace.c,v 1.11.14.3 2008/09/24 21:36:53 shadow Exp $");
  
! #ifdef RXDEBUG
  #include <string.h>
  #ifdef AFS_NT40_ENV
  #include <fcntl.h>
--- 11,28 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_trace.c,v 1.11.14.4 2009/01/13 16:26:16 jaltman Exp $");
  
! #ifndef RXDEBUG
! char rxi_tracename[80] = "\0Tracing not compiled in";
! #ifdef DUMPTRACE
! int
! main(int argc, char **argv)
! {
!     return 0;
! }
! #endif
! #else
  #include <string.h>
  #ifdef AFS_NT40_ENV
  #include <fcntl.h>
***************
*** 183,187 ****
  }
  
  #endif /* DUMPTRACE */
! 
! #endif
--- 192,195 ----
  }
  
  #endif /* DUMPTRACE */
! #endif /* RXDEBUG */
Index: openafs/src/rx/rx_user.c
diff -c openafs/src/rx/rx_user.c:1.24.4.8 openafs/src/rx/rx_user.c:1.24.4.11
*** openafs/src/rx/rx_user.c:1.24.4.8	Sat Nov 29 13:55:44 2008
--- openafs/src/rx/rx_user.c	Wed Jan 14 01:34:19 2009
***************
*** 13,19 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_user.c,v 1.24.4.8 2008/11/29 18:55:44 jaltman Exp $");
  
  # include <sys/types.h>
  # include <errno.h>
--- 13,19 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_user.c,v 1.24.4.11 2009/01/14 06:34:19 jaltman Exp $");
  
  # include <sys/types.h>
  # include <errno.h>
***************
*** 59,67 ****
   * Inited
   */
  
! pthread_mutex_t rx_if_init_mutex;
! #define LOCK_IF_INIT assert(pthread_mutex_lock(&rx_if_init_mutex)==0)
! #define UNLOCK_IF_INIT assert(pthread_mutex_unlock(&rx_if_init_mutex)==0)
  
  /*
   * The rx_if_mutex mutex protects the following global variables:
--- 59,67 ----
   * Inited
   */
  
! afs_kmutex_t rx_if_init_mutex;
! #define LOCK_IF_INIT MUTEX_ENTER(&rx_if_init_mutex)
! #define UNLOCK_IF_INIT MUTEX_EXIT(&rx_if_init_mutex)
  
  /*
   * The rx_if_mutex mutex protects the following global variables:
***************
*** 70,78 ****
   * myNetMasks
   */
  
! pthread_mutex_t rx_if_mutex;
! #define LOCK_IF assert(pthread_mutex_lock(&rx_if_mutex)==0)
! #define UNLOCK_IF assert(pthread_mutex_unlock(&rx_if_mutex)==0)
  #else
  #define LOCK_IF_INIT
  #define UNLOCK_IF_INIT
--- 70,78 ----
   * myNetMasks
   */
  
! afs_kmutex_t rx_if_mutex;
! #define LOCK_IF MUTEX_ENTER(&rx_if_mutex)
! #define UNLOCK_IF MUTEX_EXIT(&rx_if_mutex)
  #else
  #define LOCK_IF_INIT
  #define UNLOCK_IF_INIT
***************
*** 165,179 ****
  
  	len1 = 32766;
  	len2 = rx_UdpBufSize;
- 	greedy =
- 	    (setsockopt
- 	     (socketFd, SOL_SOCKET, SO_RCVBUF, (char *)&len2,
- 	      sizeof(len2)) >= 0);
- 	if (!greedy) {
- 	    len2 = 32766;	/* fall back to old size... uh-oh! */
- 	}
  
! 	greedy =
  	    (setsockopt
  	     (socketFd, SOL_SOCKET, SO_SNDBUF, (char *)&len1,
  	      sizeof(len1)) >= 0)
--- 165,190 ----
  
  	len1 = 32766;
  	len2 = rx_UdpBufSize;
  
!         /* find the size closest to rx_UdpBufSize that will be accepted */
!         while (!greedy && len2 > len1) {
!             greedy =
!                 (setsockopt
!                   (socketFd, SOL_SOCKET, SO_RCVBUF, (char *)&len2,
!                    sizeof(len2)) >= 0);
!             if (!greedy)
!                 len2 /= 2;
!         }
! 
!         /* but do not let it get smaller than 32K */ 
!         if (len2 < len1)
!             len2 = len1;
! 
!         if (len1 < len2)
!             len1 = len2;
! 
! 
!         greedy =
  	    (setsockopt
  	     (socketFd, SOL_SOCKET, SO_SNDBUF, (char *)&len1,
  	      sizeof(len1)) >= 0)
***************
*** 184,192 ****
  	if (!greedy)
  	    (osi_Msg "%s*WARNING* Unable to increase buffering on socket\n",
  	     name);
! 	MUTEX_ENTER(&rx_stats_mutex);
! 	rx_stats.socketGreedy = greedy;
! 	MUTEX_EXIT(&rx_stats_mutex);
      }
  #endif /* AFS_DJGPP_ENV */
  
--- 195,205 ----
  	if (!greedy)
  	    (osi_Msg "%s*WARNING* Unable to increase buffering on socket\n",
  	     name);
!         if (rx_stats_active) {
!             MUTEX_ENTER(&rx_stats_mutex);
!             rx_stats.socketGreedy = greedy;
!             MUTEX_EXIT(&rx_stats_mutex);
!         }
      }
  #endif /* AFS_DJGPP_ENV */
  
Index: openafs/src/rx/xdr.h
diff -c openafs/src/rx/xdr.h:1.14 openafs/src/rx/xdr.h:1.14.2.1
*** openafs/src/rx/xdr.h:1.14	Thu Mar  9 01:34:48 2006
--- openafs/src/rx/xdr.h	Thu Jan 22 16:29:08 2009
***************
*** 96,106 ****
--- 96,108 ----
  #define	osi_free		afs_osi_Free
  
  /* keep here for now, 64 bit issues */
+ #ifndef AFS_OBSD44_ENV
  extern void *afs_osi_Alloc(size_t x);
  #ifndef afs_osi_Alloc_NoSleep
  extern void *afs_osi_Alloc_NoSleep(size_t x);
  #endif
  extern void afs_osi_Free(void *x, size_t asize);
+ #endif
  
  #endif
  #ifndef major			/* ouch! */
Index: openafs/src/rx/xdr_arrayn.c
diff -c openafs/src/rx/xdr_arrayn.c:1.10 openafs/src/rx/xdr_arrayn.c:1.10.6.1
*** openafs/src/rx/xdr_arrayn.c:1.10	Sun Apr  3 14:09:30 2005
--- openafs/src/rx/xdr_arrayn.c	Thu Jan 22 16:29:08 2009
***************
*** 30,37 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/xdr_arrayn.c,v 1.10 2005/04/03 18:09:30 shadow Exp $");
  
  #if !defined(NeXT)
  
  /*
--- 30,42 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/xdr_arrayn.c,v 1.10.6.1 2009/01/22 21:29:08 shadow Exp $");
  
+ #if defined(AFS_OBSD44_ENV) && defined(KERNEL) && !defined(UKERNEL)
+ /* XXX osi_alloc, please find and fix */
+ #include "osi_machdep.h"
+ #endif
+  
  #if !defined(NeXT)
  
  /*
***************
*** 44,49 ****
--- 49,55 ----
   */
  
  #if defined(KERNEL) && !defined(UKERNEL)
+ 
  #include <sys/param.h>
  #ifdef AFS_LINUX20_ENV
  #include "h/string.h"
Index: openafs/src/rxdebug/Makefile.in
diff -c openafs/src/rxdebug/Makefile.in:1.5 openafs/src/rxdebug/Makefile.in:1.5.2.1
*** openafs/src/rxdebug/Makefile.in:1.5	Thu Mar  9 01:34:53 2006
--- openafs/src/rxdebug/Makefile.in	Tue Jan 13 11:33:35 2009
***************
*** 8,14 ****
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=${COMMON_CFLAGS} ${XCFLAGS} ${ARCHFLAGS} -DRXDEBUG
  
  LIBS=${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libcmd.a \
  	       ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/libafsutil.a
--- 8,14 ----
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=${COMMON_CFLAGS} ${XCFLAGS} ${ARCHFLAGS}
  
  LIBS=${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libcmd.a \
  	       ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/libafsutil.a
Index: openafs/src/sys/afssyscalls.c
diff -c openafs/src/sys/afssyscalls.c:1.13 openafs/src/sys/afssyscalls.c:1.13.2.1
*** openafs/src/sys/afssyscalls.c:1.13	Mon Feb 20 23:45:12 2006
--- openafs/src/sys/afssyscalls.c	Thu Jan 22 16:38:57 2009
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/sys/afssyscalls.c,v 1.13 2006/02/21 04:45:12 shadow Exp $");
  
  #include <signal.h>
  #include <sys/errno.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/sys/afssyscalls.c,v 1.13.2.1 2009/01/22 21:38:57 shadow Exp $");
  
  #include <signal.h>
  #include <sys/errno.h>
***************
*** 338,343 ****
--- 338,348 ----
  lpioctl(char *path, int cmd, char *cmarg, int follow)
  {
      int errcode, rval;
+ #if defined(AFS_FBSD_ENV)
+     /* As kauth/user.c says, handle smoothly the case where no AFS system call
+      *  exists (yet).  Why don't more platforms have trouble here?  Matt */
+     sig_t old = (int (*)())signal(SIGSYS, SIG_IGN);
+ #endif
  
  #if defined(AFS_LINUX20_ENV)
      rval = proc_afs_syscall(AFSCALL_PIOCTL, (long)path, cmd, (long)cmarg, 
Index: openafs/src/util/afsutil.h
diff -c openafs/src/util/afsutil.h:1.21.2.5 openafs/src/util/afsutil.h:1.21.2.6
*** openafs/src/util/afsutil.h:1.21.2.5	Sun Dec 21 01:00:41 2008
--- openafs/src/util/afsutil.h	Thu Jan 22 10:16:37 2009
***************
*** 115,126 ****
  
  /* Abort on error, possibly trapping to debugger or dumping a trace. */
       void afs_NTAbort(void);
! #endif /* NT40 */
  
       typedef char b32_string_t[8];
  /* b64_string_t is 8 bytes, in stds.h */
       typedef char lb64_string_t[12];
  
  #ifndef UKERNEL
  #include "afs/ktime.h"
  #endif
--- 115,134 ----
  
  /* Abort on error, possibly trapping to debugger or dumping a trace. */
       void afs_NTAbort(void);
! #endif /* AFS_NT40_ENV */
  
       typedef char b32_string_t[8];
  /* b64_string_t is 8 bytes, in stds.h */
       typedef char lb64_string_t[12];
  
+ #ifndef HAVE_STRLCAT
+ extern size_t strlcat(char *dst, const char *src, size_t siz);
+ #endif
+ 
+ #ifndef HAVE_STRLCPY
+ extern size_t strlcpy(char *dst, const char *src, size_t siz);
+ #endif
+ 
  #ifndef UKERNEL
  #include "afs/ktime.h"
  #endif
Index: openafs/src/util/volparse.c
diff -c openafs/src/util/volparse.c:1.11.14.3 openafs/src/util/volparse.c:1.11.14.4
*** openafs/src/util/volparse.c:1.11.14.3	Tue Jul  1 14:33:38 2008
--- openafs/src/util/volparse.c	Thu Jan 22 10:16:37 2009
***************
*** 9,23 ****
  
  #include <afsconfig.h>
  #include <afs/param.h>
- 
  RCSID
!     ("$Header: /cvs/openafs/src/util/volparse.c,v 1.11.14.3 2008/07/01 18:33:38 shadow Exp $");
  
  #include <string.h>
  #ifdef HAVE_STDLIB_H
  #include <stdlib.h>
  #endif
  
  /**
   * map a partition id from any partition-style name.
   *
--- 9,27 ----
  
  #include <afsconfig.h>
  #include <afs/param.h>
  RCSID
!     ("$Header: /cvs/openafs/src/util/volparse.c,v 1.11.14.4 2009/01/22 15:16:37 jaltman Exp $");
  
  #include <string.h>
  #ifdef HAVE_STDLIB_H
  #include <stdlib.h>
  #endif
  
+ #include "afsutil.h"
+ 
+ /* maximum number of partitions - must match vol/voldefs.h */
+ #define VOLMAXPARTS 255
+ 
  /**
   * map a partition id from any partition-style name.
   *
***************
*** 44,54 ****
      if (tc >= '0' && tc <= '9') {
  	temp = atoi(aname);
  	/* this next check is to make the syntax less ambiguous when discriminating
! 	 * between volume numbers and partition IDs.  This less things like
! 	 * bos salvage do some reasonability checks its input w/o checking
  	 * to see if the partition is really on the server.
  	 */
! 	if (temp < 0 || temp > 25)
  	    return -1;
  	else
  	    return temp;
--- 48,58 ----
      if (tc >= '0' && tc <= '9') {
  	temp = atoi(aname);
  	/* this next check is to make the syntax less ambiguous when discriminating
! 	 * between volume numbers and partition IDs.  This lets things like
! 	 * bos salvage do some reasonability checks on its input w/o checking
  	 * to see if the partition is really on the server.
  	 */
! 	if (temp < 0 || temp >= VOLMAXPARTS)
  	    return -1;
  	else
  	    return temp;
***************
*** 76,82 ****
  	    return -1;		/* wrongo */
  	if (ascii[1] < 'a' || ascii[1] > 'z')
  	    return -1;		/* just as bad */
! 	return (ascii[0] - 'a') * 26 + (ascii[1] - 'a') + 26;
      }
  }
  
--- 80,87 ----
  	    return -1;		/* wrongo */
  	if (ascii[1] < 'a' || ascii[1] > 'z')
  	    return -1;		/* just as bad */
! 	temp = (ascii[0] - 'a') * 26 + (ascii[1] - 'a') + 26;
!         return (temp >= VOLMAXPARTS ? -1 : temp);
      }
  }
  
***************
*** 102,108 ****
      char tempString[3];
      register int i;
  
!     if (part < 0 || part >= (26 * 26 + 26)) {
  	return -2;
      }
  
--- 107,113 ----
      char tempString[3];
      register int i;
  
!     if (part < 0 || part >= VOLMAXPARTS) {
  	return -2;
      }
  
***************
*** 229,235 ****
      negative = 0;
  
      /* skip over leading spaces */
!     while ((tc = *as)) {
  	if (tc != ' ' && tc != '\t')
  	    break;
      }
--- 234,240 ----
      negative = 0;
  
      /* skip over leading spaces */
!     for (; tc = *as; as++) {
  	if (tc != ' ' && tc != '\t')
  	    break;
      }
***************
*** 252,263 ****
  	base = 10;
  
      /* compute the # itself */
!     while ((tc = *as)) {
  	if (!ismeta(tc, base))
  	    return -1;
  	total *= base;
  	total += getmeta(tc);
- 	as++;
      }
  
      if (negative)
--- 257,267 ----
  	base = 10;
  
      /* compute the # itself */
!     for (; tc = *as; as++) {
  	if (!ismeta(tc, base))
  	    return -1;
  	total *= base;
  	total += getmeta(tc);
      }
  
      if (negative)
***************
*** 277,283 ****
      total = 0;			/* initialize things */
  
      /* skip over leading spaces */
!     while ((tc = *as)) {
  	if (tc != ' ' && tc != '\t')
  	    break;
      }
--- 281,287 ----
      total = 0;			/* initialize things */
  
      /* skip over leading spaces */
!     for (; tc = *as; as++) {
  	if (tc != ' ' && tc != '\t')
  	    break;
      }
***************
*** 294,305 ****
  	base = 10;
  
      /* compute the # itself */
!     while ((tc = *as)) {
  	if (!ismeta(tc, base))
  	    return -1;
  	total *= base;
  	total += getmeta(tc);
- 	as++;
      }
  
      *aval = total;
--- 298,308 ----
  	base = 10;
  
      /* compute the # itself */
!     for (;tc = *as; as++) {
  	if (!ismeta(tc, base))
  	    return -1;
  	total *= base;
  	total += getmeta(tc);
      }
  
      *aval = total;
Index: openafs/src/venus/cacheout.c
diff -c openafs/src/venus/cacheout.c:1.8.14.1 openafs/src/venus/cacheout.c:1.8.14.2
*** openafs/src/venus/cacheout.c:1.8.14.1	Wed Oct 31 00:09:39 2007
--- openafs/src/venus/cacheout.c	Thu Jan 22 10:29:10 2009
***************
*** 13,19 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/venus/cacheout.c,v 1.8.14.1 2007/10/31 04:09:39 shadow Exp $");
  
  #include <stdio.h>
  #include <string.h>
--- 13,19 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/venus/cacheout.c,v 1.8.14.2 2009/01/22 15:29:10 jaltman Exp $");
  
  #include <stdio.h>
  #include <string.h>
***************
*** 173,179 ****
      memset(&addrs, 0, sizeof(addrs));
      memset(&spare3, 0, sizeof(spare3));
      code =
! 	ubik_Call(VL_GetAddrs, client, 0, Handle, spare2, &spare3,
  		  &server_count, &addrs);
      if (code) {
  	printf("Fatal error: could not get list of file servers\n");
--- 173,179 ----
      memset(&addrs, 0, sizeof(addrs));
      memset(&spare3, 0, sizeof(spare3));
      code =
! 	ubik_VL_GetAddrs(client, 0, Handle, spare2, &spare3,
  		  &server_count, &addrs);
      if (code) {
  	printf("Fatal error: could not get list of file servers\n");
***************
*** 190,196 ****
  		m_addrs.bulkaddrs_val = 0;
  		m_addrs.bulkaddrs_len = 0;
  		code =
! 		    ubik_Call(VL_GetAddrsU, client, 0, &m_attrs, &m_uuid,
  			      &m_unique, &m_nentries, &m_addrs);
  		if (vcode)
  		    return code;
--- 190,196 ----
  		m_addrs.bulkaddrs_val = 0;
  		m_addrs.bulkaddrs_len = 0;
  		code =
! 		    ubik_VL_GetAddrsU(client, 0, &m_attrs, &m_uuid,
  			      &m_unique, &m_nentries, &m_addrs);
  		if (vcode)
  		    return code;
Index: openafs/src/venus/kdump.c
diff -c openafs/src/venus/kdump.c:1.38.4.4 openafs/src/venus/kdump.c:1.38.4.5
*** openafs/src/venus/kdump.c:1.38.4.4	Fri Oct  3 16:39:56 2008
--- openafs/src/venus/kdump.c	Wed Jan 21 15:07:49 2009
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/venus/kdump.c,v 1.38.4.4 2008/10/03 20:39:56 shadow Exp $");
  
  #include <stdio.h>
  #include <errno.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/venus/kdump.c,v 1.38.4.5 2009/01/21 20:07:49 shadow Exp $");
  
  #include <stdio.h>
  #include <errno.h>
***************
*** 2005,2014 ****
      T += j;
      printf("%20s:\t%8d bytes\t[%d servers/%d bytes each]\n", "Server package",
  	   j, i, sizeof(struct server));
!     j = (Nconns * sizeof(struct conn));
      T += j;
      printf("%20s:\t%8d bytes\t[%d conns/%d bytes each]\n",
! 	   "Connection package", j, Nconns, sizeof(struct conn));
  
      i = (AFS_NCBRS * sizeof(struct afs_cbr)) * (j =
  						afs_cmperfstats.
--- 2005,2014 ----
      T += j;
      printf("%20s:\t%8d bytes\t[%d servers/%d bytes each]\n", "Server package",
  	   j, i, sizeof(struct server));
!     j = (Nconns * sizeof(struct afs_conn));
      T += j;
      printf("%20s:\t%8d bytes\t[%d conns/%d bytes each]\n",
! 	   "Connection package", j, Nconns, sizeof(struct afs_conn));
  
      i = (AFS_NCBRS * sizeof(struct afs_cbr)) * (j =
  						afs_cmperfstats.
***************
*** 2669,2680 ****
  print_conns(kmem, srv, conns, Con, pnt)
       int kmem, Con, pnt;
       struct srvAddr *srv;
!      struct conn *conns;
  {
!     struct conn *cep, ce, *centry = &ce;
      int i = 1;
  
!     cep = (struct conn *)conns;
      if (pnt && Con != 2) {
  	if (cep)
  	    printf("\tRPC connections for server %lx:\n", srv);
--- 2669,2680 ----
  print_conns(kmem, srv, conns, Con, pnt)
       int kmem, Con, pnt;
       struct srvAddr *srv;
!      struct afs_conn *conns;
  {
!     struct afs_conn *cep, ce, *centry = &ce;
      int i = 1;
  
!     cep = (struct afs_conn *)conns;
      if (pnt && Con != 2) {
  	if (cep)
  	    printf("\tRPC connections for server %lx:\n", srv);
***************
*** 2693,2699 ****
  void
  print_conn(kmem, conns, ptr, pnt)
       int kmem, pnt;
!      struct conn *conns, *ptr;
  {
      if (!pnt)
  	return;
--- 2693,2699 ----
  void
  print_conn(kmem, conns, ptr, pnt)
       int kmem, pnt;
!      struct afs_conn *conns, *ptr;
  {
      if (!pnt)
  	return;
Index: openafs/src/viced/Makefile.in
diff -c openafs/src/viced/Makefile.in:1.14 openafs/src/viced/Makefile.in:1.14.2.1
*** openafs/src/viced/Makefile.in:1.14	Fri Mar 17 14:54:47 2006
--- openafs/src/viced/Makefile.in	Tue Jan 13 11:33:35 2009
***************
*** 14,20 ****
  
  CFLAGS=${DBG} ${OPTMZ} -I${TOP_OBJDIR}/src/config -I. -I${TOP_INCDIR} \
  	-I${TOP_INCDIR}/afs -I${TOP_OBJDIR} -I${TOP_OBJDIR}/fsint\
! 	 ${XCFLAGS} ${ARCHFLAGS} -DRXDEBUG -DNINTERFACE
  
  LDFLAGS = ${DBUG} ${XLDFLAGS} ${ARCHFLAGS}
  
--- 14,20 ----
  
  CFLAGS=${DBG} ${OPTMZ} -I${TOP_OBJDIR}/src/config -I. -I${TOP_INCDIR} \
  	-I${TOP_INCDIR}/afs -I${TOP_OBJDIR} -I${TOP_OBJDIR}/fsint\
! 	 ${XCFLAGS} ${ARCHFLAGS} -DNINTERFACE
  
  LDFLAGS = ${DBUG} ${XLDFLAGS} ${ARCHFLAGS}
  
Index: openafs/src/viced/afsfileprocs.c
diff -c openafs/src/viced/afsfileprocs.c:1.113.2.29 openafs/src/viced/afsfileprocs.c:1.113.2.31
*** openafs/src/viced/afsfileprocs.c:1.113.2.29	Mon Oct 27 19:41:47 2008
--- openafs/src/viced/afsfileprocs.c	Mon Jan 19 22:32:38 2009
***************
*** 29,35 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/afsfileprocs.c,v 1.113.2.29 2008/10/27 23:41:47 shadow 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.31 2009/01/20 03:32:38 jaltman Exp $");
  
  #include <stdio.h>
  #include <stdlib.h>
Index: openafs/src/vlserver/vlclient.c
diff -c openafs/src/vlserver/vlclient.c:1.16.2.3 openafs/src/vlserver/vlclient.c:1.16.2.4
*** openafs/src/vlserver/vlclient.c:1.16.2.3	Wed Oct 31 00:09:43 2007
--- openafs/src/vlserver/vlclient.c	Thu Jan 22 10:29:10 2009
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/vlserver/vlclient.c,v 1.16.2.3 2007/10/31 04:09:43 shadow Exp $");
  
  #include <afs/stds.h>
  #include <sys/types.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/vlserver/vlclient.c,v 1.16.2.4 2009/01/22 15:29:10 jaltman Exp $");
  
  #include <afs/stds.h>
  #include <sys/types.h>
***************
*** 226,232 ****
      if (as->parms[5].items) {	/* -gstats */
  	vldstats stats;
  	vital_vlheader vital_header;
! 	code = ubik_Call(VL_GetStats, cstruct, 0, &stats, &vital_header);
  	if (!code)
  	    dump_stats(&stats, &vital_header);
  	exit(0);
--- 226,232 ----
      if (as->parms[5].items) {	/* -gstats */
  	vldstats stats;
  	vital_vlheader vital_header;
! 	code = ubik_VL_GetStats(cstruct, 0, &stats, &vital_header);
  	if (!code)
  	    dump_stats(&stats, &vital_header);
  	exit(0);
***************
*** 251,263 ****
  	    if (!strcmp(oper, "cr")) {
  		fill_entry(&entry, argp, nargs);
  		display_entry(&entry, 0);
! 		code = ubik_Call(VL_CreateEntry, cstruct, 0, &entry);
  		printf("return code is %d\n", code);
  	    } else if (!strcmp(oper, "rm")) {
  		sscanf(&(*argp)[0], "%d", &id);
  		++argp, --nargs;
  		sscanf(&(*argp)[0], "%d", &voltype);
! 		code = ubik_Call(VL_DeleteEntry, cstruct, 0, id, voltype);
  		printf("return code is %d\n", code);
  	    } else if (!strcmp(oper, "re")) {
  		sscanf(&(*argp)[0], "%d", &id);
--- 251,263 ----
  	    if (!strcmp(oper, "cr")) {
  		fill_entry(&entry, argp, nargs);
  		display_entry(&entry, 0);
! 		code = ubik_VL_CreateEntry(cstruct, 0, &entry);
  		printf("return code is %d\n", code);
  	    } else if (!strcmp(oper, "rm")) {
  		sscanf(&(*argp)[0], "%d", &id);
  		++argp, --nargs;
  		sscanf(&(*argp)[0], "%d", &voltype);
! 		code = ubik_VL_DeleteEntry(cstruct, 0, id, voltype);
  		printf("return code is %d\n", code);
  	    } else if (!strcmp(oper, "re")) {
  		sscanf(&(*argp)[0], "%d", &id);
***************
*** 269,275 ****
  		fill_entry(&entry, argp, nargs);
  		display_entry(&entry, 0);
  		code =
! 		    ubik_Call(VL_ReplaceEntry, cstruct, 0, id, voltype,
  			      &entry, releasetype);
  		printf("return code is %d\n", code);
  	    } else if (!strcmp(oper, "up")) {
--- 269,276 ----
  		fill_entry(&entry, argp, nargs);
  		display_entry(&entry, 0);
  		code =
! 		    ubik_VL_ReplaceEntry(
!                     cstruct, 0, id, voltype,
  			      &entry, releasetype);
  		printf("return code is %d\n", code);
  	    } else if (!strcmp(oper, "up")) {
***************
*** 282,288 ****
  		fill_update_entry(&updateentry, argp, nargs);
  		display_update_entry(&updateentry, 0);
  		code =
! 		    ubik_Call(VL_UpdateEntry, cstruct, 0, id, voltype,
  			      &updateentry, releasetype);
  		printf("return code is %d\n", code);
  	    } else if (!strcmp(oper, "ls")) {
--- 283,289 ----
  		fill_update_entry(&updateentry, argp, nargs);
  		display_update_entry(&updateentry, 0);
  		code =
! 		    ubik_VL_UpdateEntry(cstruct, 0, id, voltype,
  			      &updateentry, releasetype);
  		printf("return code is %d\n", code);
  	    } else if (!strcmp(oper, "ls")) {
***************
*** 290,296 ****
  		for (index = 0; 1; index = next_index) {
  		    memset(&entry, 0, sizeof(entry));
  		    code =
! 			ubik_Call(VL_ListEntry, cstruct, 0, index, &count,
  				  &next_index, &entry);
  		    if (code) {
  			printf("VL_ListEntry returned code = %d\n", code);
--- 291,297 ----
  		for (index = 0; 1; index = next_index) {
  		    memset(&entry, 0, sizeof(entry));
  		    code =
! 			ubik_VL_ListEntry(cstruct, 0, index, &count,
  				  &next_index, &entry);
  		    if (code) {
  			printf("VL_ListEntry returned code = %d\n", code);
***************
*** 314,320 ****
  		for (index = 0; 1; index = next_index) {
  		    memset(&entry, 0, sizeof(entry));
  		    code =
! 			ubik_Call(VL_ListEntry, cstruct, 0, index, &count,
  				  &next_index, &entry);
  		    if (code) {
  			printf("VL_ListEntry returned code = %d\n", code);
--- 315,321 ----
  		for (index = 0; 1; index = next_index) {
  		    memset(&entry, 0, sizeof(entry));
  		    code =
! 			ubik_VL_ListEntry(cstruct, 0, index, &count,
  				  &next_index, &entry);
  		    if (code) {
  			printf("VL_ListEntry returned code = %d\n", code);
***************
*** 363,369 ****
  		for (index = 0; 1; index = next_index) {
  		    memset(&entry, 0, sizeof(entry));
  		    code =
! 			ubik_Call(VL_ListEntry, cstruct, 0, index, &count,
  				  &next_index, &entry);
  		    if (code) {
  			printf("VL_ListEntry returned code = %d\n", code);
--- 364,370 ----
  		for (index = 0; 1; index = next_index) {
  		    memset(&entry, 0, sizeof(entry));
  		    code =
! 			ubik_VL_ListEntry(cstruct, 0, index, &count,
  				  &next_index, &entry);
  		    if (code) {
  			printf("VL_ListEntry returned code = %d\n", code);
***************
*** 373,379 ****
  			break;
  		    num++;
  		    code =
! 			ubik_Call(VL_GetEntryByNameO, cstruct, 0, entry.name,
  				  &tentry);
  		    if (code == VL_NOENT) {
  			num1++;
--- 374,380 ----
  			break;
  		    num++;
  		    code =
! 			ubik_VL_GetEntryByNameO(cstruct, 0, entry.name,
  				  &tentry);
  		    if (code == VL_NOENT) {
  			num1++;
***************
*** 381,387 ****
  			       entry.name, entry.volumeId[RWVOL]);
  		    }
  		    code =
! 			ubik_Call(VL_GetEntryByID, cstruct, 0,
  				  entry.volumeId[RWVOL], RWVOL, &tentry);
  		    if (code == VL_NOENT) {
  			num2++;
--- 382,388 ----
  			       entry.name, entry.volumeId[RWVOL]);
  		    }
  		    code =
! 			ubik_VL_GetEntryByID(cstruct, 0,
  				  entry.volumeId[RWVOL], RWVOL, &tentry);
  		    if (code == VL_NOENT) {
  			num2++;
***************
*** 390,396 ****
  		    }
  		    if (entry.volumeId[BACKVOL]) {
  			code =
! 			    ubik_Call(VL_GetEntryByID, cstruct, 0,
  				      entry.volumeId[BACKVOL], BACKVOL,
  				      &tentry);
  			num31++;
--- 391,397 ----
  		    }
  		    if (entry.volumeId[BACKVOL]) {
  			code =
! 			    ubik_VL_GetEntryByID(cstruct, 0,
  				      entry.volumeId[BACKVOL], BACKVOL,
  				      &tentry);
  			num31++;
***************
*** 402,408 ****
  		    }
  		    if (entry.volumeId[ROVOL]) {
  			code =
! 			    ubik_Call(VL_GetEntryByID, cstruct, 0,
  				      entry.volumeId[ROVOL], ROVOL, &tentry);
  			num41++;
  			if (code == VL_NOENT) {
--- 403,409 ----
  		    }
  		    if (entry.volumeId[ROVOL]) {
  			code =
! 			    ubik_VL_GetEntryByID(cstruct, 0,
  				      entry.volumeId[ROVOL], ROVOL, &tentry);
  			num41++;
  			if (code == VL_NOENT) {
***************
*** 440,446 ****
  		    int n1 = 0, n2 = 0, n3 = 0, n4 = 0;
  		    memset(&entry, 0, sizeof(entry));
  		    code =
! 			ubik_Call(VL_ListEntry, cstruct, 0, index, &count,
  				  &next_index, &entry);
  		    if (code) {
  			printf("VL_ListEntry returned code = %d\n", code);
--- 441,447 ----
  		    int n1 = 0, n2 = 0, n3 = 0, n4 = 0;
  		    memset(&entry, 0, sizeof(entry));
  		    code =
! 			ubik_VL_ListEntry(cstruct, 0, index, &count,
  				  &next_index, &entry);
  		    if (code) {
  			printf("VL_ListEntry returned code = %d\n", code);
***************
*** 450,456 ****
  			break;
  		    num++;
  		    code =
! 			ubik_Call(VL_GetEntryByNameO, cstruct, 0, entry.name,
  				  &tentry);
  		    if (code == VL_NOENT) {
  			num1++;
--- 451,457 ----
  			break;
  		    num++;
  		    code =
! 			ubik_VL_GetEntryByNameO(cstruct, 0, entry.name,
  				  &tentry);
  		    if (code == VL_NOENT) {
  			num1++;
***************
*** 459,465 ****
  			printf("\tVolume %s %d (not in namehash)\n",
  			       entry.name, entry.volumeId[RWVOL]);
  			code =
! 			    ubik_Call(VL_UpdateEntry, cstruct, 0,
  				      entry.volumeId[RWVOL], -1, &updateentry,
  				      0);
  			if (code) {
--- 460,466 ----
  			printf("\tVolume %s %d (not in namehash)\n",
  			       entry.name, entry.volumeId[RWVOL]);
  			code =
! 			    ubik_VL_UpdateEntry(cstruct, 0,
  				      entry.volumeId[RWVOL], -1, &updateentry,
  				      0);
  			if (code) {
***************
*** 469,475 ****
  			}
  		    }
  		    code =
! 			ubik_Call(VL_GetEntryByID, cstruct, 0,
  				  entry.volumeId[RWVOL], RWVOL, &tentry);
  		    if (code == VL_NOENT) {
  			num1++;
--- 470,476 ----
  			}
  		    }
  		    code =
! 			ubik_VL_GetEntryByID(cstruct, 0,
  				  entry.volumeId[RWVOL], RWVOL, &tentry);
  		    if (code == VL_NOENT) {
  			num1++;
***************
*** 479,485 ****
  			printf("\tVolume %s %d (not in rw id hash)\n",
  			       entry.name, entry.volumeId[RWVOL]);
  			code =
! 			    ubik_Call(VL_UpdateEntryByName, cstruct, 0,
  				      entry.name, &updateentry, 0);
  			if (code) {
  			    printf("\tFailed to update volume %s (err=%d)\n",
--- 480,486 ----
  			printf("\tVolume %s %d (not in rw id hash)\n",
  			       entry.name, entry.volumeId[RWVOL]);
  			code =
! 			    ubik_VL_UpdateEntryByName(cstruct, 0,
  				      entry.name, &updateentry, 0);
  			if (code) {
  			    printf("\tFailed to update volume %s (err=%d)\n",
***************
*** 490,496 ****
  		    }
  		    if (entry.volumeId[BACKVOL] && !n2) {
  			code =
! 			    ubik_Call(VL_GetEntryByID, cstruct, 0,
  				      entry.volumeId[BACKVOL], BACKVOL,
  				      &tentry);
  			if (code == VL_NOENT) {
--- 491,497 ----
  		    }
  		    if (entry.volumeId[BACKVOL] && !n2) {
  			code =
! 			    ubik_VL_GetEntryByID(cstruct, 0,
  				      entry.volumeId[BACKVOL], BACKVOL,
  				      &tentry);
  			if (code == VL_NOENT) {
***************
*** 501,507 ****
  			    printf("\tVolume %s %d (not in backup id hash)\n",
  				   entry.name, entry.volumeId[BACKVOL]);
  			    code =
! 				ubik_Call(VL_UpdateEntry, cstruct, 0,
  					  entry.volumeId[RWVOL], -1,
  					  &updateentry, 0);
  			    if (code) {
--- 502,508 ----
  			    printf("\tVolume %s %d (not in backup id hash)\n",
  				   entry.name, entry.volumeId[BACKVOL]);
  			    code =
! 				ubik_VL_UpdateEntry(cstruct, 0,
  					  entry.volumeId[RWVOL], -1,
  					  &updateentry, 0);
  			    if (code) {
***************
*** 514,520 ****
  		    }
  		    if (entry.volumeId[ROVOL && !n2]) {
  			code =
! 			    ubik_Call(VL_GetEntryByID, cstruct, 0,
  				      entry.volumeId[ROVOL], ROVOL, &tentry);
  			if (code == VL_NOENT) {
  			    n4 = 1;
--- 515,521 ----
  		    }
  		    if (entry.volumeId[ROVOL && !n2]) {
  			code =
! 			    ubik_VL_GetEntryByID(cstruct, 0,
  				      entry.volumeId[ROVOL], ROVOL, &tentry);
  			if (code == VL_NOENT) {
  			    n4 = 1;
***************
*** 524,530 ****
  			    printf("\tVolume %s %d (not in RO id hash)\n",
  				   entry.name, entry.volumeId[ROVOL]);
  			    code =
! 				ubik_Call(VL_UpdateEntry, cstruct, 0,
  					  entry.volumeId[RWVOL], -1,
  					  &updateentry, 0);
  			    if (code) {
--- 525,531 ----
  			    printf("\tVolume %s %d (not in RO id hash)\n",
  				   entry.name, entry.volumeId[ROVOL]);
  			    code =
! 				ubik_VL_UpdateEntry(cstruct, 0,
  					  entry.volumeId[RWVOL], -1,
  					  &updateentry, 0);
  			    if (code) {
***************
*** 548,554 ****
  		fill_listattributes_entry(&listbyattributes, argp, nargs);
  		display_listattributes_entry(&listbyattributes, 0);
  		code =
! 		    ubik_Call(VL_ListAttributes, cstruct, 0,
  			      &listbyattributes, &nentries, &entries);
  		if (code) {
  		    printf("VL_ListAttributes returned code = %d\n", code);
--- 549,555 ----
  		fill_listattributes_entry(&listbyattributes, argp, nargs);
  		display_listattributes_entry(&listbyattributes, 0);
  		code =
! 		    ubik_VL_ListAttributes(cstruct, 0,
  			      &listbyattributes, &nentries, &entries);
  		if (code) {
  		    printf("VL_ListAttributes returned code = %d\n", code);
***************
*** 581,587 ****
  		    nentries = 0;
  		    memset(&entries, 0, sizeof(entries));
  		    code =
! 			ubik_Call(VL_ListAttributesN2, cstruct, 0,
  				  &listbyattributes, name, si, &nentries,
  				  &entries, &nsi);
  		    if (code) {
--- 582,588 ----
  		    nentries = 0;
  		    memset(&entries, 0, sizeof(entries));
  		    code =
! 			ubik_VL_ListAttributesN2(cstruct, 0,
  				  &listbyattributes, name, si, &nentries,
  				  &entries, &nsi);
  		    if (code) {
***************
*** 607,613 ****
  		display_listattributes_entry(&listbyattributes, 0);
  		memset(&linkedvldbs, 0, sizeof(vldb_list));
  		code =
! 		    ubik_Call(VL_LinkedList, cstruct, 0, &listbyattributes,
  			      &netries, &linkedvldbs);
  		if (code) {
  		    printf("VL_LinkedList returned code = %d\n", code);
--- 608,614 ----
  		display_listattributes_entry(&listbyattributes, 0);
  		memset(&linkedvldbs, 0, sizeof(vldb_list));
  		code =
! 		    ubik_VL_LinkedList(cstruct, 0, &listbyattributes,
  			      &netries, &linkedvldbs);
  		if (code) {
  		    printf("VL_LinkedList returned code = %d\n", code);
***************
*** 629,635 ****
  		display_listattributes_entry(&listbyattributes, 0);
  		memset(&linkedvldbs, 0, sizeof(vldb_list));
  		code =
! 		    ubik_Call(VL_LinkedListN, cstruct, 0, &listbyattributes,
  			      &netries, &linkedvldbs);
  		if (code) {
  		    printf("VL_LinkedList returned code = %d\n", code);
--- 630,636 ----
  		display_listattributes_entry(&listbyattributes, 0);
  		memset(&linkedvldbs, 0, sizeof(vldb_list));
  		code =
! 		    ubik_VL_LinkedListN(cstruct, 0, &listbyattributes,
  			      &netries, &linkedvldbs);
  		if (code) {
  		    printf("VL_LinkedList returned code = %d\n", code);
***************
*** 647,653 ****
  		++argp, --nargs;
  		sscanf(&(*argp)[0], "%d", &voltype);
  		code =
! 		    ubik_Call(VL_GetEntryByID, cstruct, 0, id, voltype,
  			      &entry);
  		display_entry(&entry, code);
  		printf("return code is %d.\n", code);
--- 648,654 ----
  		++argp, --nargs;
  		sscanf(&(*argp)[0], "%d", &voltype);
  		code =
! 		    ubik_VL_GetEntryByID(cstruct, 0, id, voltype,
  			      &entry);
  		display_entry(&entry, code);
  		printf("return code is %d.\n", code);
***************
*** 656,662 ****
  		++argp, --nargs;
  		sscanf(&(*argp)[0], "%d", &voltype);
  		code =
! 		    ubik_Call(VL_GetEntryByID, cstruct, 0, id, voltype,
  			      &entry);
  		display_entry(&entry, code);
  		memset(&updateentry, 0, sizeof(updateentry));
--- 657,663 ----
  		++argp, --nargs;
  		sscanf(&(*argp)[0], "%d", &voltype);
  		code =
! 		    ubik_VL_GetEntryByID(cstruct, 0, id, voltype,
  			      &entry);
  		display_entry(&entry, code);
  		memset(&updateentry, 0, sizeof(updateentry));
***************
*** 664,670 ****
  		printf("\tRehashing namehash table for %s (%d)\n", entry.name,
  		       entry.volumeId[RWVOL]);
  		code =
! 		    ubik_Call(VL_UpdateEntry, cstruct, 0,
  			      entry.volumeId[RWVOL], -1, &updateentry, 0);
  		if (code) {
  		    printf("\tFailed to update volume %s (err=%d)\n",
--- 665,671 ----
  		printf("\tRehashing namehash table for %s (%d)\n", entry.name,
  		       entry.volumeId[RWVOL]);
  		code =
! 		    ubik_VL_UpdateEntry(cstruct, 0,
  			      entry.volumeId[RWVOL], -1, &updateentry, 0);
  		if (code) {
  		    printf("\tFailed to update volume %s (err=%d)\n",
***************
*** 686,692 ****
  		for (index = 0; 1; index = next_index) {
  		    memset(&entry, 0, sizeof(entry));
  		    code =
! 			ubik_Call(VL_ListEntry, cstruct, 0, index, &count,
  				  &next_index, &entry);
  		    if (code) {
  			printf("VL_ListEntry returned code = %d\n", code);
--- 687,693 ----
  		for (index = 0; 1; index = next_index) {
  		    memset(&entry, 0, sizeof(entry));
  		    code =
! 			ubik_VL_ListEntry(cstruct, 0, index, &count,
  				  &next_index, &entry);
  		    if (code) {
  			printf("VL_ListEntry returned code = %d\n", code);
***************
*** 707,713 ****
  				("\tUndeleting vldb entry for vol %d (%s)\n",
  				 id, entry.name);
  			    code =
! 				ubik_Call(VL_UpdateEntry, cstruct, 0, id, -1,
  					  &updateentry, 0);
  			    if (code) {
  				printf
--- 708,714 ----
  				("\tUndeleting vldb entry for vol %d (%s)\n",
  				 id, entry.name);
  			    code =
! 				ubik_VL_UpdateEntry(cstruct, 0, id, -1,
  					  &updateentry, 0);
  			    if (code) {
  				printf
***************
*** 723,736 ****
  	    } else if (!strcmp(oper, "dn")) {
  		vname = &argp[0][0];
  		code =
! 		    ubik_Call(VL_GetEntryByNameO, cstruct, 0, vname, &entry);
  		display_entry(&entry, code);
  		printf("return code is %d.\n", code);
  	    } else if (!strcmp(oper, "nv")) {
  		int newvolid;
  		sscanf(&(*argp)[0], "%d", &id);
  		code =
! 		    ubik_Call(VL_GetNewVolumeId, cstruct, 0, id, &newvolid);
  		if (!code)
  		    printf("Current Max volid is (in hex):%X\n", newvolid);
  		printf("return code is %d\n", code);
--- 724,737 ----
  	    } else if (!strcmp(oper, "dn")) {
  		vname = &argp[0][0];
  		code =
! 		    ubik_VL_GetEntryByNameO(cstruct, 0, vname, &entry);
  		display_entry(&entry, code);
  		printf("return code is %d.\n", code);
  	    } else if (!strcmp(oper, "nv")) {
  		int newvolid;
  		sscanf(&(*argp)[0], "%d", &id);
  		code =
! 		    ubik_VL_GetNewVolumeId(cstruct, 0, id, &newvolid);
  		if (!code)
  		    printf("Current Max volid is (in hex):%X\n", newvolid);
  		printf("return code is %d\n", code);
***************
*** 738,744 ****
  		vldstats stats;
  		vital_vlheader vital_header;
  		code =
! 		    ubik_Call(VL_GetStats, cstruct, 0, &stats, &vital_header);
  		if (!code)
  		    dump_stats(&stats, &vital_header);
  		printf("return code is %d.\n", code);
--- 739,745 ----
  		vldstats stats;
  		vital_vlheader vital_header;
  		code =
! 		    ubik_VL_GetStats(cstruct, 0, &stats, &vital_header);
  		if (!code)
  		    dump_stats(&stats, &vital_header);
  		printf("return code is %d.\n", code);
***************
*** 750,756 ****
  
  		addrs.bulkaddrs_val = 0;
  		addrs.bulkaddrs_len = 0;
! 		code = ubik_Call(VL_GetAddrs, cstruct, 0, 0 /*Handle */ ,
  				 0 /*spare2 */ , &vlcb,
  				 &nentries, &addrs);
  		if (code) {
--- 751,757 ----
  
  		addrs.bulkaddrs_val = 0;
  		addrs.bulkaddrs_len = 0;
! 		code = ubik_VL_GetAddrs(cstruct, 0, 0 /*Handle */ ,
  				 0 /*spare2 */ , &vlcb,
  				 &nentries, &addrs);
  		if (code) {
***************
*** 775,781 ****
  
  		addrs.bulkaddrs_val = 0;
  		addrs.bulkaddrs_len = 0;
! 		code = ubik_Call(VL_GetAddrs, cstruct, 0, 0 /*Handle */ ,
  				 0 /*spare2 */ , &vlcb,
  				 &nentries, &addrs);
  		if (code) {
--- 776,782 ----
  
  		addrs.bulkaddrs_val = 0;
  		addrs.bulkaddrs_len = 0;
! 		code = ubik_VL_GetAddrs(cstruct, 0, 0 /*Handle */ ,
  				 0 /*spare2 */ , &vlcb,
  				 &nentries, &addrs);
  		if (code) {
***************
*** 800,806 ****
  			attrs.index = *addrp & 0x00ffffff;
  
  			code =
! 			    ubik_Call(VL_GetAddrsU, cstruct, 0, &attrs, &uuid,
  				      &unique, &mhnentries, &mhaddrs);
  			if (code) {
  			    printf("VL_GetAddrsU returned code = %d\n", code);
--- 801,807 ----
  			attrs.index = *addrp & 0x00ffffff;
  
  			code =
! 			    ubik_VL_GetAddrsU(cstruct, 0, &attrs, &uuid,
  				      &unique, &mhnentries, &mhaddrs);
  			if (code) {
  			    printf("VL_GetAddrsU returned code = %d\n", code);
***************
*** 850,856 ****
  		addrs1.bulkaddrs_val = 0;
  		addrs1.bulkaddrs_len = 0;
  		code =
! 		    ubik_Call(VL_GetAddrs, cstruct, 0, 0, 0, &vlcb,
  			      &nentries1, &addrs1);
  		if (code) {
  		    printf("VL_GetAddrs returned code = %d\n", code);
--- 851,857 ----
  		addrs1.bulkaddrs_val = 0;
  		addrs1.bulkaddrs_len = 0;
  		code =
! 		    ubik_VL_GetAddrs(cstruct, 0, 0, 0, &vlcb,
  			      &nentries1, &addrs1);
  		if (code) {
  		    printf("VL_GetAddrs returned code = %d\n", code);
***************
*** 872,878 ****
  			attrs.Mask = VLADDR_INDEX;
  			attrs.index = (base * VL_MHSRV_PERBLK) + index;
  			code =
! 			    ubik_Call(VL_GetAddrsU, cstruct, 0, &attrs, &uuid,
  				      &unique, &nentries2, &addrs2);
  			if (code) {
  			    printf("VL_GetAddrsU returned code = %d\n", code);
--- 873,879 ----
  			attrs.Mask = VLADDR_INDEX;
  			attrs.index = (base * VL_MHSRV_PERBLK) + index;
  			code =
! 			    ubik_VL_GetAddrsU(cstruct, 0, &attrs, &uuid,
  				      &unique, &nentries2, &addrs2);
  			if (code) {
  			    printf("VL_GetAddrsU returned code = %d\n", code);
***************
*** 956,962 ****
  		    ++argp, --nargs;
  		}
  		code =
! 		    ubik_Call(VL_RegisterAddrs, cstruct, 0, &uuid,
  			      0 /*spare */ , &addrs);
  		if (code) {
  		    printf("VL_RegisterAddrs returned code = %d\n", code);
--- 957,963 ----
  		    ++argp, --nargs;
  		}
  		code =
! 		    ubik_VL_RegisterAddrs(cstruct, 0, &uuid,
  			      0 /*spare */ , &addrs);
  		if (code) {
  		    printf("VL_RegisterAddrs returned code = %d\n", code);
***************
*** 988,994 ****
  
  		printf("changing 0x%x to 0x%x\n", ntohl(a1), ntohl(a2));
  		code =
! 		    ubik_Call(VL_ChangeAddr, cstruct, 0, ntohl(a1),
  			      ntohl(a2));
  		if (code) {
  		    printf("VL_ChangeAddr returned code = %d\n", code);
--- 989,995 ----
  
  		printf("changing 0x%x to 0x%x\n", ntohl(a1), ntohl(a2));
  		code =
! 		    ubik_VL_ChangeAddr(cstruct, 0, ntohl(a1),
  			      ntohl(a2));
  		if (code) {
  		    printf("VL_ChangeAddr returned code = %d\n", code);
***************
*** 1002,1008 ****
  		++argp, --nargs;
  		sscanf(&(*argp)[0], "%d", &a2);
  		printf(" to %d (0x%x)\n", a2, a2);
! 		code = ubik_Call(VL_ChangeAddr, cstruct, 0, a1, a2);
  		if (code) {
  		    printf("VL_ChangeAddr returned code = %d\n", code);
  		    continue;
--- 1003,1009 ----
  		++argp, --nargs;
  		sscanf(&(*argp)[0], "%d", &a2);
  		printf(" to %d (0x%x)\n", a2, a2);
! 		code = ubik_VL_ChangeAddr(cstruct, 0, a1, a2);
  		if (code) {
  		    printf("VL_ChangeAddr returned code = %d\n", code);
  		    continue;
Index: openafs/src/vol/vol-salvage.c
diff -c openafs/src/vol/vol-salvage.c:1.51.2.21 openafs/src/vol/vol-salvage.c:1.51.2.22
*** openafs/src/vol/vol-salvage.c:1.51.2.21	Tue Dec  9 12:05:11 2008
--- openafs/src/vol/vol-salvage.c	Thu Jan 22 09:29:54 2009
***************
*** 87,93 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/vol-salvage.c,v 1.51.2.21 2008/12/09 17:05:11 shadow Exp $");
  
  #ifndef AFS_NT40_ENV
  #include <sys/param.h>
--- 87,93 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/vol-salvage.c,v 1.51.2.22 2009/01/22 14:29:54 shadow Exp $");
  
  #ifndef AFS_NT40_ENV
  #include <sys/param.h>
***************
*** 1213,1219 ****
  	    p = strrchr(dp->d_name, '.');
  	    if (p != NULL && strcmp(p, VHDREXT) == 0) {
  		int fd;
! 		if ((fd = afs_open(dp->d_name, O_RDONLY)) != -1
  		    && read(fd, (char *)&diskHeader, sizeof(diskHeader))
  		    == sizeof(diskHeader)
  		    && diskHeader.stamp.magic == VOLUMEHEADERMAGIC) {
--- 1213,1221 ----
  	    p = strrchr(dp->d_name, '.');
  	    if (p != NULL && strcmp(p, VHDREXT) == 0) {
  		int fd;
! 		char name[64];
! 		sprintf(name, "%s/%s", fileSysPath, dp->d_name);
! 		if ((fd = afs_open(name, O_RDONLY)) != -1
  		    && read(fd, (char *)&diskHeader, sizeof(diskHeader))
  		    == sizeof(diskHeader)
  		    && diskHeader.stamp.magic == VOLUMEHEADERMAGIC) {
***************
*** 1247,1253 ****
  	if (p != NULL && strcmp(p, VHDREXT) == 0) {
  	    int error = 0;
  	    int fd;
! 	    if ((fd = afs_open(dp->d_name, O_RDONLY)) == -1
  		|| read(fd, &diskHeader, sizeof(diskHeader))
  		!= sizeof(diskHeader)
  		|| diskHeader.stamp.magic != VOLUMEHEADERMAGIC) {
--- 1249,1257 ----
  	if (p != NULL && strcmp(p, VHDREXT) == 0) {
  	    int error = 0;
  	    int fd;
! 	    char name[64];
! 	    sprintf(name, "%s/%s", fileSysPath, dp->d_name);
! 	    if ((fd = afs_open(name, O_RDONLY)) == -1
  		|| read(fd, &diskHeader, sizeof(diskHeader))
  		!= sizeof(diskHeader)
  		|| diskHeader.stamp.magic != VOLUMEHEADERMAGIC) {
***************
*** 1737,1759 ****
      }
  
      if (isp->volSummary == NULL) {
! 	char name[64];
! 	(void)afs_snprintf(name, sizeof name, VFORMAT, isp->volumeId);
  	if (check) {
  	    Log("No header file for volume %u\n", isp->volumeId);
  	    return -1;
  	}
  	if (!Showmode)
! 	    Log("No header file for volume %u; %screating %s/%s\n",
  		isp->volumeId, (Testing ? "it would have been " : ""),
! 		fileSysPathName, name);
! 	headerFd = afs_open(name, O_RDWR | O_CREAT | O_TRUNC, 0644);
  	assert(headerFd != -1);
  	isp->volSummary = (struct VolumeSummary *)
  	    malloc(sizeof(struct VolumeSummary));
! 	isp->volSummary->fileName = ToString(name);
      } else {
! 	char name[64];
  	/* hack: these two fields are obsolete... */
  	isp->volSummary->header.volumeAcl = 0;
  	isp->volSummary->header.volumeMountTable = 0;
--- 1741,1766 ----
      }
  
      if (isp->volSummary == NULL) {
! 	char path[64];
! 	char headerName[64];
! 	(void)afs_snprintf(headerName, sizeof headerName, VFORMAT, isp->volumeId);
! 	(void)afs_snprintf(path, sizeof path, "%s/%s", fileSysPath, headerName);
  	if (check) {
  	    Log("No header file for volume %u\n", isp->volumeId);
  	    return -1;
  	}
  	if (!Showmode)
! 	    Log("No header file for volume %u; %screating %s\n",
  		isp->volumeId, (Testing ? "it would have been " : ""),
! 		path);
! 	headerFd = afs_open(path, O_RDWR | O_CREAT | O_TRUNC, 0644);
  	assert(headerFd != -1);
  	isp->volSummary = (struct VolumeSummary *)
  	    malloc(sizeof(struct VolumeSummary));
! 	isp->volSummary->fileName = ToString(headerName);
      } else {
! 	char path[64];
! 	char headerName[64];
  	/* hack: these two fields are obsolete... */
  	isp->volSummary->header.volumeAcl = 0;
  	isp->volSummary->header.volumeMountTable = 0;
***************
*** 1763,1780 ****
  	     sizeof(struct VolumeHeader))) {
  	    /* We often remove the name before calling us, so we make a fake one up */
  	    if (isp->volSummary->fileName) {
! 		strcpy(name, isp->volSummary->fileName);
  	    } else {
! 		(void)afs_snprintf(name, sizeof name, VFORMAT, isp->volumeId);
! 		isp->volSummary->fileName = ToString(name);
  	    }
  
! 	    Log("Header file %s is damaged or no longer valid%s\n", name,
  		(check ? "" : "; repairing"));
  	    if (check)
  		return -1;
  
! 	    headerFd = afs_open(name, O_RDWR | O_TRUNC, 0644);
  	    assert(headerFd != -1);
  	}
      }
--- 1770,1788 ----
  	     sizeof(struct VolumeHeader))) {
  	    /* We often remove the name before calling us, so we make a fake one up */
  	    if (isp->volSummary->fileName) {
! 		strcpy(headerName, isp->volSummary->fileName);
  	    } else {
! 		(void)afs_snprintf(headerName, sizeof headerName, VFORMAT, isp->volumeId);
! 		isp->volSummary->fileName = ToString(headerName);
  	    }
+ 	    (void)afs_snprintf(path, sizeof path, "%s/%s", fileSysPath, headerName);
  
! 	    Log("Header file %s is damaged or no longer valid%s\n", path,
  		(check ? "" : "; repairing"));
  	    if (check)
  		return -1;
  
! 	    headerFd = afs_open(path, O_RDWR | O_TRUNC, 0644);
  	    assert(headerFd != -1);
  	}
      }
Index: openafs/src/vol/volume.c
diff -c openafs/src/vol/volume.c:1.43.2.24 openafs/src/vol/volume.c:1.43.2.25
*** openafs/src/vol/volume.c:1.43.2.24	Mon Oct 27 19:53:47 2008
--- openafs/src/vol/volume.c	Thu Jan 22 14:12:51 2009
***************
*** 22,28 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/volume.c,v 1.43.2.24 2008/10/27 23:53:47 shadow 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.25 2009/01/22 19:12:51 shadow Exp $");
  
  #include <rx/xdr.h>
  #include <afs/afsint.h>
***************
*** 2509,2515 ****
  	    V_offlineMessage(vp)[0] = '\0';
  	}
      } else {
! 	V_inUse(vp) = programType;
  	V_checkoutMode(vp) = mode;
      }
  
--- 2509,2516 ----
  	    V_offlineMessage(vp)[0] = '\0';
  	}
      } else {
! 	if ((mode != V_PEEK) && (mode != V_SECRETLY))
! 	    V_inUse(vp) = programType;
  	V_checkoutMode(vp) = mode;
      }
  
***************
*** 3199,3204 ****
--- 3200,3208 ----
      DeleteVolumeFromVByPList_r(vp);
      VLRU_Delete_r(vp);
      VChangeState_r(vp, VOL_STATE_SHUTTING_DOWN);
+ #else
+     if (programType != fileServer) 
+ 	V_inUse(vp) = 0;
  #endif /* AFS_DEMAND_ATTACH_FS */
      VPutVolume_r(vp);
      /* Will be detached sometime in the future--this is OK since volume is offline */
Index: openafs/src/volser/volprocs.c
diff -c openafs/src/volser/volprocs.c:1.42.2.18 openafs/src/volser/volprocs.c:1.42.2.19
*** openafs/src/volser/volprocs.c:1.42.2.18	Thu Sep 25 04:58:22 2008
--- openafs/src/volser/volprocs.c	Sun Jan 18 22:19:15 2009
***************
*** 13,19 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/volprocs.c,v 1.42.2.18 2008/09/25 08:58:22 shadow Exp $");
  
  #include <stdio.h>
  #include <sys/types.h>
--- 13,19 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/volprocs.c,v 1.42.2.19 2009/01/19 03:19:15 shadow Exp $");
  
  #include <stdio.h>
  #include <sys/types.h>
***************
*** 1068,1073 ****
--- 1068,1074 ----
      }
      VUpdateVolume(&error, vp);
      tt->vflags = aflags;
+     tt->rxCallPtr = (struct rx_call *)0;
      if (TRELE(tt) && !error)
  	return VOLSERTRELE_ERROR;
  
