Index: openafs/src/NTMakefile
diff -c openafs/src/NTMakefile:1.24.2.1 openafs/src/NTMakefile:1.24.2.2
*** openafs/src/NTMakefile:1.24.2.1	Tue Mar 22 14:48:28 2005
--- openafs/src/NTMakefile	Wed May 18 18:57:06 2005
***************
*** 469,531 ****
  	$(NTMAKE)
  	$(CD) ..\..\..
  
! afsadmsvr: license
       echo ***** $@
  	$(DOCD) $(SRC)\WINNT\$@
  	$(CD) $(SRC)\WINNT\$@
  	$(NTMAKE)
  	$(CD) ..\..\..
  
! afsusrmgr: afsadmsvr
       echo ***** $@
  	$(DOCD) $(SRC)\WINNT\$@
  	$(CD) $(SRC)\WINNT\$@
  	$(NTMAKE)
  	$(CD) ..\..\..
  
! afssvrmgr: afsusrmgr
       echo ***** $@
  	$(DOCD) $(SRC)\WINNT\$@
  	$(CD) $(SRC)\WINNT\$@
  	$(NTMAKE)
  	$(CD) ..\..\..
  
! afssvrcfg: afssvrmgr
       echo ***** $@
  	$(DOCD) $(SRC)\WINNT\$@
  	$(CD) $(SRC)\WINNT\$@
  	$(NTMAKE)
  	$(CD) ..\..\..
  
! afssvrcpa: afssvrcfg
       echo ***** $@
  	$(DOCD) $(SRC)\WINNT\$@
  	$(CD) $(SRC)\WINNT\$@
  	$(NTMAKE)
  	$(CD) ..\..\..
  
! client_talocale: afssvrcpa
       echo ***** $@
! 	$(DOCD) $(SRC)\WINNT\talocale
! 	$(CD) $(SRC)\WINNT\talocale
  	$(NTMAKE)
  	$(CD) ..\..\..
  
! client_osi: client_talocale
       echo ***** $@
  	$(DOCD) $(SRC)\WINNT\$@
  	$(CD) $(SRC)\WINNT\$@
  	$(NTMAKE)
  	$(CD) ..\..\..
  
! afsd: client_osi
       echo ***** $@
! 	$(DOCD) $(SRC)\WINNT\$@
! 	$(CD) $(SRC)\WINNT\$@
  	$(NTMAKE)
  	$(CD) ..\..\..
  
! client_cpa: afsd
       echo ***** $@
  	$(DOCD) $(SRC)\WINNT\$@
  	$(CD) $(SRC)\WINNT\$@
--- 469,531 ----
  	$(NTMAKE)
  	$(CD) ..\..\..
  
! client_osi: license
       echo ***** $@
  	$(DOCD) $(SRC)\WINNT\$@
  	$(CD) $(SRC)\WINNT\$@
  	$(NTMAKE)
  	$(CD) ..\..\..
  
! afsd: client_osi
       echo ***** $@
  	$(DOCD) $(SRC)\WINNT\$@
  	$(CD) $(SRC)\WINNT\$@
  	$(NTMAKE)
  	$(CD) ..\..\..
  
! afsadmsvr: afsd
       echo ***** $@
  	$(DOCD) $(SRC)\WINNT\$@
  	$(CD) $(SRC)\WINNT\$@
  	$(NTMAKE)
  	$(CD) ..\..\..
  
! afsusrmgr: afsadmsvr
       echo ***** $@
  	$(DOCD) $(SRC)\WINNT\$@
  	$(CD) $(SRC)\WINNT\$@
  	$(NTMAKE)
  	$(CD) ..\..\..
  
! afssvrmgr: afsusrmgr
       echo ***** $@
  	$(DOCD) $(SRC)\WINNT\$@
  	$(CD) $(SRC)\WINNT\$@
  	$(NTMAKE)
  	$(CD) ..\..\..
  
! afssvrcfg: afssvrmgr
       echo ***** $@
! 	$(DOCD) $(SRC)\WINNT\$@
! 	$(CD) $(SRC)\WINNT\$@
  	$(NTMAKE)
  	$(CD) ..\..\..
  
! afssvrcpa: afssvrcfg
       echo ***** $@
  	$(DOCD) $(SRC)\WINNT\$@
  	$(CD) $(SRC)\WINNT\$@
  	$(NTMAKE)
  	$(CD) ..\..\..
  
! client_talocale: afssvrcpa
       echo ***** $@
! 	$(DOCD) $(SRC)\WINNT\talocale
! 	$(CD) $(SRC)\WINNT\talocale
  	$(NTMAKE)
  	$(CD) ..\..\..
  
! client_cpa: client_talocale
       echo ***** $@
  	$(DOCD) $(SRC)\WINNT\$@
  	$(CD) $(SRC)\WINNT\$@
Index: openafs/src/WINNT/afsapplib/al_admsvr.cpp
diff -c openafs/src/WINNT/afsapplib/al_admsvr.cpp:1.2 openafs/src/WINNT/afsapplib/al_admsvr.cpp:1.2.20.1
*** openafs/src/WINNT/afsapplib/al_admsvr.cpp:1.2	Sat Nov  4 05:01:18 2000
--- openafs/src/WINNT/afsapplib/al_admsvr.cpp	Wed May 18 18:57:06 2005
***************
*** 25,31 ****
     {
     BOOL fUseAdminServer;
     DWORD idAdminServerClient;
!    } l;
  
  
  /*
--- 25,31 ----
     {
     BOOL fUseAdminServer;
     DWORD idAdminServerClient;
!    } l = {0, 0};
  
  
  /*
Index: openafs/src/WINNT/afsapplib/al_creds.cpp
diff -c openafs/src/WINNT/afsapplib/al_creds.cpp:1.4 openafs/src/WINNT/afsapplib/al_creds.cpp:1.4.2.1
*** openafs/src/WINNT/afsapplib/al_creds.cpp:1.4	Sat Nov 29 17:07:57 2003
--- openafs/src/WINNT/afsapplib/al_creds.cpp	Wed May 18 18:57:06 2005
***************
*** 68,74 ****
        {
        rc = asc_CredentialsCrack (idClient, hCreds, pszCell, pszUser, pst, &status);
        }
!    else if (OpenClientLibrary())
        {
        char szUserA[ cchRESOURCE ], szUser2A[ cchRESOURCE ];
        char szCellA[ cchRESOURCE ];
--- 68,75 ----
        {
        rc = asc_CredentialsCrack (idClient, hCreds, pszCell, pszUser, pst, &status);
        }
!    else 
!        if (OpenClientLibrary())
        {
        char szUserA[ cchRESOURCE ], szUser2A[ cchRESOURCE ];
        char szCellA[ cchRESOURCE ];
***************
*** 102,108 ****
        {
        hCreds = asc_CredentialsGet (idClient, pszCell, &status);
        }
!    else if (OpenClientLibrary())
        {
        LPSTR pszCellA = StringToAnsi (pszCell);
  
--- 103,110 ----
        {
        hCreds = asc_CredentialsGet (idClient, pszCell, &status);
        }
!    else
!        if (OpenClientLibrary())
        {
        LPSTR pszCellA = StringToAnsi (pszCell);
  
***************
*** 128,134 ****
        {
        hCreds = asc_CredentialsSet (idClient, pszCell, pszUser, pszPassword, &status);
        }
!    else if (OpenClientLibrary())
        {
        char szCellA[ cchRESOURCE ];
        char szUserA[ cchRESOURCE ];
--- 130,137 ----
        {
        hCreds = asc_CredentialsSet (idClient, pszCell, pszUser, pszPassword, &status);
        }
!    else
!        if (OpenClientLibrary())
        {
        char szCellA[ cchRESOURCE ];
        char szUserA[ cchRESOURCE ];
***************
*** 903,908 ****
--- 906,914 ----
  
  BOOL AfsAppLib_IsUserAdmin (PVOID hCreds, LPTSTR pszUser)
  {
+ #ifndef USE_KASERVER
+     return TRUE;
+ #else
     BOOL rc = FALSE;
     afs_status_t status;
  
***************
*** 969,973 ****
--- 975,980 ----
        }
  
     return rc;
+ #endif /* USE_KASERVER */
  }
  
Index: openafs/src/WINNT/afsapplib/al_misc.cpp
diff -c openafs/src/WINNT/afsapplib/al_misc.cpp:1.2 openafs/src/WINNT/afsapplib/al_misc.cpp:1.2.20.1
*** openafs/src/WINNT/afsapplib/al_misc.cpp:1.2	Sat Nov  4 05:01:20 2000
--- openafs/src/WINNT/afsapplib/al_misc.cpp	Wed May 18 18:57:06 2005
***************
*** 213,219 ****
        ULONG status;
        return asc_ErrorCodeTranslate (idClient, code, idLanguage, pszText, &status);
        }
!    else if (OpenUtilLibrary())
        {
        const char *pszTextA = NULL;
        afs_status_t status;
--- 213,220 ----
        ULONG status;
        return asc_ErrorCodeTranslate (idClient, code, idLanguage, pszText, &status);
        }
!    else
!        if (OpenUtilLibrary())
        {
        const char *pszTextA = NULL;
        afs_status_t status;
***************
*** 463,469 ****
           {
           rc = asc_LocalCellGet (idClient, szCell, &status);
           }
!       else if (OpenClientLibrary())
           {
           char szCellNameA[ MAX_PATH ];
           if ((rc = afsclient_LocalCellGet (szCellNameA, (afs_status_p)&status)) == TRUE)
--- 464,471 ----
           {
           rc = asc_LocalCellGet (idClient, szCell, &status);
           }
!       else 
!           if (OpenClientLibrary())
           {
           char szCellNameA[ MAX_PATH ];
           if ((rc = afsclient_LocalCellGet (szCellNameA, (afs_status_p)&status)) == TRUE)
Index: openafs/src/WINNT/afsd/NTMakefile
diff -c openafs/src/WINNT/afsd/NTMakefile:1.27.2.8 openafs/src/WINNT/afsd/NTMakefile:1.27.2.9
*** openafs/src/WINNT/afsd/NTMakefile:1.27.2.8	Thu Apr 28 08:05:19 2005
--- openafs/src/WINNT/afsd/NTMakefile	Sun May 29 23:52:52 2005
***************
*** 282,288 ****
          $(EXEDIR)\afsdacl.exe \
  	$(LOGON_DLLFILE) \
  	$(EXEDIR)\afsshare.exe \
! 	$(DESTDIR)\bin\kpasswd.exe $(EXEDIR)\cmdebug.exe
  
  install9X: install_headers $(CONF_DLLFILE) \
  	$(EXEDIR)\klog.exe \
--- 282,288 ----
          $(EXEDIR)\afsdacl.exe \
  	$(LOGON_DLLFILE) \
  	$(EXEDIR)\afsshare.exe \
! 	$(DESTDIR)\bin\kpasswd.exe $(EXEDIR)\cmdebug.exe $(EXEDIR)\afscpcc.exe
  
  install9X: install_headers $(CONF_DLLFILE) \
  	$(EXEDIR)\klog.exe \
***************
*** 354,359 ****
--- 354,365 ----
  	$(EXECONLINK) dnsapi.lib mpr.lib iphlpapi.lib
  	$(EXEPREP)
  
+ # afscpcc.exe
+ $(EXEDIR)\afscpcc.exe: $(OUT)\afscpcc.obj $(OUT)\afscpcc.res $(LOGON_DLLLIBS)
+ 	$(EXECONLINK) dnsapi.lib mpr.lib iphlpapi.lib
+ 	$(EXEPREP)
+ 
+ 
  # afsd.exe
  AFSD_EXEFILE = $(EXEDIR)\afsd.exe
  
***************
*** 472,477 ****
--- 478,485 ----
  
  $(OUT)\unlog.res: unlog.rc AFS_component_version_number.h
  
+ $(OUT)\afscpcc.res: afscpcc.rc AFS_component_version_number.h
+ 
  afsd_eventmessages.rc: afsd_eventmessages.h
  
  $(OUT)\afsd_service.res: afsd_service.rc afsd_eventmessages.rc AFS_component_version_number.h
Index: openafs/src/WINNT/afsd/afscpcc.c
diff -c /dev/null openafs/src/WINNT/afsd/afscpcc.c:1.1.2.2
*** /dev/null	Wed Jun  1 00:59:55 2005
--- openafs/src/WINNT/afsd/afscpcc.c	Sun May 29 23:52:52 2005
***************
*** 0 ****
--- 1,21 ----
+ /*
+  * Copyright 2005, Secure Endpoints Inc.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the MIT License.  
+  */
+ 
+ #include <windows.h>
+ #include <afskfw.h>
+ 
+ int main(int argc, char *argv[])
+ {
+     if ( argc != 2 )
+         return 1;
+ 
+     KFW_initialize();
+ 
+     return KFW_AFS_copy_system_file_to_default_cache(argv[1]);
+ }
+ 
+ 
Index: openafs/src/WINNT/afsd/afscpcc.rc
diff -c /dev/null openafs/src/WINNT/afsd/afscpcc.rc:1.1.2.2
*** /dev/null	Wed Jun  1 00:59:55 2005
--- openafs/src/WINNT/afsd/afscpcc.rc	Sun May 29 23:52:52 2005
***************
*** 0 ****
--- 1,15 ----
+ /*
+  * Copyright 2005, Secure Endpoints Inc.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the MIT License.  
+  */
+ 
+ /* Define VERSIONINFO resource */
+ 
+ #define  AFS_VERINFO_FILE_DESCRIPTION "AFS Logon Copy Credentials Command"
+ #define AFS_VERINFO_NAME "afscpcc"
+ #define AFS_VERINFO_FILENAME "afscpcc.exe"
+ 
+ #include "AFS_component_version_number.h"
+ #include "..\..\config\NTVersioninfo.rc"
Index: openafs/src/WINNT/afsd/afsd.h
diff -c openafs/src/WINNT/afsd/afsd.h:1.5.2.5 openafs/src/WINNT/afsd/afsd.h:1.5.2.6
*** openafs/src/WINNT/afsd/afsd.h:1.5.2.5	Tue Apr 19 17:07:14 2005
--- openafs/src/WINNT/afsd/afsd.h	Wed May 18 18:57:07 2005
***************
*** 147,150 ****
--- 147,152 ----
  typedef BOOL ( APIENTRY * AfsdStoppingHook )(void);
  #define AFSD_STOPPED_HOOK "AfsdStoppedHook"
  typedef BOOL ( APIENTRY * AfsdStoppedHook )(void);
+ 
+ #define SERVICE_CONTROL_CUSTOM_DUMP 128
  #endif /* AFSD_H_ENV */
Index: openafs/src/WINNT/afsd/afsd_init.c
diff -c openafs/src/WINNT/afsd/afsd_init.c:1.40.2.18 openafs/src/WINNT/afsd/afsd_init.c:1.40.2.20
*** openafs/src/WINNT/afsd/afsd_init.c:1.40.2.18	Mon Apr  4 22:17:15 2005
--- openafs/src/WINNT/afsd/afsd_init.c	Sun May 29 23:52:52 2005
***************
*** 19,24 ****
--- 19,25 ----
  #include <locale.h>
  #include <mbctype.h>
  #include <winsock2.h>
+ #include <ErrorRep.h>
  
  #include <osi.h>
  #include "afsd.h"
***************
*** 135,141 ****
  void
  afsi_start()
  {
!     char wd[100];
      char t[100], u[100], *p, *path;
      int zilch;
      int code;
--- 136,142 ----
  void
  afsi_start()
  {
!     char wd[256];
      char t[100], u[100], *p, *path;
      int zilch;
      int code;
***************
*** 145,155 ****
      DWORD maxLogSize = 100 * 1024;
  
      afsi_file = INVALID_HANDLE_VALUE;
!     if (getenv("TEMP"))
!     {
!         StringCbCopyA(wd, sizeof(wd), getenv("TEMP"));
!     }
!     else
      {
          code = GetWindowsDirectory(wd, sizeof(wd));
          if (code == 0) 
--- 146,153 ----
      DWORD maxLogSize = 100 * 1024;
  
      afsi_file = INVALID_HANDLE_VALUE;
!     code = GetEnvironmentVariable("TEMP", wd, sizeof(wd));
!     if ( code == 0 || code > sizeof(wd) )
      {
          code = GetWindowsDirectory(wd, sizeof(wd));
          if (code == 0) 
***************
*** 185,194 ****
      WriteFile(afsi_file, t, strlen(t), &zilch, NULL);
      WriteFile(afsi_file, u, strlen(u), &zilch, NULL);
      p = "PATH=";
!     path = getenv("PATH");
      WriteFile(afsi_file, p, strlen(p), &zilch, NULL);
      WriteFile(afsi_file, path, strlen(path), &zilch, NULL);
      WriteFile(afsi_file, "\n", 1, &zilch, NULL);
  
      /* Initialize C RTL Code Page conversion functions */
      /* All of the path info obtained from the SMB client is in the OEM code page */
--- 183,195 ----
      WriteFile(afsi_file, t, strlen(t), &zilch, NULL);
      WriteFile(afsi_file, u, strlen(u), &zilch, NULL);
      p = "PATH=";
!     code = GetEnvironmentVariable("PATH", NULL, 0);
!     path = malloc(code);
!     code = GetEnvironmentVariable("PATH", path, code);
      WriteFile(afsi_file, p, strlen(p), &zilch, NULL);
      WriteFile(afsi_file, path, strlen(path), &zilch, NULL);
      WriteFile(afsi_file, "\n", 1, &zilch, NULL);
+     free(path);
  
      /* Initialize C RTL Code Page conversion functions */
      /* All of the path info obtained from the SMB client is in the OEM code page */
***************
*** 815,827 ****
      dummyLen = sizeof(traceOnPanic);
      code = RegQueryValueEx(parmKey, "TrapOnPanic", NULL, NULL,
                              (BYTE *) &traceOnPanic, &dummyLen);
!     if (code == ERROR_SUCCESS)
!         afsi_log("Set to %s on panic",
!                   traceOnPanic ? "trap" : "not trap");
!     else {  
!         traceOnPanic = 0;
!         /* Don't log */
!     }
  
      dummyLen = sizeof(reportSessionStartups);
      code = RegQueryValueEx(parmKey, "ReportSessionStartups", NULL, NULL,
--- 816,824 ----
      dummyLen = sizeof(traceOnPanic);
      code = RegQueryValueEx(parmKey, "TrapOnPanic", NULL, NULL,
                              (BYTE *) &traceOnPanic, &dummyLen);
!     if (code != ERROR_SUCCESS)
!         traceOnPanic = 1;              /* log */
!     afsi_log("Set to %s on panic", traceOnPanic ? "trap" : "not trap");
  
      dummyLen = sizeof(reportSessionStartups);
      code = RegQueryValueEx(parmKey, "ReportSessionStartups", NULL, NULL,
***************
*** 1390,1401 ****
--- 1387,1488 ----
  static DWORD afsd_crtDbgBreaks[256];
  #endif
  
+ static EFaultRepRetVal (WINAPI *pReportFault)(LPEXCEPTION_POINTERS pep, DWORD dwMode) = NULL;
+ static BOOL (WINAPI *pMiniDumpWriteDump)(HANDLE hProcess,DWORD ProcessId,HANDLE hFile,
+                                   MINIDUMP_TYPE DumpType,
+                                   PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
+                                   PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
+                                   PMINIDUMP_CALLBACK_INFORMATION CallbackParam) = NULL;
+ 
+ 
+ static HANDLE
+ OpenDumpFile(void)
+ {
+     char wd[256];
+     DWORD code;
+ 
+     code = GetEnvironmentVariable("TEMP", wd, sizeof(wd));
+     if ( code == 0 || code > sizeof(wd) )
+     {
+         if (!GetWindowsDirectory(wd, sizeof(wd)))
+             return NULL;
+     }
+     StringCbCatA(wd, sizeof(wd), "\\afsd.dmp");
+     return CreateFile( wd, GENERIC_WRITE, FILE_SHARE_READ, NULL,
+                             CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);
+ }
+ 
+ void 
+ GenerateMiniDump(PEXCEPTION_POINTERS ep)
+ {
+     if (ep == NULL) 
+     {
+         // Generate exception to get proper context in dump
+         __try 
+         {
+             RaiseException(DBG_CONTINUE, 0, 0, NULL);
+         } 
+         __except(GenerateMiniDump(GetExceptionInformation()), EXCEPTION_CONTINUE_EXECUTION) 
+         {
+         }
+     } 
+     else
+     {
+         MINIDUMP_EXCEPTION_INFORMATION eInfo;
+         HANDLE hFile = NULL;
+         HMODULE hDbgHelp = NULL;
+ 
+         hDbgHelp = LoadLibrary("Dbghelp.dll");
+         if ( hDbgHelp == NULL )
+             return;
+ 
+         (FARPROC) pMiniDumpWriteDump = GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
+         if ( pMiniDumpWriteDump == NULL ) {
+             FreeLibrary(hDbgHelp);
+             return;
+         }
+ 
+         hFile = OpenDumpFile();
+ 
+         if ( hFile ) {
+             HKEY parmKey;
+             DWORD dummyLen;
+             DWORD dwValue;
+             DWORD code;
+             DWORD dwMiniDumpType = MiniDumpNormal;
+ 
+             code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY,
+                                  0, KEY_QUERY_VALUE, &parmKey);
+             if (code == ERROR_SUCCESS) {
+                 dummyLen = sizeof(DWORD);
+                 code = RegQueryValueEx(parmKey, "MiniDumpType", NULL, NULL,
+                                         (BYTE *) &dwValue, &dummyLen);
+                 if (code == ERROR_SUCCESS)
+                     dwMiniDumpType = dwValue ? 1 : 0;
+                 RegCloseKey (parmKey);
+             }
+ 
+             eInfo.ThreadId = GetCurrentThreadId();
+             eInfo.ExceptionPointers = ep;
+             eInfo.ClientPointers = FALSE;
+ 
+             pMiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(),
+                                 hFile, dwMiniDumpType, ep ? &eInfo : NULL,
+                                 NULL, NULL);
+ 
+             CloseHandle(hFile);
+         }
+         FreeLibrary(hDbgHelp);
+     }
+ }
+ 
  LONG __stdcall afsd_ExceptionFilter(EXCEPTION_POINTERS *ep)
  {
      CONTEXT context;
  #ifdef _DEBUG  
      BOOL allocRequestBrk = FALSE;
  #endif 
+     HMODULE hLib = NULL;
    
      afsi_log("UnhandledException : code : 0x%x, address: 0x%x\n", 
               ep->ExceptionRecord->ExceptionCode, 
***************
*** 1414,1420 ****
      context = *ep->ContextRecord;
  	   
      afsd_printStack(GetCurrentThread(), &context);
! 	   
      if (ep->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)
      {
          afsi_log("\nEXCEPTION_BREAKPOINT - continue execution ...\n");
--- 1501,1517 ----
      context = *ep->ContextRecord;
  	   
      afsd_printStack(GetCurrentThread(), &context);
! 
!     GenerateMiniDump(ep);
! 
!     hLib = LoadLibrary("Faultrep.dll");
!     if ( hLib ) {
!         (FARPROC) pReportFault = GetProcAddress(hLib, "ReportFault");
!         if ( pReportFault )
!             pReportFault(ep, 0);
!         FreeLibrary(hLib);
!     }
! 
      if (ep->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)
      {
          afsi_log("\nEXCEPTION_BREAKPOINT - continue execution ...\n");
Index: openafs/src/WINNT/afsd/afsd_init.h
diff -c openafs/src/WINNT/afsd/afsd_init.h:1.5 openafs/src/WINNT/afsd/afsd_init.h:1.5.2.1
*** openafs/src/WINNT/afsd/afsd_init.h:1.5	Sat Apr  3 14:50:37 2004
--- openafs/src/WINNT/afsd/afsd_init.h	Wed May 18 18:57:08 2005
***************
*** 12,17 ****
--- 12,19 ----
  #ifndef DJGPP
  int afsd_InitCM(char **reasonP);
  int afsd_InitSMB(char **reasonP, void *aMBfunc);
+ 
+ void GenerateMiniDump(PEXCEPTION_POINTERS ep);
  #else /* DJGPP */
  int afsd_InitCM(char **reasonP, struct cmd_syndesc *as, char *arock);
  int afsd_InitSMB(char **reasonP);
***************
*** 22,24 ****
--- 24,28 ----
  
  extern char cm_HostName[];
  extern char cm_NetbiosName[];
+ 
+ 
Index: openafs/src/WINNT/afsd/afsd_service.c
diff -c openafs/src/WINNT/afsd/afsd_service.c:1.28.2.15 openafs/src/WINNT/afsd/afsd_service.c:1.28.2.16
*** openafs/src/WINNT/afsd/afsd_service.c:1.28.2.15	Tue Apr 19 17:07:14 2005
--- openafs/src/WINNT/afsd/afsd_service.c	Wed May 18 18:57:08 2005
***************
*** 354,359 ****
--- 354,367 ----
                  }   
              }
          }
+         break;
+     case SERVICE_CONTROL_CUSTOM_DUMP: 
+         {
+             afsi_log("SERVICE_CONTROL_CUSTOM_DUMP"); 
+             GenerateMiniDump(NULL);
+ 			dwRet = NO_ERROR;
+         }
+         break;
      }		/* end switch(ctrlCode) */                                                        
      return dwRet;   
  }
***************
*** 1050,1056 ****
      ServiceStatus.dwCheckPoint = 1;
      ServiceStatus.dwWaitHint = 30000;
      /* accept Power Events */
!     ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT;
      SetServiceStatus(StatusHandle, &ServiceStatus);
  #endif
  
--- 1058,1064 ----
      ServiceStatus.dwCheckPoint = 1;
      ServiceStatus.dwWaitHint = 30000;
      /* accept Power Events */
!     ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT_PARAMCHANGE;
      SetServiceStatus(StatusHandle, &ServiceStatus);
  #endif
  
***************
*** 1138,1144 ****
              ServiceStatus.dwCheckPoint = 2;
              ServiceStatus.dwWaitHint = 20000;
              /* accept Power Events */
!             ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT;
              SetServiceStatus(StatusHandle, &ServiceStatus);
          }
      }
--- 1146,1152 ----
              ServiceStatus.dwCheckPoint = 2;
              ServiceStatus.dwWaitHint = 20000;
              /* accept Power Events */
!             ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT_PARAMCHANGE;
              SetServiceStatus(StatusHandle, &ServiceStatus);
          }
      }
***************
*** 1241,1247 ****
          ServiceStatus.dwWaitHint = 0;
  
          /* accept Power events */
!         ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT;
          SetServiceStatus(StatusHandle, &ServiceStatus);
  #endif  
          {
--- 1249,1255 ----
          ServiceStatus.dwWaitHint = 0;
  
          /* accept Power events */
!         ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT_PARAMCHANGE;
          SetServiceStatus(StatusHandle, &ServiceStatus);
  #endif  
          {
Index: openafs/src/WINNT/afsd/afskfw.c
diff -c openafs/src/WINNT/afsd/afskfw.c:1.8.2.11 openafs/src/WINNT/afsd/afskfw.c:1.8.2.13
*** openafs/src/WINNT/afsd/afskfw.c:1.8.2.11	Tue Apr 19 01:11:17 2005
--- openafs/src/WINNT/afsd/afskfw.c	Tue May 31 10:19:06 2005
***************
*** 1080,1086 ****
                      code = pkrb5_cc_close(ctx,cc);
                      cc = 0;
                      code = pkrb5_cc_close(ctx,oldcc);
!                     cc = 0;
                      KRB5_error(code, "krb5_cc_copy_creds", 0, NULL, NULL);
                      continue;
                  }
--- 1080,1086 ----
                      code = pkrb5_cc_close(ctx,cc);
                      cc = 0;
                      code = pkrb5_cc_close(ctx,oldcc);
!                     oldcc = 0;
                      KRB5_error(code, "krb5_cc_copy_creds", 0, NULL, NULL);
                      continue;
                  }
***************
*** 1370,1376 ****
          return 0;
  
      if ( IsDebuggerPresent() ) {
!         OutputDebugString("KFW_AFS_destroy_ticets_for_cell: ");
          OutputDebugString(cell);
          OutputDebugString("\n");
      }
--- 1370,1376 ----
          return 0;
  
      if ( IsDebuggerPresent() ) {
!         OutputDebugString("KFW_AFS_destroy_tickets_for_cell: ");
          OutputDebugString(cell);
          OutputDebugString("\n");
      }
***************
*** 1422,1427 ****
--- 1422,1481 ----
      return 0;
  }
  
+ int 
+ KFW_AFS_destroy_tickets_for_principal(char * user)
+ {
+     krb5_context		ctx = 0;
+     krb5_error_code		code;
+     int count;
+     char ** cells = NULL;
+     krb5_principal      princ = 0;
+     krb5_ccache			cc  = 0;
+ 
+     if (!pkrb5_init_context)
+         return 0;
+ 
+     if ( IsDebuggerPresent() ) {
+         OutputDebugString("KFW_AFS_destroy_tickets_for_user: ");
+         OutputDebugString(user);
+         OutputDebugString("\n");
+     }
+ 
+     code = pkrb5_init_context(&ctx);
+     if (code) ctx = 0;
+ 
+     code = pkrb5_parse_name(ctx, user, &princ);
+     if (code) goto loop_cleanup;
+ 
+     code = KFW_get_ccache(ctx, princ, &cc);
+     if (code) goto loop_cleanup;
+ 
+     code = pkrb5_cc_destroy(ctx, cc);
+     if (!code) cc = 0;
+ 
+   loop_cleanup:
+     if ( cc ) {
+         pkrb5_cc_close(ctx, cc);
+         cc = 0;
+     }
+     if ( princ ) {
+         pkrb5_free_principal(ctx, princ);
+         princ = 0;
+     }
+ 
+     count = KFW_AFS_find_cells_for_princ(ctx, user, &cells, TRUE);
+     if ( count >= 1 ) {
+         while ( count-- ) {
+             KFW_AFS_update_cell_princ_map(ctx, cells[count], user, FALSE);
+             free(cells[count]);
+         }
+         free(cells);
+     }
+ 
+     pkrb5_free_context(ctx);
+     return 0;
+ }
+ 
  int
  KFW_AFS_renew_expiring_tokens(void)
  {
***************
*** 3454,3457 ****
      if (ctx)
          pkrb5_free_context(ctx);
      return success;
! }
\ No newline at end of file
--- 3508,3638 ----
      if (ctx)
          pkrb5_free_context(ctx);
      return success;
! }
! 
! void
! KFW_AFS_copy_cache_to_system_file(char * user, char * szLogonId)
! {
!     char filename[256];
!     DWORD count;
!     char cachename[264] = "FILE:";
!     krb5_context		ctx = 0;
!     krb5_error_code		code;
!     krb5_principal              princ = 0;
!     krb5_ccache			cc  = 0;
!     krb5_ccache                 ncc = 0;
! 
!     if (!pkrb5_init_context)
!         return;
! 
!     count = GetEnvironmentVariable("TEMP", filename, sizeof(filename));
!     if ( count > sizeof(filename) || count == 0 ) {
!         GetWindowsDirectory(filename, sizeof(filename));
!     }
! 
!     if ( strlen(filename) + strlen(szLogonId) + 2 > sizeof(filename) )
!         return;
! 
!     strcat(filename, "\\");
!     strcat(filename, szLogonId);    
! 
!     strcat(cachename, filename);
! 
!     DeleteFile(filename);
! 
!     code = pkrb5_init_context(&ctx);
!     if (code) ctx = 0;
! 
!     code = pkrb5_parse_name(ctx, user, &princ);
!     if (code) goto cleanup;
! 
!     code = KFW_get_ccache(ctx, princ, &cc);
!     if (code) goto cleanup;
! 
!     code = pkrb5_cc_resolve(ctx, cachename, &ncc);
!     if (code) goto cleanup;
! 
!     code = pkrb5_cc_initialize(ctx, ncc, princ);
!     if (code) goto cleanup;
! 
!     code = pkrb5_cc_copy_creds(ctx,cc,ncc);
! 
!   cleanup:
!     if ( cc ) {
!         pkrb5_cc_close(ctx, cc);
!         cc = 0;
!     }
!     if ( ncc ) {
!         pkrb5_cc_close(ctx, ncc);
!         ncc = 0;
!     }
!     if ( princ ) {
!         pkrb5_free_principal(ctx, princ);
!         princ = 0;
!     }
! 
!     if (ctx)
!         pkrb5_free_context(ctx);
! }
! 
! int
! KFW_AFS_copy_system_file_to_default_cache(char * filename)
! {
!     DWORD count;
!     char cachename[264] = "FILE:";
!     HANDLE hFile;
!     krb5_context		ctx = 0;
!     krb5_error_code		code;
!     krb5_principal              princ = 0;
!     krb5_ccache			cc  = 0;
!     krb5_ccache                 ncc = 0;
!     int retval = 1;
! 
!     if (!pkrb5_init_context)
!         return 1;
! 
!     if ( strlen(filename) + 6 > sizeof(cachename) )
!         return 1;
! 
!     strcat(cachename, filename);
! 
!     code = pkrb5_init_context(&ctx);
!     if (code) ctx = 0;
! 
!     code = pkrb5_cc_resolve(ctx, cachename, &cc);
!     if (code) goto cleanup;
!     
!     code = pkrb5_cc_get_principal(ctx, cc, &princ);
! 
!     code = pkrb5_cc_default(ctx, &ncc);
!     if (!code) {
!         code = pkrb5_cc_initialize(ctx, ncc, princ);
! 
!         if (!code)
!             code = pkrb5_cc_copy_creds(ctx,cc,ncc);
!     }
!     if ( ncc ) {
!         pkrb5_cc_close(ctx, ncc);
!         ncc = 0;
!     }
! 
!     retval=0;   /* success */
! 
!   cleanup:
!     if ( cc ) {
!         pkrb5_cc_close(ctx, cc);
!         cc = 0;
!     }
! 
!     DeleteFile(filename);
! 
!     if ( princ ) {
!         pkrb5_free_principal(ctx, princ);
!         princ = 0;
!     }
! 
!     if (ctx)
!         pkrb5_free_context(ctx);
! 
!     return 0;
! }
Index: openafs/src/WINNT/afsd/afskfw.h
diff -c openafs/src/WINNT/afsd/afskfw.h:1.2.2.1 openafs/src/WINNT/afsd/afskfw.h:1.2.2.2
*** openafs/src/WINNT/afsd/afskfw.h:1.2.2.1	Tue Apr 19 01:11:17 2005
--- openafs/src/WINNT/afsd/afskfw.h	Sun May 29 23:52:52 2005
***************
*** 47,52 ****
--- 47,53 ----
  void KFW_cleanup(void);
  int  KFW_is_available(void);
  int  KFW_AFS_destroy_tickets_for_cell(char *);
+ int  KFW_AFS_destroy_tickets_for_principal(char *);
  int  KFW_AFS_renew_expiring_tokens(void);
  int  KFW_AFS_get_cred( char * username, 
                          char * cell,
***************
*** 62,67 ****
--- 63,72 ----
  void KFW_import_windows_lsa(void);
  BOOL KFW_AFS_get_lsa_principal(char *, DWORD *);
  
+ /* These functions are only to be used in the afslogon.dll */
+ void KFW_AFS_copy_cache_to_system_file(char *, char *);
+ int  KFW_AFS_copy_system_file_to_default_cache(char *);
+ 
  /* From afs/krb_prot.h */
  /* values for kerb error codes */
  #define         KERB_ERR_OK                              0
Index: openafs/src/WINNT/afsd/afslogon.c
diff -c openafs/src/WINNT/afsd/afslogon.c:1.24.2.9 openafs/src/WINNT/afsd/afslogon.c:1.24.2.11
*** openafs/src/WINNT/afsd/afslogon.c:1.24.2.9	Tue Apr 19 01:11:17 2005
--- openafs/src/WINNT/afsd/afslogon.c	Tue May 31 10:19:06 2005
***************
*** 41,48 ****
--- 41,50 ----
  void DebugEvent0(char *a) 
  {
      HANDLE h; char *ptbuf[1];
+     
      if (!ISLOGONTRACE(TraceOption))
          return;
+     
      h = RegisterEventSource(NULL, AFS_LOGON_EVENT_NAME);
      ptbuf[0] = a;
      ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);
***************
*** 651,660 ****
      char logonDomain[MAX_DOMAIN_LENGTH]="";
      char cell[256]="<non-integrated logon>";
      char homePath[MAX_PATH]="";
  
      MSV1_0_INTERACTIVE_LOGON *IL;
  
!     DWORD code;
  
      int pw_exp;
      char *reason;
--- 653,663 ----
      char logonDomain[MAX_DOMAIN_LENGTH]="";
      char cell[256]="<non-integrated logon>";
      char homePath[MAX_PATH]="";
+     char szLogonId[128] = "";
  
      MSV1_0_INTERACTIVE_LOGON *IL;
  
!     DWORD code, code2;
  
      int pw_exp;
      char *reason;
***************
*** 675,689 ****
      int retryInterval;
      int sleepInterval;
  
      /* Make sure the AFS Libraries are initialized */
      AfsLogonInit();
  
      /* Initialize Logon Script to none */
      *lpLogonScript=NULL;
      
!     /* TODO: We should check the value of lpAuthentInfoType before assuming that it is
!        MSV1_0_INTERACTIVE_LOGON though for our purposes KERB_INTERACTIVE_LOGON is
!        co-incidentally equivalent. */
      IL = (MSV1_0_INTERACTIVE_LOGON *) lpAuthentInfo;
  
      /* Are we interactive? */
--- 678,710 ----
      int retryInterval;
      int sleepInterval;
  
+     (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
+                          0, KEY_QUERY_VALUE, &NPKey);
+     LSPsize=sizeof(TraceOption);
+     RegQueryValueEx(NPKey, REG_CLIENT_TRACE_OPTION_PARM, NULL,
+                      &LSPtype, (LPBYTE)&TraceOption, &LSPsize);
+ 
+     RegCloseKey (NPKey);
+ 
+     DebugEvent("NPLogonNotify - LoginId(%d,%d)", lpLogonId->HighPart, lpLogonId->LowPart);
+ 
      /* Make sure the AFS Libraries are initialized */
      AfsLogonInit();
  
      /* Initialize Logon Script to none */
      *lpLogonScript=NULL;
      
!     /* MSV1_0_INTERACTIVE_LOGON and KERB_INTERACTIVE_LOGON are equivalent for
!      * our purposes */
! 
!     if ( wcscmp(lpAuthentInfoType,L"MSV1_0:Interactive") && 
!          wcscmp(lpAuthentInfoType,L"Kerberos:Interactive") )
!     {
!         DebugEvent("Unsupported Authentication Info Type: %S",
!                    lpAuthentInfoType);
!         return 0;
!     }
! 
      IL = (MSV1_0_INTERACTIVE_LOGON *) lpAuthentInfo;
  
      /* Are we interactive? */
***************
*** 708,721 ****
          }
      }
  
-     (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
-                          0, KEY_QUERY_VALUE, &NPKey);
-     LSPsize=sizeof(TraceOption);
-     RegQueryValueEx(NPKey, REG_CLIENT_TRACE_OPTION_PARM, NULL,
-                      &LSPtype, (LPBYTE)&TraceOption, &LSPsize);
- 
-     RegCloseKey (NPKey);
- 
      /*
       * Get Logon options
       */
--- 729,734 ----
***************
*** 804,812 ****
  
                          p = opt.theseCells;
                          while ( *p ) {
!                             code = KFW_AFS_get_cred(principal, p, 0, 0, opt.smbName, &reason);
                              DebugEvent("KFW_AFS_get_cred  uname=[%s] smbname=[%s] cell=[%s] code=[%d]",
!                                         principal,opt.smbName,p,code);
                              p += strlen(p) + 1;
                          }
                          
--- 817,825 ----
  
                          p = opt.theseCells;
                          while ( *p ) {
!                             code2 = KFW_AFS_get_cred(principal, p, 0, 0, opt.smbName, &reason);
                              DebugEvent("KFW_AFS_get_cred  uname=[%s] smbname=[%s] cell=[%s] code=[%d]",
!                                         principal,opt.smbName,p,code2);
                              p += strlen(p) + 1;
                          }
                          
***************
*** 873,881 ****
      }
  
      DebugEvent("while loop exited");
!     /* remove any kerberos 5 tickets currently held by the SYSTEM account */
!     if ( KFW_is_available() )
!         KFW_AFS_destroy_tickets_for_cell(cell);
  
      if (code) {
          char msg[128];
--- 886,900 ----
      }
  
      DebugEvent("while loop exited");
!     /* remove any kerberos 5 tickets currently held by the SYSTEM account
!      * for this user 
!      */
!     if ( KFW_is_available() ) {
!         sprintf(szLogonId,"%d.%d",lpLogonId->HighPart, lpLogonId->LowPart);
!         KFW_AFS_copy_cache_to_system_file(uname, szLogonId);
! 
!         KFW_AFS_destroy_tickets_for_principal(uname);
!     }
  
      if (code) {
          char msg[128];
***************
*** 1040,1059 ****
  
  VOID AFS_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
  {
-     DWORD code;
      TCHAR profileDir[1024] = TEXT("");
      DWORD  len = 1024;
      PTOKEN_USER  tokenUser = NULL;
      DWORD  retLen;
-     HANDLE hToken;
- 
      WCHAR szUserW[128] = L"";
      char  szUserA[128] = "";
      char  szClient[MAX_PATH];
      char szPath[MAX_PATH] = "";
      NETRESOURCE nr;
      DWORD res;
-     DWORD gle;
      DWORD dwSize;
  
      /* Make sure the AFS Libraries are initialized */
--- 1059,1074 ----
***************
*** 1061,1066 ****
--- 1076,1083 ----
  
      DebugEvent0("AFS_Logon_Event - Start");
  
+     DebugEvent("AFS_Logon_Event Process ID: %d",GetCurrentProcessId());
+ 
      if (!GetTokenInformation(pInfo->hToken, TokenUser, NULL, 0, &retLen))
      {
          if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) {
***************
*** 1123,1125 ****
--- 1140,1256 ----
      DebugEvent0("AFS_Logon_Event - End");
  }
  
+ static BOOL
+ GetSecurityLogonSessionData(HANDLE hToken, PSECURITY_LOGON_SESSION_DATA * ppSessionData)
+ {
+     NTSTATUS Status = 0;
+     HANDLE  TokenHandle;
+     TOKEN_STATISTICS Stats;
+     DWORD   ReqLen;
+     BOOL    Success;
+ 
+     if (!ppSessionData)
+         return FALSE;
+     *ppSessionData = NULL;
+ 
+ #if 0
+     Success = OpenProcessToken( HANDLE GetCurrentProcess(), TOKEN_QUERY, &TokenHandle );
+     if ( !Success )
+         return FALSE;
+ #endif
+ 
+     Success = GetTokenInformation( hToken, TokenStatistics, &Stats, sizeof(TOKEN_STATISTICS), &ReqLen );
+ #if 0
+     CloseHandle( TokenHandle );
+ #endif
+     if ( !Success )
+         return FALSE;
+ 
+     Status = LsaGetLogonSessionData( &Stats.AuthenticationId, ppSessionData );
+     if ( FAILED(Status) || !ppSessionData )
+         return FALSE;
+ 
+     return TRUE;
+ }
+ 
+ VOID KFW_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
+ {
+     DWORD code;
+ 
+     WCHAR szUserW[128] = L"";
+     char  szUserA[128] = "";
+     char  szClient[MAX_PATH];
+     char szPath[MAX_PATH] = "";
+     char szLogonId[128] = "";
+     NETRESOURCE nr;
+     DWORD res;
+     DWORD gle;
+     DWORD dwSize;
+     DWORD dwDisp;
+     DWORD dwType;
+     DWORD count;
+     VOID * ticketData;
+     char filename[256];
+     char commandline[512];
+     STARTUPINFO startupinfo;
+     PROCESS_INFORMATION procinfo;
+ 
+     LUID LogonId = {0, 0};
+     PSECURITY_LOGON_SESSION_DATA pLogonSessionData = NULL;
+ 
+     HKEY hKey1 = NULL, hKey2 = NULL;
+ 
+     /* Make sure the KFW Libraries are initialized */
+     AfsLogonInit();
+ 
+     DebugEvent0("KFW_Logon_Event - Start");
+ 
+     GetSecurityLogonSessionData( pInfo->hToken, &pLogonSessionData );
+ 
+     if ( pLogonSessionData ) {
+         LogonId = pLogonSessionData->LogonId;
+         DebugEvent("KFW_Logon_Event - LogonId(%d,%d)", LogonId.HighPart, LogonId.LowPart);
+ 
+         sprintf(szLogonId,"%d.%d",LogonId.HighPart, LogonId.LowPart);
+         LsaFreeReturnBuffer( pLogonSessionData );
+     } else {
+         DebugEvent0("KFW_Logon_Event - Unable to determine LogonId");
+         return;
+     }
+ 
+     count = GetEnvironmentVariable("TEMP", filename, sizeof(filename));
+     if ( count > sizeof(filename) || count == 0 ) {
+         GetWindowsDirectory(filename, sizeof(filename));
+     }
+ 
+     if ( strlen(filename) + strlen(szLogonId) + 2 <= sizeof(filename) ) {
+         strcat(filename, "\\");
+         strcat(filename, szLogonId);    
+ 
+         sprintf(commandline, "afscpcc.exe \"%s\"", filename);
+ 
+         GetStartupInfo(&startupinfo);
+         if (CreateProcessAsUser( pInfo->hToken,
+                              "afscpcc.exe",
+                              commandline,
+                              NULL,
+                              NULL,
+                              FALSE,
+                              CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS,
+                              NULL,
+                              NULL,
+                              &startupinfo,
+                              &procinfo)) 
+         {
+             WaitForSingleObject(procinfo.hProcess, 30000);
+ 
+             CloseHandle(procinfo.hThread);
+             CloseHandle(procinfo.hProcess);
+         }
+     }
+ 
+     DeleteFile(filename);
+ 
+     DebugEvent0("KFW_Logon_Event - End");
+ }
+ 
Index: openafs/src/WINNT/afsd/afslogon.def
diff -c openafs/src/WINNT/afsd/afslogon.def:1.3.2.1 openafs/src/WINNT/afsd/afslogon.def:1.3.2.2
*** openafs/src/WINNT/afsd/afslogon.def:1.3.2.1	Thu Apr 28 08:05:19 2005
--- openafs/src/WINNT/afsd/afslogon.def	Sun May 29 23:52:52 2005
***************
*** 11,15 ****
--- 11,17 ----
      AFS_Startup_Event
      AFS_Logoff_Event
      AFS_Logon_Event
+     KFW_Logon_Event
+ 
  
  
Index: openafs/src/WINNT/afsd/cm_buf.c
diff -c openafs/src/WINNT/afsd/cm_buf.c:1.13.2.8 openafs/src/WINNT/afsd/cm_buf.c:1.13.2.9
*** openafs/src/WINNT/afsd/cm_buf.c:1.13.2.8	Fri Mar 11 01:58:39 2005
--- openafs/src/WINNT/afsd/cm_buf.c	Sun May 29 23:52:52 2005
***************
*** 592,598 ****
          }
  
          /* we better find it */
!         osi_assertx(tbp != NULL, "buf_GetNewLocked: hash table screwup");
  
          *lbpp = bp->hashp;	/* hash out */
  
--- 592,598 ----
          }
  
          /* we better find it */
!         osi_assertx(tbp != NULL, "buf_Recycle: hash table screwup");
  
          *lbpp = bp->hashp;	/* hash out */
  
***************
*** 806,814 ****
      pageOffset.HighPart = offsetp->HighPart;
      pageOffset.LowPart = offsetp->LowPart & ~(cm_data.buf_blockSize-1);
      while (1) {
!         lock_ObtainWrite(&buf_globalLock);
!         bp = buf_LockedFind(scp, &pageOffset);
!         lock_ReleaseWrite(&buf_globalLock);
          if (bp) {
              /* lock it and break out */
              lock_ObtainMutex(&bp->mx);
--- 806,812 ----
      pageOffset.HighPart = offsetp->HighPart;
      pageOffset.LowPart = offsetp->LowPart & ~(cm_data.buf_blockSize-1);
      while (1) {
!         bp = buf_Find(scp, &pageOffset);
          if (bp) {
              /* lock it and break out */
              lock_ObtainMutex(&bp->mx);
***************
*** 848,853 ****
--- 846,852 ----
  }
  
  /* get a page, returning it held but unlocked.  Make sure it is complete */
+ /* The scp must be unlocked when passed to this function */
  long buf_Get(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp)
  {
      cm_buf_t *bp;
***************
*** 869,877 ****
          buf_ValidateBufQueues();
  #endif /* TESTING */
  
!         lock_ObtainWrite(&buf_globalLock);
!         bp = buf_LockedFind(scp, &pageOffset);
!         lock_ReleaseWrite(&buf_globalLock);
          if (bp) {
              /* lock it and break out */
              lock_ObtainMutex(&bp->mx);
--- 868,874 ----
          buf_ValidateBufQueues();
  #endif /* TESTING */
  
!         bp = buf_Find(scp, &pageOffset);
          if (bp) {
              /* lock it and break out */
              lock_ObtainMutex(&bp->mx);
Index: openafs/src/WINNT/afsd/cm_config.c
diff -c openafs/src/WINNT/afsd/cm_config.c:1.20.2.2 openafs/src/WINNT/afsd/cm_config.c:1.20.2.3
*** openafs/src/WINNT/afsd/cm_config.c:1.20.2.2	Fri Mar 11 01:58:40 2005
--- openafs/src/WINNT/afsd/cm_config.c	Sun May 29 23:52:53 2005
***************
*** 201,206 ****
--- 201,207 ----
  	int tracking = 1, partial = 0;
  #if defined(DJGPP) || defined(AFS_WIN95_ENV)
      char *afsconf_path;
+     DWORD dwSize;
  #endif
  
      cm_GetCellServDB(wdir);
***************
*** 212,222 ****
          /* If we are in Win95 here, we are linking with klog etc. and are
          using DJGPP client even though DJGPP is not defined.  So we still
          need to check AFSCONF for location. */
!         afsconf_path = getenv("AFSCONF");
          if (!afsconf_path)
              strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
!         else
              strcpy(wdir, afsconf_path);
          strcat(wdir, "/");
          strcat(wdir, AFS_CELLSERVDB);
          /*fprintf(stderr, "opening cellservdb file %s\n", wdir);*/
--- 213,227 ----
          /* If we are in Win95 here, we are linking with klog etc. and are
          using DJGPP client even though DJGPP is not defined.  So we still
          need to check AFSCONF for location. */
!         dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0);
!         afsconf_path = malloc(dwSize);
!         dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize);
          if (!afsconf_path)
              strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
!         else {
              strcpy(wdir, afsconf_path);
+             free(afsconf_path);
+         }
          strcat(wdir, "/");
          strcat(wdir, AFS_CELLSERVDB);
          /*fprintf(stderr, "opening cellservdb file %s\n", wdir);*/
***************
*** 485,501 ****
          FILE *thisCell;
          char thisCellPath[256];
          char *newline;
  
  #ifdef DJGPP
          strcpy(thisCellPath, cm_confDir);
  #else
          /* Win 95 */
          char *afsconf_path;
!         afsconf_path = getenv("AFSCONF");
          if (!afsconf_path)
            strcpy(thisCellPath, AFSDIR_CLIENT_ETC_DIRPATH);
!         else
            strcpy(thisCellPath, afsconf_path);
  #endif
          strcat(thisCellPath,"/");
  
--- 490,511 ----
          FILE *thisCell;
          char thisCellPath[256];
          char *newline;
+         DWORD dwSize;
  
  #ifdef DJGPP
          strcpy(thisCellPath, cm_confDir);
  #else
          /* Win 95 */
          char *afsconf_path;
!         dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0);
!         afsconf_path = malloc(dwSize);
!         dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize);
          if (!afsconf_path)
            strcpy(thisCellPath, AFSDIR_CLIENT_ETC_DIRPATH);
!         else {
            strcpy(thisCellPath, afsconf_path);
+           free(afsconf_path);
+         }
  #endif
          strcat(thisCellPath,"/");
  
***************
*** 532,542 ****
  #ifdef DJGPP
          strcpy(wdir,cm_confDir);
  #else
!         char *afsconf_path = getenv("AFSCONF");
          if (!afsconf_path)
!           strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
!         else
!           strcpy(wdir, afsconf_path);
  #endif /* !DJGPP */
          strcat(wdir,"/");
  #endif /* DJGPP || WIN95 */
--- 542,560 ----
  #ifdef DJGPP
          strcpy(wdir,cm_confDir);
  #else
!         DWORD dwSize;
!         char *afsconf_path;
!     
!         dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0);
!         afsconf_path = malloc(dwSize);
!         dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize);
! 
          if (!afsconf_path)
!             strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
!         else {
!             strcpy(wdir, afsconf_path);
!             free(afsconf_path);
!         }
  #endif /* !DJGPP */
          strcat(wdir,"/");
  #endif /* DJGPP || WIN95 */
***************
*** 682,694 ****
  
  long cm_CloseCellFile(cm_configFile_t *filep)
  {
! 	char wdir[256];
      char sdir[256];
      long code;
      long closeCode;
      int tlen;
  #ifdef AFS_WIN95_ENV
      char *afsconf_path;
  #endif
  	closeCode = fclose((FILE *)filep);
  
--- 700,713 ----
  
  long cm_CloseCellFile(cm_configFile_t *filep)
  {
!     char wdir[256];
      char sdir[256];
      long code;
      long closeCode;
      int tlen;
  #ifdef AFS_WIN95_ENV
      char *afsconf_path;
+     DWORD dwSize;
  #endif
  	closeCode = fclose((FILE *)filep);
  
***************
*** 702,712 ****
  #ifdef DJGPP
      strcpy(wdir,cm_confDir);
  #else
!     afsconf_path = getenv("AFSCONF");
      if (!afsconf_path)
          strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
!     else
          strcpy(wdir, afsconf_path);
  #endif /* !DJGPP */
      strcat(wdir,"/");
  #endif /* DJGPP || WIN95 */
--- 721,735 ----
  #ifdef DJGPP
      strcpy(wdir,cm_confDir);
  #else
!     dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0);
!     afsconf_path = malloc(dwSize);
!     dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize);
      if (!afsconf_path)
          strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
!     else {
          strcpy(wdir, afsconf_path);
+         free(afsconf_path);
+     }
  #endif /* !DJGPP */
      strcat(wdir,"/");
  #endif /* DJGPP || WIN95 */
***************
*** 739,744 ****
--- 762,768 ----
      int tlen;
  #ifdef AFS_WIN95_ENV
      char *afsconf_path;
+     DWORD dwSize;
  #endif
  
  #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
***************
*** 751,761 ****
  #ifdef DJGPP
      strcpy(wdir,cm_confDir);
  #else
!     afsconf_path = getenv("AFSCONF");
      if (!afsconf_path)
          strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
!     else
          strcpy(wdir, afsconf_path);
  #endif /* !DJGPP */
      strcat(wdir,"\\");
  #endif /* DJGPP || WIN95 */
--- 775,789 ----
  #ifdef DJGPP
      strcpy(wdir,cm_confDir);
  #else
!     dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0);
!     afsconf_path = malloc(dwSize);
!     dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize);
      if (!afsconf_path)
          strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
!     else {
          strcpy(wdir, afsconf_path);
+         free(afsconf_path);
+     }
  #endif /* !DJGPP */
      strcat(wdir,"\\");
  #endif /* DJGPP || WIN95 */
Index: openafs/src/WINNT/afsd/cm_conn.c
diff -c openafs/src/WINNT/afsd/cm_conn.c:1.25.2.8 openafs/src/WINNT/afsd/cm_conn.c:1.25.2.9
*** openafs/src/WINNT/afsd/cm_conn.c:1.25.2.8	Wed Mar 30 15:50:15 2005
--- openafs/src/WINNT/afsd/cm_conn.c	Wed May 18 18:57:08 2005
***************
*** 378,384 ****
          if ( timeLeft > 2 )
              retry = 1;
      }
!     else if (errorCode == RXKADEXPIRED) {
          if (!dead_session) {
              lock_ObtainMutex(&userp->mx);
              ucellp = cm_GetUCell(userp, serverp->cellp);
--- 378,385 ----
          if ( timeLeft > 2 )
              retry = 1;
      }
!     else if (errorCode == RXKADEXPIRED || 
!              errorCode == RXKADBADTICKET) {
          if (!dead_session) {
              lock_ObtainMutex(&userp->mx);
              ucellp = cm_GetUCell(userp, serverp->cellp);
***************
*** 393,400 ****
                  retry = 1;
          }
      } else {
!         if (errorCode)
!             osi_Log1(afsd_logp, "cm_Analyze: ignoring error code 0x%x", errorCode);
      }
  
      if (retry && dead_session)
--- 394,419 ----
                  retry = 1;
          }
      } else {
!         if (errorCode) {
!             char * s = "unknown error";
!             switch ( errorCode ) {
!             case RXKADINCONSISTENCY: s = "RXKADINCONSISTENCY"; break;
!             case RXKADPACKETSHORT  : s = "RXKADPACKETSHORT  "; break;
!             case RXKADLEVELFAIL    : s = "RXKADLEVELFAIL    "; break;
!             case RXKADTICKETLEN    : s = "RXKADTICKETLEN    "; break;
!             case RXKADOUTOFSEQUENCE: s = "RXKADOUTOFSEQUENCE"; break;
!             case RXKADNOAUTH       : s = "RXKADNOAUTH       "; break;
!             case RXKADBADKEY       : s = "RXKADBADKEY       "; break;
!             case RXKADBADTICKET    : s = "RXKADBADTICKET    "; break;
!             case RXKADUNKNOWNKEY   : s = "RXKADUNKNOWNKEY   "; break;
!             case RXKADEXPIRED      : s = "RXKADEXPIRED      "; break;
!             case RXKADSEALEDINCON  : s = "RXKADSEALEDINCON  "; break;
!             case RXKADDATALEN      : s = "RXKADDATALEN      "; break;
!             case RXKADILLEGALLEVEL : s = "RXKADILLEGALLEVEL "; break;
!             }
!             osi_Log2(afsd_logp, "cm_Analyze: ignoring error code 0x%x (%s)", 
!                      errorCode, s);
!         }
      }
  
      if (retry && dead_session)
Index: openafs/src/WINNT/afsd/cm_dcache.c
diff -c openafs/src/WINNT/afsd/cm_dcache.c:1.11.2.8 openafs/src/WINNT/afsd/cm_dcache.c:1.11.2.11
*** openafs/src/WINNT/afsd/cm_dcache.c:1.11.2.8	Thu Mar 31 01:05:47 2005
--- openafs/src/WINNT/afsd/cm_dcache.c	Tue May 31 16:34:26 2005
***************
*** 727,733 ****
--- 727,735 ----
              break;
  
          /* try to lock it, and quit if we can't (simplifies locking) */
+         lock_ReleaseMutex(&scp->mx);
          code = lock_TryMutex(&bufp->mx);
+         lock_ObtainMutex(&scp->mx);
          if (code == 0) {
              buf_Release(bufp);
              break;
***************
*** 781,787 ****
--- 783,791 ----
              break;
  
          /* try to lock it, and quit if we can't (simplifies locking) */
+         lock_ReleaseMutex(&scp->mx);
          code = lock_TryMutex(&bufp->mx);
+         lock_ObtainMutex(&scp->mx);
          if (code == 0) {
              buf_Release(bufp);
              break;
***************
*** 890,916 ****
       * sequence at a time.
       */
  
      /* first hold all buffers, since we can't hold any locks in buf_Get */
      while (1) {
          /* stop at chunk boundary */
!         if (collected >= cm_chunkSize) break;
                  
          /* see if the next page would be past EOF */
!         if (LargeIntegerGreaterThanOrEqualTo(pageBase, fileSize)) break;
! 
!         lock_ObtainMutex(&cm_bufGetMutex);
  
          code = buf_Get(scp, &pageBase, &tbp);
          if (code) {
              lock_ReleaseMutex(&cm_bufGetMutex);
              lock_ObtainMutex(&scp->mx);
              return code;
          }
                  
          buf_Release(tbp);
  
-         lock_ReleaseMutex(&cm_bufGetMutex);
- 
          toffset.HighPart = 0;
          toffset.LowPart = cm_data.buf_blockSize;
          pageBase = LargeIntegerAdd(toffset, pageBase);
--- 894,920 ----
       * sequence at a time.
       */
  
+     // lock_ObtainMutex(&cm_bufGetMutex);
      /* first hold all buffers, since we can't hold any locks in buf_Get */
      while (1) {
          /* stop at chunk boundary */
!         if (collected >= cm_chunkSize) 
!             break;
                  
          /* see if the next page would be past EOF */
!         if (LargeIntegerGreaterThanOrEqualTo(pageBase, fileSize)) 
!             break;
  
          code = buf_Get(scp, &pageBase, &tbp);
          if (code) {
              lock_ReleaseMutex(&cm_bufGetMutex);
              lock_ObtainMutex(&scp->mx);
+             cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
              return code;
          }
                  
          buf_Release(tbp);
  
          toffset.HighPart = 0;
          toffset.LowPart = cm_data.buf_blockSize;
          pageBase = LargeIntegerAdd(toffset, pageBase);
***************
*** 920,925 ****
--- 924,931 ----
      /* reserve a chunk's worth of buffers if possible */
      reserving = buf_TryReserveBuffers(cm_chunkSize / cm_data.buf_blockSize);
  
+     // lock_ReleaseMutex(&cm_bufGetMutex);
+ 
      pageBase = *offsetp;
      collected = pageBase.LowPart & (cm_chunkSize - 1);
  
***************
*** 1376,1381 ****
--- 1382,1390 ----
      code = cm_MapRPCError(code, reqp);
  
      lock_ObtainMutex(&scp->mx);
+     
+     cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_FETCHSTATUS);
+ 
      /* we know that no one else has changed the buffer, since we still have
       * the fetching flag on the buffers, and we have the scp locked again.
       * Copy in the version # into the buffer if we got code 0 back from the
Index: openafs/src/WINNT/afsd/cm_dnlc.c
diff -c openafs/src/WINNT/afsd/cm_dnlc.c:1.5.2.2 openafs/src/WINNT/afsd/cm_dnlc.c:1.5.2.3
*** openafs/src/WINNT/afsd/cm_dnlc.c:1.5.2.2	Fri Mar 11 01:58:41 2005
--- openafs/src/WINNT/afsd/cm_dnlc.c	Wed May 18 18:57:08 2005
***************
*** 54,59 ****
--- 54,60 ----
  #define dnlcNotify(x,debug)
  #endif /* !DJGPP */
  
+ /* Must be called with cm_dnlcLock write locked */
  static cm_nc_t * 
  GetMeAnEntry() 
  {
***************
*** 332,339 ****
  	tnc->next->prev = tnc->prev;
      }
  
!     tnc->prev = (cm_nc_t *) 0; /* everything not in hash table has 0 prev */
!     tnc->key = 0; /* just for safety's sake */
      return 0;	  /* success */
  }
  
--- 333,340 ----
  	tnc->next->prev = tnc->prev;
      }
  
!     memset(tnc, 0, sizeof(cm_nc_t));
!     tnc->magic = CM_DNLC_MAGIC;
      return 0;	  /* success */
  }
  
***************
*** 368,374 ****
  	if ( (tnc->dirp == adp) && (tnc->key == key) 
  			&& !strcmp(tnc->name,aname) )
  	{
- 	    tnc->dirp = (cm_scache_t *) 0; /* now it won't match anything */
  	    tmp = tnc->next;
      	    error = RemoveEntry(tnc, skey);
  	    if ( error )
--- 369,374 ----
***************
*** 376,382 ****
  
  	    tnc->next = cm_data.ncfreelist; /* insert entry into freelist */
  	    cm_data.ncfreelist = tnc;
! 	    found = 1;		/* found atleast one entry */
  
  	    tnc = tmp;		/* continue down the linked list */
  	}
--- 376,382 ----
  
  	    tnc->next = cm_data.ncfreelist; /* insert entry into freelist */
  	    cm_data.ncfreelist = tnc;
! 	    found = 1;		/* found at least one entry */
  
  	    tnc = tmp;		/* continue down the linked list */
  	}
***************
*** 426,438 ****
      {
  	if (cm_data.nameCache[i].dirp == adp ) 
  	{
! 	    cm_data.nameCache[i].dirp = cm_data.nameCache[i].vp = (cm_scache_t *) 0;
! 	    if (cm_data.nameCache[i].prev && !err) 
! 	    {
! 		err = RemoveEntry(&cm_data.nameCache[i], cm_data.nameCache[i].key & (NHSIZE-1));
! 		cm_data.nameCache[i].next = cm_data.ncfreelist;
! 		cm_data.ncfreelist = &cm_data.nameCache[i];
! 	    }
  	}
      }
      lock_ReleaseWrite(&cm_dnlcLock);
--- 426,441 ----
      {
  	if (cm_data.nameCache[i].dirp == adp ) 
  	{
! 	    if (cm_data.nameCache[i].prev) {
!                 err = RemoveEntry(&cm_data.nameCache[i], cm_data.nameCache[i].key & (NHSIZE-1));
!                 if (!err)
!                 {
!                     cm_data.nameCache[i].next = cm_data.ncfreelist;
!                     cm_data.ncfreelist = &cm_data.nameCache[i];
!                 }
! 	    } else {
!                 cm_data.nameCache[i].dirp = cm_data.nameCache[i].vp = (cm_scache_t *) 0;
!             }
  	}
      }
      lock_ReleaseWrite(&cm_dnlcLock);
***************
*** 461,475 ****
      {
     	if (cm_data.nameCache[i].vp == avc) 
  	{
! 	    cm_data.nameCache[i].dirp = cm_data.nameCache[i].vp = (cm_scache_t *) 0;
! 	    /* can't simply break; because of hard links -- might be two */
! 	    /* different entries with same vnode */ 
! 	    if (!err && cm_data.nameCache[i].prev) 
! 	    {
! 		err=RemoveEntry(&cm_data.nameCache[i], cm_data.nameCache[i].key & (NHSIZE-1));
! 		cm_data.nameCache[i].next = cm_data.ncfreelist;
! 		cm_data.ncfreelist = &cm_data.nameCache[i];
! 	    }
  	}
      }
      lock_ReleaseWrite(&cm_dnlcLock);
--- 464,479 ----
      {
     	if (cm_data.nameCache[i].vp == avc) 
  	{
! 	    if (cm_data.nameCache[i].prev) {
!                 err = RemoveEntry(&cm_data.nameCache[i], cm_data.nameCache[i].key & (NHSIZE-1));
!                 if (!err)
!                 {
!                     cm_data.nameCache[i].next = cm_data.ncfreelist;
!                     cm_data.ncfreelist = &cm_data.nameCache[i];
!                 }
! 	    } else {
!                 cm_data.nameCache[i].dirp = cm_data.nameCache[i].vp = (cm_scache_t *) 0;
!             }
  	}
      }
      lock_ReleaseWrite(&cm_dnlcLock);
***************
*** 494,503 ****
      cm_data.ncfreelist = (cm_nc_t *) 0;
      memset (cm_data.nameCache, 0, sizeof(cm_nc_t) * NCSIZE);
      memset (cm_data.nameHash, 0, sizeof(cm_nc_t *) * NHSIZE);
!     for (i=0; i<NCSIZE; i++) 
      {
! 	cm_data.nameCache[i].next = cm_data.ncfreelist;
! 	cm_data.ncfreelist = &cm_data.nameCache[i];
      }
      lock_ReleaseWrite(&cm_dnlcLock);
     
--- 498,508 ----
      cm_data.ncfreelist = (cm_nc_t *) 0;
      memset (cm_data.nameCache, 0, sizeof(cm_nc_t) * NCSIZE);
      memset (cm_data.nameHash, 0, sizeof(cm_nc_t *) * NHSIZE);
!     for (i=0; i<NCSIZE; i++)
      {
!         cm_data.nameCache[i].magic = CM_DNLC_MAGIC;
!         cm_data.nameCache[i].next = cm_data.ncfreelist;
!         cm_data.ncfreelist = &cm_data.nameCache[i];
      }
      lock_ReleaseWrite(&cm_dnlcLock);
     
***************
*** 519,558 ****
  long
  cm_dnlcValidate(void)
  {
!     int i;
      cm_nc_t * ncp;
!     
      // are all nameCache entries marked with the magic bit?
      for (i=0; i<NCSIZE; i++)
      {
          if (cm_data.nameCache[i].magic != CM_DNLC_MAGIC) {
              afsi_log("cm_dnlcValidate failure: cm_data.nameCache[%d].magic != CM_DNLC_MAGIC", i);
              fprintf(stderr, "cm_dnlcValidate failure: cm_data.nameCache[%d].magic != CM_DNLC_MAGIC\n", i);
!             return -1;
          }
          if (cm_data.nameCache[i].next &&
              cm_data.nameCache[i].next->magic != CM_DNLC_MAGIC) {
              afsi_log("cm_dnlcValidate failure: cm_data.nameCache[%d].next->magic != CM_DNLC_MAGIC", i);
              fprintf(stderr, "cm_dnlcValidate failure: cm_data.nameCache[%d].next->magic != CM_DNLC_MAGIC\n", i);
!             return -2;
          }
          if (cm_data.nameCache[i].prev &&
              cm_data.nameCache[i].prev->magic != CM_DNLC_MAGIC) {
              afsi_log("cm_dnlcValidate failure: cm_data.nameCache[%d].prev->magic != CM_DNLC_MAGIC", i);
              fprintf(stderr, "cm_dnlcValidate failure: cm_data.nameCache[%d].prev->magic != CM_DNLC_MAGIC\n", i);
!             return -3;
          }
          if (cm_data.nameCache[i].dirp &&
              cm_data.nameCache[i].dirp->magic != CM_SCACHE_MAGIC) {
              afsi_log("cm_dnlcValidate failure: cm_data.nameCache[%d].dirp->magic != CM_SCACHE_MAGIC", i);
              fprintf(stderr, "cm_dnlcValidate failure: cm_data.nameCache[%d].dirp->magic != CM_SCACHE_MAGIC\n", i);
!             return -4;
          }
          if (cm_data.nameCache[i].vp &&
              cm_data.nameCache[i].vp->magic != CM_SCACHE_MAGIC) {
              afsi_log("cm_dnlcValidate failure: cm_data.nameCache[%d].vp->magic != CM_SCACHE_MAGIC", i);
              fprintf(stderr, "cm_dnlcValidate failure: cm_data.nameCache[%d].vp->magic != CM_SCACHE_MAGIC\n", i);
!             return -5;
          }
      }
  
--- 524,564 ----
  long
  cm_dnlcValidate(void)
  {
!     int i, purged = 0;
      cm_nc_t * ncp;
! 
!   retry:
      // are all nameCache entries marked with the magic bit?
      for (i=0; i<NCSIZE; i++)
      {
          if (cm_data.nameCache[i].magic != CM_DNLC_MAGIC) {
              afsi_log("cm_dnlcValidate failure: cm_data.nameCache[%d].magic != CM_DNLC_MAGIC", i);
              fprintf(stderr, "cm_dnlcValidate failure: cm_data.nameCache[%d].magic != CM_DNLC_MAGIC\n", i);
!             goto purge;
          }
          if (cm_data.nameCache[i].next &&
              cm_data.nameCache[i].next->magic != CM_DNLC_MAGIC) {
              afsi_log("cm_dnlcValidate failure: cm_data.nameCache[%d].next->magic != CM_DNLC_MAGIC", i);
              fprintf(stderr, "cm_dnlcValidate failure: cm_data.nameCache[%d].next->magic != CM_DNLC_MAGIC\n", i);
!             goto purge;
          }
          if (cm_data.nameCache[i].prev &&
              cm_data.nameCache[i].prev->magic != CM_DNLC_MAGIC) {
              afsi_log("cm_dnlcValidate failure: cm_data.nameCache[%d].prev->magic != CM_DNLC_MAGIC", i);
              fprintf(stderr, "cm_dnlcValidate failure: cm_data.nameCache[%d].prev->magic != CM_DNLC_MAGIC\n", i);
!             goto purge;
          }
          if (cm_data.nameCache[i].dirp &&
              cm_data.nameCache[i].dirp->magic != CM_SCACHE_MAGIC) {
              afsi_log("cm_dnlcValidate failure: cm_data.nameCache[%d].dirp->magic != CM_SCACHE_MAGIC", i);
              fprintf(stderr, "cm_dnlcValidate failure: cm_data.nameCache[%d].dirp->magic != CM_SCACHE_MAGIC\n", i);
!             goto purge;
          }
          if (cm_data.nameCache[i].vp &&
              cm_data.nameCache[i].vp->magic != CM_SCACHE_MAGIC) {
              afsi_log("cm_dnlcValidate failure: cm_data.nameCache[%d].vp->magic != CM_SCACHE_MAGIC", i);
              fprintf(stderr, "cm_dnlcValidate failure: cm_data.nameCache[%d].vp->magic != CM_SCACHE_MAGIC\n", i);
!             goto purge;
          }
      }
  
***************
*** 563,616 ****
              if (ncp->magic != CM_DNLC_MAGIC) {
                  afsi_log("cm_dnlcValidate failure: ncp->magic != CM_DNLC_MAGIC");
                  fprintf(stderr, "cm_dnlcValidate failure: ncp->magic != CM_DNLC_MAGIC\n");
!                 return -6;
              }
              if (ncp->prev && ncp->prev->magic != CM_DNLC_MAGIC) {
                  afsi_log("cm_dnlcValidate failure: ncp->prev->magic != CM_DNLC_MAGIC");
                  fprintf(stderr, "cm_dnlcValidate failure: ncp->prev->magic != CM_DNLC_MAGIC\n");
!                 return -7;
              }
              if (ncp->dirp && ncp->dirp->magic != CM_SCACHE_MAGIC) {
                  afsi_log("cm_dnlcValidate failure: ncp->dirp->magic != CM_DNLC_MAGIC");
                  fprintf(stderr, "cm_dnlcValidate failure: ncp->dirp->magic != CM_DNLC_MAGIC\n");
!                 return -8;
              }
              if (ncp->vp && ncp->vp->magic != CM_SCACHE_MAGIC) {
                  afsi_log("cm_dnlcValidate failure: ncp->vp->magic != CM_DNLC_MAGIC");
                  fprintf(stderr, "cm_dnlcValidate failure: ncp->vp->magic != CM_DNLC_MAGIC\n");
!                 return -9;
              }
          }
      }
  
      // is the freelist stable?
      if ( cm_data.ncfreelist ) {
!         for (ncp = cm_data.ncfreelist; ncp; 
!              ncp = ncp->next != cm_data.ncfreelist ? ncp->next : NULL) {
              if (ncp->magic != CM_DNLC_MAGIC) {
                  afsi_log("cm_dnlcValidate failure: ncp->magic != CM_DNLC_MAGIC");
                  fprintf(stderr, "cm_dnlcValidate failure: ncp->magic != CM_DNLC_MAGIC\n");
!                 return -10;
              }
!             if (ncp->prev && ncp->prev->magic != CM_DNLC_MAGIC) {
!                 afsi_log("cm_dnlcValidate failure: ncp->prev->magic != CM_DNLC_MAGIC");
!                 fprintf(stderr, "cm_dnlcValidate failure: ncp->prev->magic != CM_DNLC_MAGIC\n");
!                 return -11;
              }
!             if (ncp->dirp && ncp->dirp->magic != CM_SCACHE_MAGIC) {
!                 afsi_log("cm_dnlcValidate failure: ncp->dirp->magic != CM_DNLC_MAGIC");
!                 fprintf(stderr, "cm_dnlcValidate failure: ncp->dirp->magic != CM_DNLC_MAGIC\n");
!                return -12;
              }
!             if (ncp->vp && ncp->vp->magic != CM_SCACHE_MAGIC) {
!                 afsi_log("cm_dnlcValidate failure: ncp->vp->magic != CM_DNLC_MAGIC");
!                 fprintf(stderr, "cm_dnlcValidate failure: ncp->vp->magic != CM_DNLC_MAGIC\n");
!                 return -13;
              }
          }
-     }
  
      return 0;
  }
  
  void 
--- 569,650 ----
              if (ncp->magic != CM_DNLC_MAGIC) {
                  afsi_log("cm_dnlcValidate failure: ncp->magic != CM_DNLC_MAGIC");
                  fprintf(stderr, "cm_dnlcValidate failure: ncp->magic != CM_DNLC_MAGIC\n");
!                 goto purge;
              }
              if (ncp->prev && ncp->prev->magic != CM_DNLC_MAGIC) {
                  afsi_log("cm_dnlcValidate failure: ncp->prev->magic != CM_DNLC_MAGIC");
                  fprintf(stderr, "cm_dnlcValidate failure: ncp->prev->magic != CM_DNLC_MAGIC\n");
!                 goto purge;
              }
              if (ncp->dirp && ncp->dirp->magic != CM_SCACHE_MAGIC) {
                  afsi_log("cm_dnlcValidate failure: ncp->dirp->magic != CM_DNLC_MAGIC");
                  fprintf(stderr, "cm_dnlcValidate failure: ncp->dirp->magic != CM_DNLC_MAGIC\n");
!                 goto purge;
              }
              if (ncp->vp && ncp->vp->magic != CM_SCACHE_MAGIC) {
                  afsi_log("cm_dnlcValidate failure: ncp->vp->magic != CM_DNLC_MAGIC");
                  fprintf(stderr, "cm_dnlcValidate failure: ncp->vp->magic != CM_DNLC_MAGIC\n");
!                 goto purge;
              }
          }
      }
  
      // is the freelist stable?
      if ( cm_data.ncfreelist ) {
!         for (ncp = cm_data.ncfreelist, i = 0; ncp && i < NCSIZE; 
!              ncp = ncp->next != cm_data.ncfreelist ? ncp->next : NULL, i++) {
              if (ncp->magic != CM_DNLC_MAGIC) {
                  afsi_log("cm_dnlcValidate failure: ncp->magic != CM_DNLC_MAGIC");
                  fprintf(stderr, "cm_dnlcValidate failure: ncp->magic != CM_DNLC_MAGIC\n");
!                 goto purge;
              }
!             if (ncp->prev) {
!                 afsi_log("cm_dnlcValidate failure: ncp->prev != NULL");
!                 fprintf(stderr, "cm_dnlcValidate failure: ncp->prev != NULL\n");
!                 goto purge;
              }
!             if (ncp->key) {
!                 afsi_log("cm_dnlcValidate failure: ncp->key != 0");
!                 fprintf(stderr, "cm_dnlcValidate failure: ncp->key != 0\n");
!                 goto purge;
              }
!             if (ncp->dirp) {
!                 afsi_log("cm_dnlcValidate failure: ncp->dirp != NULL");
!                 fprintf(stderr, "cm_dnlcValidate failure: ncp->dirp != NULL\n");
!                goto purge;
!             }
!             if (ncp->vp) {
!                 afsi_log("cm_dnlcValidate failure: ncp->vp != NULL");
!                 fprintf(stderr, "cm_dnlcValidate failure: ncp->vp != NULL\n");
!                 goto purge;
              }
          }
  
+         if ( i == NCSIZE && ncp ) {
+             afsi_log("cm_dnlcValidate failure: dnlc freeList corrupted");
+             fprintf(stderr, "cm_dnlcValidate failure: dnlc freeList corrupted\n");
+             goto purge;
+         }
+     }
      return 0;
+ 
+   purge:
+     if ( purged )
+         return -1;
+ 
+     afsi_log("cm_dnlcValidate information: purging");
+     fprintf(stderr, "cm_dnlcValidate information: purging\n");
+     cm_data.ncfreelist = (cm_nc_t *) 0;
+     memset (cm_data.nameCache, 0, sizeof(cm_nc_t) * NCSIZE);
+     memset (cm_data.nameHash, 0, sizeof(cm_nc_t *) * NHSIZE);
+     for (i=0; i<NCSIZE; i++)
+     {
+         cm_data.nameCache[i].magic = CM_DNLC_MAGIC;
+         cm_data.nameCache[i].next = cm_data.ncfreelist;
+         cm_data.ncfreelist = &cm_data.nameCache[i];
+     }
+     purged = 1;
+     goto retry;
  }
  
  void 
Index: openafs/src/WINNT/afsd/cm_ioctl.c
diff -c openafs/src/WINNT/afsd/cm_ioctl.c:1.33.2.11 openafs/src/WINNT/afsd/cm_ioctl.c:1.33.2.12
*** openafs/src/WINNT/afsd/cm_ioctl.c:1.33.2.11	Wed Mar 30 15:50:15 2005
--- openafs/src/WINNT/afsd/cm_ioctl.c	Sun May 29 23:52:53 2005
***************
*** 2317,2322 ****
--- 2317,2323 ----
      HANDLE hLogFile;
      char logfileName[MAX_PATH+1];
      char *cookie;
+     DWORD dwSize;
    
  #ifdef _DEBUG  
      static _CrtMemState memstate;
***************
*** 2325,2336 ****
      cm_SkipIoctlPath(ioctlp);
      memcpy(&inValue, ioctlp->inDatap, sizeof(long));
    
!     if (getenv("TEMP"))
!     {
!         strncpy(logfileName, getenv("TEMP"), MAX_PATH);
!         logfileName[MAX_PATH] = '\0';
!     }
!     else
      {
          GetWindowsDirectory(logfileName, sizeof(logfileName));
      }
--- 2326,2333 ----
      cm_SkipIoctlPath(ioctlp);
      memcpy(&inValue, ioctlp->inDatap, sizeof(long));
    
!     dwSize = GetEnvironmentVariable("TEMP", logfileName, sizeof(logfileName));
!     if ( dwSize == 0 || dwSize > sizeof(logfileName) )
      {
          GetWindowsDirectory(logfileName, sizeof(logfileName));
      }
Index: openafs/src/WINNT/afsd/cm_memmap.c
diff -c openafs/src/WINNT/afsd/cm_memmap.c:1.1.2.2 openafs/src/WINNT/afsd/cm_memmap.c:1.1.2.3
*** openafs/src/WINNT/afsd/cm_memmap.c:1.1.2.2	Tue Apr 19 01:11:17 2005
--- openafs/src/WINNT/afsd/cm_memmap.c	Wed May 18 18:57:08 2005
***************
*** 400,412 ****
      if (!cm_IsCacheValid()) {
          fprintf(stderr,"Cache file fails validation test\n");
          UnmapViewOfFile(config_data_p);
-         CloseHandle(hm);
          return CM_ERROR_INVAL;
      }
  
      fprintf(stderr,"Cache passes validation test\n");
      UnmapViewOfFile(config_data_p);
-     CloseHandle(hm);
      return 0;
  }
  
--- 400,410 ----
Index: openafs/src/WINNT/afsd/cm_vnodeops.c
diff -c openafs/src/WINNT/afsd/cm_vnodeops.c:1.19.2.16 openafs/src/WINNT/afsd/cm_vnodeops.c:1.19.2.18
*** openafs/src/WINNT/afsd/cm_vnodeops.c:1.19.2.16	Tue Apr 19 01:11:17 2005
--- openafs/src/WINNT/afsd/cm_vnodeops.c	Tue May 31 13:36:57 2005
***************
*** 1635,1642 ****
                       CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_DIRSEARCH,
                       userp, NULL, reqp, outScpp);
  
! 	if (code == CM_ERROR_NOSUCHFILE)
! 		code = CM_ERROR_NOSUCHPATH;
  
      /* this stuff is allocated no matter what happened on the namei call,
       * so free it */
--- 1635,1642 ----
                       CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_DIRSEARCH,
                       userp, NULL, reqp, outScpp);
  
!     if (code == CM_ERROR_NOSUCHFILE)
!         code = CM_ERROR_NOSUCHPATH;
  
      /* this stuff is allocated no matter what happened on the namei call,
       * so free it */
***************
*** 2599,2606 ****
--- 2599,2608 ----
                  lock_ReleaseMutex(&newDscp->mx);
                  if (code) {
                      /* cleanup first one */
+                     lock_ObtainMutex(&newDscp->mx);
                      cm_SyncOpDone(oldDscp, NULL,
                                     CM_SCACHESYNC_STOREDATA);
+                     lock_ReleaseMutex(&oldDscp->mx);
                  }       
              }
          }
***************
*** 2619,2626 ****
--- 2621,2630 ----
                  lock_ReleaseMutex(&oldDscp->mx);
                  if (code) {
                      /* cleanup first one */
+                     lock_ObtainMutex(&newDscp->mx);
                      cm_SyncOpDone(newDscp, NULL,
                                     CM_SCACHESYNC_STOREDATA);
+                     lock_ReleaseMutex(&newDscp->mx);
                  }       
              }
          }
Index: openafs/src/WINNT/afsd/fs.c
diff -c openafs/src/WINNT/afsd/fs.c:1.16.2.6 openafs/src/WINNT/afsd/fs.c:1.16.2.7
*** openafs/src/WINNT/afsd/fs.c:1.16.2.6	Fri Mar 11 01:58:43 2005
--- openafs/src/WINNT/afsd/fs.c	Wed May 18 18:57:08 2005
***************
*** 60,65 ****
--- 60,66 ----
  
  static int MemDumpCmd(struct cmd_syndesc *asp, char *arock);
  static int CSCPolicyCmd(struct cmd_syndesc *asp, char *arock);
+ static int MiniDumpCmd(struct cmd_syndesc *asp, char *arock);
  
  extern afs_int32 VL_GetEntryByNameO();
  
***************
*** 3619,3639 ****
  {
      long code;
      struct ViceIoctl blob;
!     long inValue;
      long outValue;
!   
      if ((asp->parms[0].items && asp->parms[1].items)) {
          fprintf(stderr, "%s trace: must use at most one of '-begin' or '-end'\n", pn);
          return EINVAL;
      }
!   
      /* determine if we're turning this tracing on or off */
-     inValue = 0;
      if (asp->parms[0].items)
          inValue = 1;            /* begin */
!     else if (asp->parms[1].items) 
          inValue = 0;            /* end */
!   
      blob.in_size = sizeof(long);
      blob.in = (char *) &inValue;
      blob.out_size = sizeof(long);
--- 3620,3645 ----
  {
      long code;
      struct ViceIoctl blob;
!     long inValue = 0;
      long outValue;
! 
!     if ( !IsAdmin() ) {
!         fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n");
!         return EACCES;
!     }
! 
      if ((asp->parms[0].items && asp->parms[1].items)) {
          fprintf(stderr, "%s trace: must use at most one of '-begin' or '-end'\n", pn);
          return EINVAL;
      }
! 
      /* determine if we're turning this tracing on or off */
      if (asp->parms[0].items)
          inValue = 1;            /* begin */
!     else if (asp->parms[1].items)
          inValue = 0;            /* end */
! 
! 
      blob.in_size = sizeof(long);
      blob.in = (char *) &inValue;
      blob.out_size = sizeof(long);
***************
*** 3645,3654 ****
          return code;
      }
  
!     if (outValue) printf("AFS memdump begin.\n");
!     else printf("AFS memdump end.\n");
  
!     return 0;
  }
  
  static int
--- 3651,3705 ----
          return code;
      }
  
!     if (outValue) { 
!         printf("AFS memdump created.\n");
!         return 0;
!     } else {
!         printf("AFS memdump failed.\n");
!         return -1;
!     }
! }
  
! static int
! MiniDumpCmd(struct cmd_syndesc *asp, char *arock)
! {
!     long code;
!     BOOL success = 0;
!     SERVICE_STATUS status;
!     SC_HANDLE hManager = NULL;
!     SC_HANDLE hService = NULL;
! 
!     if ( !IsAdmin() ) {
!         fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n");
!         return EACCES;
!     }
! 
!     hManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
!     if (!hManager)
!         goto failure;
! 
!     hService = OpenService(hManager, "TransarcAFSDaemon", SERVICE_USER_DEFINED_CONTROL);
!     if (!hService)
!         goto failure;
! 
!     success = ControlService(hService, SERVICE_CONTROL_CUSTOM_DUMP, &status);
! 
!     if (success) {
!         CloseServiceHandle(hService);
!         CloseServiceHandle(hManager);
! 
!         printf("AFS minidump generated.\n");
!         return 0;
!     }
! 
!   failure: 
!     if (hService)
!         CloseServiceHandle(hService);
!     if (hManager)
!         CloseServiceHandle(hManager);
! 
!     printf("AFS minidump failed.\n");
!     return -1;
  }
  
  static int
***************
*** 3658,3663 ****
--- 3709,3719 ----
      char *share = NULL;
      HKEY hkCSCPolicy;
  
+     if ( !IsAdmin() ) {
+         fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n");
+         return EACCES;
+     }
+ 
      for(ti=asp->parms[0].items; ti;ti=ti->next) {
          share = ti->data;
          if (share)
***************
*** 4352,4357 ****
--- 4408,4415 ----
      cmd_AddParm(ts, "-documents", CMD_FLAG, CMD_OPTIONAL, "automatic caching of documents");
      cmd_AddParm(ts, "-disable", CMD_FLAG, CMD_OPTIONAL, "disable caching");
  
+     ts = cmd_CreateSyntax("minidump", MiniDumpCmd, 0, "Generate MiniDump of current service state");
+ 
      code = cmd_Dispatch(argc, argv);
  
  #ifndef WIN32
Index: openafs/src/WINNT/afsd/smb.c
diff -c openafs/src/WINNT/afsd/smb.c:1.55.2.22 openafs/src/WINNT/afsd/smb.c:1.55.2.23
*** openafs/src/WINNT/afsd/smb.c:1.55.2.22	Tue Apr 19 02:27:57 2005
--- openafs/src/WINNT/afsd/smb.c	Wed May 18 18:57:09 2005
***************
*** 1546,1552 ****
          /* Get the full name for this cell */
          code = cm_SearchCellFile(p, temp, 0, 0);
  #ifdef AFS_AFSDB_ENV
! 		if (code && cm_dnsEnabled) {
              int ttl;
              code = cm_SearchCellByDNS(p, temp, &ttl, 0, 0);
          }
--- 1546,1552 ----
          /* Get the full name for this cell */
          code = cm_SearchCellFile(p, temp, 0, 0);
  #ifdef AFS_AFSDB_ENV
!         if (code && cm_dnsEnabled) {
              int ttl;
              code = cm_SearchCellByDNS(p, temp, &ttl, 0, 0);
          }
***************
*** 1680,1686 ****
          lock_ReleaseMutex(&dsp->mx);
      }
      /* do this now to avoid spurious locking hierarchy creation */
!     if (scp) cm_ReleaseSCache(scp);
  }       
  
  void smb_ReleaseDirSearch(smb_dirSearch_t *dsp)
--- 1680,1687 ----
          lock_ReleaseMutex(&dsp->mx);
      }
      /* do this now to avoid spurious locking hierarchy creation */
!     if (scp) 
!         cm_ReleaseSCache(scp);
  }       
  
  void smb_ReleaseDirSearch(smb_dirSearch_t *dsp)
***************
*** 4780,4786 ****
                  else 
                      code = CM_ERROR_EXISTS;
                  cm_ReleaseSCache(tmpscp2);
! 				tmpscp2 = NULL;
              } else {
                  code = CM_ERROR_NOSUCHFILE;
              }
--- 4781,4787 ----
                  else 
                      code = CM_ERROR_EXISTS;
                  cm_ReleaseSCache(tmpscp2);
!                 tmpscp2 = NULL;
              } else {
                  code = CM_ERROR_NOSUCHFILE;
              }
Index: openafs/src/WINNT/afsd/smb3.c
diff -c openafs/src/WINNT/afsd/smb3.c:1.42.2.25 openafs/src/WINNT/afsd/smb3.c:1.42.2.27
*** openafs/src/WINNT/afsd/smb3.c:1.42.2.25	Tue Apr 19 01:11:18 2005
--- openafs/src/WINNT/afsd/smb3.c	Sun May 22 01:54:21 2005
***************
*** 5328,5333 ****
--- 5328,5335 ----
          fidflags |= SMB_FID_OPENREAD;
      if (desiredAccess & AFS_ACCESS_WRITE)
          fidflags |= SMB_FID_OPENWRITE;
+     if (createOptions & FILE_DELETE_ON_CLOSE)
+         fidflags |= SMB_FID_DELONCLOSE;
  
      code = 0;
  
***************
*** 5472,5479 ****
          if (!smb_IsLegalFilename(lastNamep)) {
              if (scp)
                  cm_ReleaseSCache(scp);
! 			if (dscp)
!             cm_ReleaseSCache(dscp);
              cm_ReleaseUser(userp);
              free(realPathp);
              return CM_ERROR_BADNTFILENAME;
--- 5474,5481 ----
          if (!smb_IsLegalFilename(lastNamep)) {
              if (scp)
                  cm_ReleaseSCache(scp);
!             if (dscp)
!                 cm_ReleaseSCache(dscp);
              cm_ReleaseUser(userp);
              free(realPathp);
              return CM_ERROR_BADNTFILENAME;
***************
*** 5492,5498 ****
                                   userp, &req, &scp);
              }
              if (code && code != CM_ERROR_NOSUCHFILE) {
!                 cm_ReleaseSCache(dscp);
                  cm_ReleaseUser(userp);
                  free(realPathp);
                  return code;
--- 5494,5501 ----
                                   userp, &req, &scp);
              }
              if (code && code != CM_ERROR_NOSUCHFILE) {
!                 if (dscp)
!                     cm_ReleaseSCache(dscp);
                  cm_ReleaseUser(userp);
                  free(realPathp);
                  return code;
***************
*** 5515,5521 ****
              /* oops, file shouldn't be there */
              if (dscp)
                  cm_ReleaseSCache(dscp);
!             cm_ReleaseSCache(scp);
              cm_ReleaseUser(userp);
              free(realPathp);
              return CM_ERROR_EXISTS;
--- 5518,5525 ----
              /* oops, file shouldn't be there */
              if (dscp)
                  cm_ReleaseSCache(dscp);
!             if (scp)
!                 cm_ReleaseSCache(scp);
              cm_ReleaseUser(userp);
              free(realPathp);
              return CM_ERROR_EXISTS;
***************
*** 5553,5559 ****
          if (code) {
              if (dscp)
                  cm_ReleaseSCache(dscp);
!             cm_ReleaseSCache(scp);
              cm_ReleaseUser(userp);
              free(realPathp);
              return code;
--- 5557,5564 ----
          if (code) {
              if (dscp)
                  cm_ReleaseSCache(dscp);
!             if (scp)
!                 cm_ReleaseSCache(scp);
              cm_ReleaseUser(userp);
              free(realPathp);
              return code;
***************
*** 5562,5569 ****
          /* don't create if not found */
          if (dscp)
              cm_ReleaseSCache(dscp);
! 		if (scp)
! 			cm_ReleaseSCache(scp);
          cm_ReleaseUser(userp);
          free(realPathp);
          return CM_ERROR_NOSUCHFILE;
--- 5567,5574 ----
          /* don't create if not found */
          if (dscp)
              cm_ReleaseSCache(dscp);
!         if (scp)
!             cm_ReleaseSCache(scp);
          cm_ReleaseUser(userp);
          free(realPathp);
          return CM_ERROR_NOSUCHFILE;
***************
*** 5736,5742 ****
      /* (only applies to single component case) */
      if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) {
          cm_ReleaseSCache(scp);
!         cm_ReleaseSCache(dscp);
          cm_ReleaseUser(userp);
          free(realPathp);
          return CM_ERROR_NOTDIR;
--- 5741,5748 ----
      /* (only applies to single component case) */
      if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) {
          cm_ReleaseSCache(scp);
!         if (dscp)
!             cm_ReleaseSCache(dscp);
          cm_ReleaseUser(userp);
          free(realPathp);
          return CM_ERROR_NOTDIR;
***************
*** 5985,5990 ****
--- 5991,5998 ----
          fidflags |= SMB_FID_OPENREAD;
      if (desiredAccess & AFS_ACCESS_WRITE)
          fidflags |= SMB_FID_OPENWRITE;
+     if (createOptions & FILE_DELETE_ON_CLOSE)
+         fidflags |= SMB_FID_DELONCLOSE;
  
      dscp = NULL;
      code = 0;
***************
*** 6111,6117 ****
          code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp,
                                 &req);
          if (code) {     
!             if (dscp) cm_ReleaseSCache(dscp);
              cm_ReleaseSCache(scp);
              cm_ReleaseUser(userp);
              free(realPathp);
--- 6119,6126 ----
          code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp,
                                 &req);
          if (code) {     
!             if (dscp) 
!                 cm_ReleaseSCache(dscp);
              cm_ReleaseSCache(scp);
              cm_ReleaseUser(userp);
              free(realPathp);
***************
*** 6120,6126 ****
  
          if (createDisp == FILE_CREATE) {
              /* oops, file shouldn't be there */
!             if (dscp) cm_ReleaseSCache(dscp);
              cm_ReleaseSCache(scp);
              cm_ReleaseUser(userp);
              free(realPathp);
--- 6129,6136 ----
  
          if (createDisp == FILE_CREATE) {
              /* oops, file shouldn't be there */
!             if (dscp) 
!                 cm_ReleaseSCache(dscp);
              cm_ReleaseSCache(scp);
              cm_ReleaseUser(userp);
              free(realPathp);
***************
*** 6156,6162 ****
      }
      else if (createDisp == FILE_OPEN || createDisp == FILE_OVERWRITE) {
          /* don't create if not found */
!         if (dscp) cm_ReleaseSCache(dscp);
          cm_ReleaseUser(userp);
          free(realPathp);
          return CM_ERROR_NOSUCHFILE;
--- 6166,6173 ----
      }
      else if (createDisp == FILE_OPEN || createDisp == FILE_OVERWRITE) {
          /* don't create if not found */
!         if (dscp) 
!             cm_ReleaseSCache(dscp);
          cm_ReleaseUser(userp);
          free(realPathp);
          return CM_ERROR_NOSUCHFILE;
***************
*** 6238,6244 ****
  
      if (code) {
          /* something went wrong creating or truncating the file */
!         if (scp) cm_ReleaseSCache(scp);
          cm_ReleaseUser(userp);
          free(realPathp);
          return code;
--- 6249,6256 ----
  
      if (code) {
          /* something went wrong creating or truncating the file */
!         if (scp) 
!             cm_ReleaseSCache(scp);
          cm_ReleaseUser(userp);
          free(realPathp);
          return code;
***************
*** 6297,6303 ****
      fidp->NTopen_wholepathp = realPathp;
  
      /* we don't need this any longer */
!     if (dscp) cm_ReleaseSCache(dscp);
  
      cm_Open(scp, 0, userp);
  
--- 6309,6316 ----
      fidp->NTopen_wholepathp = realPathp;
  
      /* we don't need this any longer */
!     if (dscp) 
!         cm_ReleaseSCache(dscp);
  
      cm_Open(scp, 0, userp);
  
Index: openafs/src/WINNT/afssvrmgr/NTMakefile
diff -c openafs/src/WINNT/afssvrmgr/NTMakefile:1.4.2.4 openafs/src/WINNT/afssvrmgr/NTMakefile:1.4.2.5
*** openafs/src/WINNT/afssvrmgr/NTMakefile:1.4.2.4	Fri Mar 11 01:59:32 2005
--- openafs/src/WINNT/afssvrmgr/NTMakefile	Wed May 18 18:22:41 2005
***************
*** 7,13 ****
  
  # make compiler warnings fatal
  
! AFSDEV_AUXCDEFINES = $(AFSDEV_AUXCDEFINES) -WX
  
  # allow the resource compiler to search the dest\include tree
  
--- 7,13 ----
  
  # make compiler warnings fatal
  
! AFSDEV_AUXCDEFINES = $(AFSDEV_AUXCDEFINES) -WX -I..\afsd -I..\client_config -I..\kfw\inc\krb5 
  
  # allow the resource compiler to search the dest\include tree
  
***************
*** 93,98 ****
--- 93,103 ----
  	shell32.lib
  
  EXELIBS = \
+ 	$(DESTDIR)\lib\afsauthent.lib \
+ 	$(DESTDIR)\lib\libafsconf.lib \
+         $(DESTDIR)\lib\afsrxkad.lib \
+         $(DESTDIR)\lib\afsdes.lib \
+         $(DESTDIR)\lib\afskfw.lib \
  	$(DESTDIR)\lib\afs\AfsClass.lib \
  	$(DESTDIR)\lib\afs\TaAfsAppLib.lib
  
Index: openafs/src/WINNT/afssvrmgr/creds.cpp
diff -c openafs/src/WINNT/afssvrmgr/creds.cpp:1.3 openafs/src/WINNT/afssvrmgr/creds.cpp:1.3.2.1
*** openafs/src/WINNT/afssvrmgr/creds.cpp:1.3	Thu Apr  1 14:38:37 2004
--- openafs/src/WINNT/afssvrmgr/creds.cpp	Wed May 18 18:57:10 2005
***************
*** 18,23 ****
--- 18,24 ----
  #include "time.h"
  #include "subset.h"
  
+ #include <afs\afskfw.h>
  
  /*
   * OPENCELL DIALOG ____________________________________________________________
***************
*** 91,118 ****
     TCHAR szPassword[ cchRESOURCE ];
     GetDlgItemText (hDlg, IDC_OPENCELL_PASSWORD, szPassword, cchNAME);
  
!    ULONG status;
!    if ((lpp->hCreds = AfsAppLib_SetCredentials (lpp->szCell, szUser, szPassword, &status)) == NULL)
!       {
!       ErrorDialog (status, IDS_SVR_ERROR_BAD_CREDENTIALS);
!       }
!    else
!       {
!       // See if those credentials are sufficient
!       //
!       CHECKCREDS_PARAMS pp;
!       memset (&pp, 0x00, sizeof(pp));
!       memcpy (&pp.bcdp, &lpp->bcdp, sizeof(BADCREDSDLG_PARAMS));
!       pp.bcdp.hParent = hDlg;
!       pp.hCreds = lpp->hCreds;
!       pp.fShowWarning = TRUE;
  
!       if ((rc = AfsAppLib_CheckCredentials (&pp)) == FALSE)
!          {
!          SetDlgItemText (hDlg, IDC_OPENCELL_ID, TEXT("admin"));
!          PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg,IDC_OPENCELL_PASSWORD), TRUE);
!          }
!       }
  
     if (rc)
        {
--- 92,144 ----
     TCHAR szPassword[ cchRESOURCE ];
     GetDlgItemText (hDlg, IDC_OPENCELL_PASSWORD, szPassword, cchNAME);
  
!     ULONG status;
  
!     if ( KFW_is_available() ) {
!         // KFW_AFS_get_cred() parses the szNameA field as complete 
!         // princial including potentially
!         // a different realm then the specified cell name.
!         char *Result = NULL;
!         
!         char szCellA[ 256 ];
!         CopyStringToAnsi (szCellA, lpp->szCell);
! 
!         char szUserA[ 256 ];
!         CopyStringToAnsi (szUserA, szUser);
! 
!         char szPasswordA[ 256 ];
!         CopyStringToAnsi (szPasswordA, szPassword);
! 
!         rc = !KFW_AFS_get_cred(szUserA, szCellA, szPasswordA, 0, NULL, &Result);
!         if (rc) {
!             if ((lpp->hCreds = AfsAppLib_GetCredentials (lpp->szCell, &status)) == NULL) {
!                 ErrorDialog (status, IDS_SVR_ERROR_BAD_CREDENTIALS);
!             }
!         }
!     } else {
!         if ((lpp->hCreds = AfsAppLib_SetCredentials (lpp->szCell, szUser, szPassword, &status)) == NULL)
!         {
!             ErrorDialog (status, IDS_SVR_ERROR_BAD_CREDENTIALS);
!         }
!         else
!         {
!             // See if those credentials are sufficient
!             //
!             CHECKCREDS_PARAMS pp;
!             memset (&pp, 0x00, sizeof(pp));
!             memcpy (&pp.bcdp, &lpp->bcdp, sizeof(BADCREDSDLG_PARAMS));
!             pp.bcdp.hParent = hDlg;
!             pp.hCreds = lpp->hCreds;
!             pp.fShowWarning = TRUE;
! 
!             if ((rc = AfsAppLib_CheckCredentials (&pp)) == FALSE)
!             {
!                 SetDlgItemText (hDlg, IDC_OPENCELL_ID, TEXT("admin"));
!                 PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg,IDC_OPENCELL_PASSWORD), TRUE);
!             }
!         }
! 
!     }
  
     if (rc)
        {
Index: openafs/src/WINNT/client_config/lang/de_DE/afs_config.rc
diff -c openafs/src/WINNT/client_config/lang/de_DE/afs_config.rc:1.3.2.1 openafs/src/WINNT/client_config/lang/de_DE/afs_config.rc:1.3.2.2
*** openafs/src/WINNT/client_config/lang/de_DE/afs_config.rc:1.3.2.1	Fri Mar 11 02:00:03 2005
--- openafs/src/WINNT/client_config/lang/de_DE/afs_config.rc	Fri Apr 29 15:56:03 2005
***************
*** 52,62 ****
      CONTROL         "&AFS-Token beim Anmelden bei Windows erhalten",
                      IDC_LOGON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,50,
                      193,10
-     CONTROL         "&Ein AFS Light Gateway bereitstellen",IDC_GATEWAY,
-                     "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,72,193,10
      CONTROL         "Das Symbol für den AFS Client in der Menüleiste &anzeigen",
!                     IDC_TRAYICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,95,
!                     194,10
      LTEXT           "Hinweis: Diese Steuerelemente sind gesperrt, weil der AFS Client-Service nicht aktiv ist.",
                      IDC_WARN,13,124,193,17
      GROUPBOX        "Client-Status",IDC_STATIC,7,157,206,61
--- 52,60 ----
      CONTROL         "&AFS-Token beim Anmelden bei Windows erhalten",
                      IDC_LOGON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,50,
                      193,10
      CONTROL         "Das Symbol für den AFS Client in der Menüleiste &anzeigen",
!                     IDC_TRAYICON,
!                     "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,72,193,10
      LTEXT           "Hinweis: Diese Steuerelemente sind gesperrt, weil der AFS Client-Service nicht aktiv ist.",
                      IDC_WARN,13,124,193,17
      GROUPBOX        "Client-Status",IDC_STATIC,7,157,206,61
Index: openafs/src/WINNT/client_config/lang/en_US/afs_config.rc
diff -c openafs/src/WINNT/client_config/lang/en_US/afs_config.rc:1.6 openafs/src/WINNT/client_config/lang/en_US/afs_config.rc:1.6.2.1
*** openafs/src/WINNT/client_config/lang/en_US/afs_config.rc:1.6	Sat Jul 31 20:20:34 2004
--- openafs/src/WINNT/client_config/lang/en_US/afs_config.rc	Fri Apr 29 15:56:07 2005
***************
*** 52,61 ****
      EDITTEXT        IDC_CELL,59,22,114,13,ES_LOWERCASE | ES_AUTOHSCROLL
      CONTROL         "&Obtain AFS tokens when logging into Windows",IDC_LOGON,
                      "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,50,193,10
!     CONTROL         "&Provide an AFS Light Gateway",IDC_GATEWAY,"Button",
                      BS_AUTOCHECKBOX | WS_TABSTOP,13,72,193,10
-     CONTROL         "S&how the AFS Client icon in the taskbar",IDC_TRAYICON,
-                     "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,95,193,10
      LTEXT           "Note: these controls are disabled because the AFS Client service is not running.",
                      IDC_WARN,13,124,193,17
      GROUPBOX        "Client Status",IDC_STATIC,7,157,206,61
--- 52,59 ----
      EDITTEXT        IDC_CELL,59,22,114,13,ES_LOWERCASE | ES_AUTOHSCROLL
      CONTROL         "&Obtain AFS tokens when logging into Windows",IDC_LOGON,
                      "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,50,193,10
!     CONTROL         "S&how the AFS Client icon in the taskbar",IDC_TRAYICON,"Button",
                      BS_AUTOCHECKBOX | WS_TABSTOP,13,72,193,10
      LTEXT           "Note: these controls are disabled because the AFS Client service is not running.",
                      IDC_WARN,13,124,193,17
      GROUPBOX        "Client Status",IDC_STATIC,7,157,206,61
Index: openafs/src/WINNT/client_config/lang/es_ES/afs_config.rc
diff -c openafs/src/WINNT/client_config/lang/es_ES/afs_config.rc:1.3.2.1 openafs/src/WINNT/client_config/lang/es_ES/afs_config.rc:1.3.2.2
*** openafs/src/WINNT/client_config/lang/es_ES/afs_config.rc:1.3.2.1	Fri Mar 11 02:00:06 2005
--- openafs/src/WINNT/client_config/lang/es_ES/afs_config.rc	Fri Apr 29 15:56:12 2005
***************
*** 52,62 ****
      CONTROL         "&Obtener señales de AFS al iniciar la sesión en Windows",
                      IDC_LOGON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,50,
                      193,10
-     CONTROL         "&Proporcionar una Pasarela de AFS Light",IDC_GATEWAY,
-                     "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,72,193,10
      CONTROL         "&Mostrar el icono AFS Client en la barra de tareas",
!                     IDC_TRAYICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,95,
!                     193,10
      LTEXT           "Nota: estos controles están inhabilitados porque el servicio de AFS Client no se está ejecutando. ",
                      IDC_WARN,13,124,193,17
      GROUPBOX        "Estado de cliente",IDC_STATIC,7,157,206,61
--- 52,60 ----
      CONTROL         "&Obtener señales de AFS al iniciar la sesión en Windows",
                      IDC_LOGON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,50,
                      193,10
      CONTROL         "&Mostrar el icono AFS Client en la barra de tareas",
!                     IDC_TRAYICON,
!                     "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,72,193,10
      LTEXT           "Nota: estos controles están inhabilitados porque el servicio de AFS Client no se está ejecutando. ",
                      IDC_WARN,13,124,193,17
      GROUPBOX        "Estado de cliente",IDC_STATIC,7,157,206,61
Index: openafs/src/WINNT/client_config/lang/ja_JP/afs_config.rc
diff -c openafs/src/WINNT/client_config/lang/ja_JP/afs_config.rc:1.3.2.1 openafs/src/WINNT/client_config/lang/ja_JP/afs_config.rc:1.3.2.2
*** openafs/src/WINNT/client_config/lang/ja_JP/afs_config.rc:1.3.2.1	Fri Mar 11 02:00:09 2005
--- openafs/src/WINNT/client_config/lang/ja_JP/afs_config.rc	Fri Apr 29 15:56:16 2005
***************
*** 52,62 ****
      CONTROL         "Windows ‚Ö‚ÌƒƒOƒCƒ“Žž‚É AFS ƒg[ƒNƒ“‚ðŽæ“¾(&O)",
                      IDC_LOGON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,50,
                      198,10
-     CONTROL         "AFS Light ƒQ[ƒgƒEƒFƒC‚ð’ñ‹Ÿ(&P)",IDC_GATEWAY,"Button",
-                     BS_AUTOCHECKBOX | WS_TABSTOP,11,72,193,10
      CONTROL         "ƒ^ƒXƒNƒo[‚ÉAFSƒNƒ‰ƒCƒAƒ“ƒgEƒAƒCƒRƒ“‚ð•\Ž¦(&H)",
!                     IDC_TRAYICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,95,
!                     201,10
      LTEXT           "’: AFS ƒNƒ‰ƒCƒAƒ“ƒgEƒT[ƒrƒX‚ªŽÀs‚³‚ê‚Ä‚¢‚È‚¢‚½‚ßA‚±‚ê‚ç‚Ì§Œä‚ÍŽg—p‚Å‚«‚Ü‚¹‚ñB",
                      IDC_WARN,13,124,193,17
      GROUPBOX        "ƒNƒ‰ƒCƒAƒ“ƒgó‹µ",IDC_STATIC,7,157,206,61
--- 52,61 ----
      CONTROL         "Windows ‚Ö‚ÌƒƒOƒCƒ“Žž‚É AFS ƒg[ƒNƒ“‚ðŽæ“¾(&O)",
                      IDC_LOGON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,50,
                      198,10
      CONTROL         "ƒ^ƒXƒNƒo[‚ÉAFSƒNƒ‰ƒCƒAƒ“ƒgEƒAƒCƒRƒ“‚ð•\Ž¦(&H)",
!                     IDC_TRAYICON,
!                     "Button",
!                     BS_AUTOCHECKBOX | WS_TABSTOP,11,72,193,10
      LTEXT           "’: AFS ƒNƒ‰ƒCƒAƒ“ƒgEƒT[ƒrƒX‚ªŽÀs‚³‚ê‚Ä‚¢‚È‚¢‚½‚ßA‚±‚ê‚ç‚Ì§Œä‚ÍŽg—p‚Å‚«‚Ü‚¹‚ñB",
                      IDC_WARN,13,124,193,17
      GROUPBOX        "ƒNƒ‰ƒCƒAƒ“ƒgó‹µ",IDC_STATIC,7,157,206,61
Index: openafs/src/WINNT/client_config/lang/ko_KR/afs_config.rc
diff -c openafs/src/WINNT/client_config/lang/ko_KR/afs_config.rc:1.3.2.1 openafs/src/WINNT/client_config/lang/ko_KR/afs_config.rc:1.3.2.2
*** openafs/src/WINNT/client_config/lang/ko_KR/afs_config.rc:1.3.2.1	Fri Mar 11 02:00:12 2005
--- openafs/src/WINNT/client_config/lang/ko_KR/afs_config.rc	Fri Apr 29 15:56:19 2005
***************
*** 51,61 ****
      EDITTEXT        IDC_CELL,59,22,114,13,ES_LOWERCASE | ES_AUTOHSCROLL
      CONTROL         "Windows·Î ·Î±×ÀÎÇÒ ¶§ AFS ÅäÅ« È®º¸(&O)",IDC_LOGON,
                      "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,50,193,10
-     CONTROL         "AFS ¶óÀÌÆ® °ÔÀÌÆ®¿þÀÌ Á¦°ø(&P)",IDC_GATEWAY,"Button",
-                     BS_AUTOCHECKBOX | WS_TABSTOP,13,72,193,10
      CONTROL         "ÀÛ¾÷ Ç¥½ÃÁÙ¿¡ AFS Å¬¶óÀÌ¾ðÆ® ¾ÆÀÌÄÜ Ç¥½Ã(&H)",
!                     IDC_TRAYICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,95,
!                     193,10
      LTEXT           "ÁÖ: ÀÌ Á¦¾î´Â AFS Å¬¶óÀÌ¾ðÆ® ¼­ºñ½º°¡ ½ÇÇà ÁßÀÌÁö ¾ÊÀ¸¹Ç·Î »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù.",
                      IDC_WARN,13,124,193,17
      GROUPBOX        "Å¬¶óÀÌ¾ðÆ® »óÅÂ",IDC_STATIC,7,157,206,61
--- 51,59 ----
      EDITTEXT        IDC_CELL,59,22,114,13,ES_LOWERCASE | ES_AUTOHSCROLL
      CONTROL         "Windows·Î ·Î±×ÀÎÇÒ ¶§ AFS ÅäÅ« È®º¸(&O)",IDC_LOGON,
                      "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,50,193,10
      CONTROL         "ÀÛ¾÷ Ç¥½ÃÁÙ¿¡ AFS Å¬¶óÀÌ¾ðÆ® ¾ÆÀÌÄÜ Ç¥½Ã(&H)",
!                     IDC_TRAYICON,"Button",
!                     BS_AUTOCHECKBOX | WS_TABSTOP,13,72,193,10
      LTEXT           "ÁÖ: ÀÌ Á¦¾î´Â AFS Å¬¶óÀÌ¾ðÆ® ¼­ºñ½º°¡ ½ÇÇà ÁßÀÌÁö ¾ÊÀ¸¹Ç·Î »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù.",
                      IDC_WARN,13,124,193,17
      GROUPBOX        "Å¬¶óÀÌ¾ðÆ® »óÅÂ",IDC_STATIC,7,157,206,61
Index: openafs/src/WINNT/client_config/lang/pt_BR/afs_config.rc
diff -c openafs/src/WINNT/client_config/lang/pt_BR/afs_config.rc:1.3.2.1 openafs/src/WINNT/client_config/lang/pt_BR/afs_config.rc:1.3.2.2
*** openafs/src/WINNT/client_config/lang/pt_BR/afs_config.rc:1.3.2.1	Fri Mar 11 02:00:15 2005
--- openafs/src/WINNT/client_config/lang/pt_BR/afs_config.rc	Fri Apr 29 15:56:22 2005
***************
*** 52,62 ****
      CONTROL         "&Obter tokens do AFS ao efetuar logon no Windows",
                      IDC_LOGON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,50,
                      193,10
-     CONTROL         "&Fornecer um Gateway do AFS Básico",IDC_GATEWAY,"Button",
-                     BS_AUTOCHECKBOX | WS_TABSTOP,13,72,193,10
      CONTROL         "&Mostrar o ícone do AFS Client na barra de tarefas",
!                     IDC_TRAYICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,95,
!                     193,10
      LTEXT           "Nota: estes controles estão desativados porque o serviço AFS Client não está sendo executado.",
                      IDC_WARN,13,124,193,17
      GROUPBOX        "Status do Cliente",IDC_STATIC,7,157,206,61
--- 52,60 ----
      CONTROL         "&Obter tokens do AFS ao efetuar logon no Windows",
                      IDC_LOGON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,50,
                      193,10
      CONTROL         "&Mostrar o ícone do AFS Client na barra de tarefas",
!                     IDC_TRAYICON,"Button",
!                     BS_AUTOCHECKBOX | WS_TABSTOP,13,72,193,10
      LTEXT           "Nota: estes controles estão desativados porque o serviço AFS Client não está sendo executado.",
                      IDC_WARN,13,124,193,17
      GROUPBOX        "Status do Cliente",IDC_STATIC,7,157,206,61
Index: openafs/src/WINNT/client_config/lang/zh_CN/afs_config.rc
diff -c openafs/src/WINNT/client_config/lang/zh_CN/afs_config.rc:1.4 openafs/src/WINNT/client_config/lang/zh_CN/afs_config.rc:1.4.2.1
*** openafs/src/WINNT/client_config/lang/zh_CN/afs_config.rc:1.4	Thu Feb 26 14:22:47 2004
--- openafs/src/WINNT/client_config/lang/zh_CN/afs_config.rc	Fri Apr 29 15:56:24 2005
***************
*** 51,60 ****
      EDITTEXT        IDC_CELL,62,22,114,13,ES_LOWERCASE | ES_AUTOHSCROLL
      CONTROL         "µÇÂ¼µ½ Windows Ê±»ñµÃ AFS ÁîÅÆ",IDC_LOGON,"Button",
                      BS_AUTOCHECKBOX | WS_TABSTOP,13,50,193,10
-     CONTROL         "Ìá¹© AFS Light Íø¹Ø(&P)",IDC_GATEWAY,"Button",
-                     BS_AUTOCHECKBOX | WS_TABSTOP,13,72,193,10
      CONTROL         "ÔÚÈÎÎñÀ¸ÖÐÏÔÊ¾ AFS ¿Í»§»úÍ¼±ê(&I)",IDC_TRAYICON,"Button",
!                     BS_AUTOCHECKBOX | WS_TABSTOP,13,95,193,10
      LTEXT           "×¢Òâ£ºÓÉÓÚÃ»ÓÐÔËÐÐ AFS ¿Í»§»ú·þÎñ£¬½«½ûÓÃÕâÐ©¿ØÖÆ¡£",
                      IDC_WARN,13,124,193,17
      GROUPBOX        "¿Í»§»ú×´Ì¬",IDC_STATIC,7,157,206,61
--- 51,58 ----
      EDITTEXT        IDC_CELL,62,22,114,13,ES_LOWERCASE | ES_AUTOHSCROLL
      CONTROL         "µÇÂ¼µ½ Windows Ê±»ñµÃ AFS ÁîÅÆ",IDC_LOGON,"Button",
                      BS_AUTOCHECKBOX | WS_TABSTOP,13,50,193,10
      CONTROL         "ÔÚÈÎÎñÀ¸ÖÐÏÔÊ¾ AFS ¿Í»§»úÍ¼±ê(&I)",IDC_TRAYICON,"Button",
!                     BS_AUTOCHECKBOX | WS_TABSTOP,13,72,193,10
      LTEXT           "×¢Òâ£ºÓÉÓÚÃ»ÓÐÔËÐÐ AFS ¿Í»§»ú·þÎñ£¬½«½ûÓÃÕâÐ©¿ØÖÆ¡£",
                      IDC_WARN,13,124,193,17
      GROUPBOX        "¿Í»§»ú×´Ì¬",IDC_STATIC,7,157,206,61
Index: openafs/src/WINNT/client_config/lang/zh_TW/afs_config.rc
diff -c openafs/src/WINNT/client_config/lang/zh_TW/afs_config.rc:1.3.2.1 openafs/src/WINNT/client_config/lang/zh_TW/afs_config.rc:1.3.2.2
*** openafs/src/WINNT/client_config/lang/zh_TW/afs_config.rc:1.3.2.1	Fri Mar 11 02:00:17 2005
--- openafs/src/WINNT/client_config/lang/zh_TW/afs_config.rc	Fri Apr 29 15:56:27 2005
***************
*** 51,60 ****
      EDITTEXT        IDC_CELL,68,22,114,13,ES_LOWERCASE | ES_AUTOHSCROLL
      CONTROL         "µn¤J Windows ®É¨ú±o AFS °O¸¹(&O)",IDC_LOGON,"Button",
                      BS_AUTOCHECKBOX | WS_TABSTOP,13,50,193,10
!     CONTROL         "´£¨Ñ AFS Light ¹h¹D(&P) ",IDC_GATEWAY,"Button",
                      BS_AUTOCHECKBOX | WS_TABSTOP,13,72,193,10
-     CONTROL         "¦b¤u§@¦CÅã¥Ü¡uAFS ¥Î¤áºÝ¡v¹Ï¥Ü(&H)  ",IDC_TRAYICON,
-                     "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,95,193,10
      LTEXT           "ªþµù¡G¥Ñ©ó¨Ã¥¼°õ¦æ¡uAFS ¥Î¤áºÝ¡vªA°È¡A¦]¦¹±±¨î³£¤w°±¥Î¡C",
                      IDC_WARN,13,124,193,17
      GROUPBOX        "¥Î¤áºÝª¬ºA",IDC_STATIC,7,157,206,61
--- 51,58 ----
      EDITTEXT        IDC_CELL,68,22,114,13,ES_LOWERCASE | ES_AUTOHSCROLL
      CONTROL         "µn¤J Windows ®É¨ú±o AFS °O¸¹(&O)",IDC_LOGON,"Button",
                      BS_AUTOCHECKBOX | WS_TABSTOP,13,50,193,10
!     CONTROL         "¦b¤u§@¦CÅã¥Ü¡uAFS ¥Î¤áºÝ¡v¹Ï¥Ü(&H)  ",IDC_TRAYICON,"Button",
                      BS_AUTOCHECKBOX | WS_TABSTOP,13,72,193,10
      LTEXT           "ªþµù¡G¥Ñ©ó¨Ã¥¼°õ¦æ¡uAFS ¥Î¤áºÝ¡vªA°È¡A¦]¦¹±±¨î³£¤w°±¥Î¡C",
                      IDC_WARN,13,124,193,17
      GROUPBOX        "¥Î¤áºÝª¬ºA",IDC_STATIC,7,157,206,61
Index: openafs/src/WINNT/install/NSIS/OpenAFS.nsi
diff -c openafs/src/WINNT/install/NSIS/OpenAFS.nsi:1.69.2.8 openafs/src/WINNT/install/NSIS/OpenAFS.nsi:1.69.2.9
*** openafs/src/WINNT/install/NSIS/OpenAFS.nsi:1.69.2.8	Thu Apr 28 08:05:33 2005
--- openafs/src/WINNT/install/NSIS/OpenAFS.nsi	Sun May 29 23:58:34 2005
***************
*** 546,551 ****
--- 546,552 ----
    
    SetOutPath "$SYSDIR"
    !insertmacro ReplaceDLL "${AFS_CLIENT_BUILDDIR}\afslogon.dll" "$SYSDIR\afslogon.dll" "$INSTDIR"
+   File "${AFS_CLIENT_BUILDDIR}\afscpcc.exe"
     
     Call AFSLangFiles
  
***************
*** 726,731 ****
--- 727,737 ----
    WriteRegStr HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" "Logoff" "AFS_Logoff_Event"
    WriteRegStr HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" "Startup" "AFS_Startup_Event"
  
+   WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" "Asynchronous" 0
+   WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" "Impersonate"  0
+   WriteRegStr HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" "DLLName" "afslogon.dll"
+   WriteRegStr HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" "Logon" "KFW_Logon_Event"
+ 
    SetRebootFlag true
    
    WriteUninstaller "$INSTDIR\Uninstall.exe"
***************
*** 1800,1809 ****
--- 1806,1817 ----
    Delete /REBOOTOK "$SYSDIR\afsserver.cpl"
    Delete /REBOOTOK "$SYSDIR\afs_cpa.cpl"
    Delete /REBOOTOK "$SYSDIR\afslogon.dll"
+   Delete /REBOOTOK "$SYSDIR\afscpcc.exe"
  
    Delete /REBOOTOK "$SYSDIR\afsserver.pdb"
    Delete /REBOOTOK "$SYSDIR\afs_cpa.pdb"
    Delete /REBOOTOK "$SYSDIR\afslogon.pdb"
+   Delete /REBOOTOK "$SYSDIR\afscpcc.pdb"
  
    RMDir /r "$INSTDIR\Documentation\html\CmdRef"
    RMDir /r "$INSTDIR\Documentation\html\InstallGd"
Index: openafs/src/WINNT/install/loopback/loopbackutils.cpp
diff -c openafs/src/WINNT/install/loopback/loopbackutils.cpp:1.6 openafs/src/WINNT/install/loopback/loopbackutils.cpp:1.6.2.1
*** openafs/src/WINNT/install/loopback/loopbackutils.cpp:1.6	Thu Jul 15 23:38:35 2004
--- openafs/src/WINNT/install/loopback/loopbackutils.cpp	Tue May 24 01:13:06 2005
***************
*** 237,242 ****
--- 237,246 ----
      BOOL found = FALSE;
      BOOL registered = FALSE;
      BOOL destroyList = FALSE;
+     PSP_DRVINFO_DETAIL_DATA pDriverInfoDetail;
+     DWORD detailBuf[2048];    // for our purposes, 8k buffer is more
+ 			      // than enough to obtain the hardware ID
+ 			      // of the loopback driver.
  
      HKEY hkey = NULL;
      DWORD cbSize;
***************
*** 294,314 ****
      destroyList = TRUE;
  
      // enumerate the driver info list
!     while (SetupDiEnumDriverInfo(hDeviceInfo, &DeviceInfoData,
!                                  SPDIT_CLASSDRIVER, index, &DriverInfoData))
      {
!         // if the manufacture is microsoft
!         if (_tcsicmp(DriverInfoData.MfgName, MANUFACTURE) == 0)
!         {
!             // case insensitive search for loopback
!             _tcscpy(temp, DriverInfoData.Description);
!             _tcslwr(temp);
!             if( _tcsstr(temp, DRIVER))
!             {
!                 found = TRUE;
!                 break;
!             }
!         }
          index++;
      }
  
--- 298,340 ----
      destroyList = TRUE;
  
      // enumerate the driver info list
!     while (TRUE)
      {
!         BOOL ret;
! 
! 	ret = SetupDiEnumDriverInfo(hDeviceInfo, &DeviceInfoData,
! 				  SPDIT_CLASSDRIVER, index, &DriverInfoData);
! 
! 	// if the function failed and GetLastError() returned
! 	// ERROR_NO_MORE_ITEMS, then we have reached the end of the
! 	// list.  Othewise there was something wrong with this
! 	// particular driver.
! 	if(!ret) {
! 	  if(GetLastError() == ERROR_NO_MORE_ITEMS)
! 	    break;
! 	  else {
! 	    index++;
! 	    continue;
! 	  }
! 	}
! 
! 	pDriverInfoDetail = (PSP_DRVINFO_DETAIL_DATA) detailBuf;
! 	pDriverInfoDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
! 
! 	// if we successfully find the hardware ID and it turns out to
! 	// be the one for the loopback driver, then we are done.
! 	if(SetupDiGetDriverInfoDetail(hDeviceInfo,
! 				      &DeviceInfoData,
! 				      &DriverInfoData,
! 				      pDriverInfoDetail,
! 				      sizeof(detailBuf),
! 				      NULL) &&
! 	   !_tcsicmp(pDriverInfoDetail->HardwareID, DRIVERHWID)) {
! 
! 	  found = TRUE;
! 	  break;
! 	}
! 
          index++;
      }
  
Index: openafs/src/WINNT/install/loopback/loopbackutils.h
diff -c openafs/src/WINNT/install/loopback/loopbackutils.h:1.2 openafs/src/WINNT/install/loopback/loopbackutils.h:1.2.2.1
*** openafs/src/WINNT/install/loopback/loopbackutils.h:1.2	Thu Jun 24 00:08:57 2004
--- openafs/src/WINNT/install/loopback/loopbackutils.h	Tue May 24 01:13:06 2005
***************
*** 41,46 ****
--- 41,47 ----
  
  #define DRIVER_DESC "Microsoft Loopback Adapter"
  #define DRIVER _T("loopback")
+ #define DRIVERHWID _T("*msloop")
  #define MANUFACTURE _T("microsoft")
  #define DEFAULT_NAME _T("AFS")
  #define DEFAULT_IP _T("10.254.254.253")
***************
*** 71,74 ****
  #define REPORT_IGNORE 3
  
  extern DWORD dwReporterType;
! extern DWORD hMsiHandle;
\ No newline at end of file
--- 72,75 ----
  #define REPORT_IGNORE 3
  
  extern DWORD dwReporterType;
! extern DWORD hMsiHandle;
Index: openafs/src/WINNT/install/wix/files.wxi
diff -c openafs/src/WINNT/install/wix/files.wxi:1.9.2.5 openafs/src/WINNT/install/wix/files.wxi:1.9.2.6
*** openafs/src/WINNT/install/wix/files.wxi:1.9.2.5	Thu Apr 28 08:05:45 2005
--- openafs/src/WINNT/install/wix/files.wxi	Sun May 29 23:58:38 2005
***************
*** 3,8 ****
--- 3,9 ----
      <Directory Id="SystemFolder" SourceName="System">
          <Component Id="cmf_afslogon_DLL" Guid="123197FE-4F53-4035-8D51-FCFB6B50A777">
              <File Id="fileafslogon_DLL" Name="afslogon.dll" LongName="afslogon.dll" KeyPath="yes" DiskId="1" src="$(var.ClientDir)afslogon.dll" />
+             <File Id="fileafscpcc_EXE"  Name="afscpcc.exe"  LongName="afscpcc.exe"  DiskId="1" src="$(var.ClientDir)afscpcc.exe" />
              <Registry Id="reg_afslogon01" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" Action="createKeyAndRemoveKeyOnUninstall" />
              <Registry Id="reg_afslogon02" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" />
              <Registry Id="reg_afslogon03" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" Name="Asynchronous" Type="integer" Value="0" />
***************
*** 11,20 ****
--- 12,26 ----
              <Registry Id="reg_afslogon06" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" Name="Logoff" Type="string" Value="AFS_Logoff_Event" />
              <Registry Id="reg_afslogon07" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" Name="Logon" Type="string" Value="AFS_Logon_Event" />
              <Registry Id="reg_afslogon08" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" Name="Startup" Type="string" Value="AFS_Startup_Event" />
+             <Registry Id="reg_afslogon09" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" Name="Asynchronous" Type="integer" Value="0" />
+             <Registry Id="reg_afslogon10" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" Name="Impersonate" Type="integer" Value="0" />
+             <Registry Id="reg_afslogon11" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" Name="DLLName" Type="string" Value="[#fileafslogon_DLL]" />
+             <Registry Id="reg_afslogon13" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" Name="Logon" Type="string" Value="KFW_Logon_Event" />
          </Component>
      <?ifdef DebugSyms?>
          <Component Id="cmp_ClientSystemDebug" Guid="DD34DA09-D9DA-4A5A-9521-87B7738A7D53">
  			<File Id="fileafslogon_PDB" Name="afslogon.pdb" LongName="afslogon.pdb" KeyPath="yes" DiskId="1" src="$(var.ClientDir)afslogon.pdb" />
+ 			<File Id="fileafscpcc_PDB" Name="afscpcc.pdb" LongName="afscpcc.pdb" DiskId="1" src="$(var.ClientDir)afscpcc.pdb" />
          </Component>
      <?endif?>
      </Directory>
Index: openafs/src/afs/afs.h
diff -c openafs/src/afs/afs.h:1.48.2.14 openafs/src/afs/afs.h:1.48.2.19
*** openafs/src/afs/afs.h:1.48.2.14	Mon Apr  4 03:43:20 2005
--- openafs/src/afs/afs.h	Mon May 30 00:05:40 2005
***************
*** 43,49 ****
  #if     defined(AFS_HPUX102_ENV)
  #define AFS_FLOCK       k_flock
  #else
! #if     defined(AFS_SUN56_ENV) || (defined(AFS_LINUX24_ENV) && !defined(AFS_PPC64_LINUX26_ENV) && !defined(AFS_AMD64_LINUX26_ENV) && !defined(AFS_IA64_LINUX26_ENV) && !defined(AFS_S390X_LINUX26_ENV) && !defined(AFS_ALPHA_LINUX26_ENV))
  #define AFS_FLOCK       flock64
  #else
  #define AFS_FLOCK       flock
--- 43,49 ----
  #if     defined(AFS_HPUX102_ENV)
  #define AFS_FLOCK       k_flock
  #else
! #if     defined(AFS_SUN56_ENV) || (defined(AFS_LINUX24_ENV) && !(defined(AFS_LINUX26_ENV) && defined(AFS_LINUX_64BIT_KERNEL)))
  #define AFS_FLOCK       flock64
  #else
  #define AFS_FLOCK       flock
***************
*** 580,599 ****
  
  extern afs_int32 vmPageHog;	/* counter for # of vnodes which are page hogs. */
  
- /*
-  * Fast map from vcache to dcache
-  */
- struct vtodc {
-     struct dcache *dc;
-     afs_uint32 stamp;
-     struct osi_file *f;
-     afs_offs_t minLoc;		/* smallest offset into dc. */
-     afs_offs_t len;		/* largest offset into dc. */
- };
- 
- extern afs_uint32 afs_stampValue;	/* stamp for pair's usage */
- #define	MakeStamp()	(++afs_stampValue)
- 
  #if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
  #define VTOAFS(v) ((struct vcache *)(v)->v_data)
  #define AFSTOV(vc) ((vc)->v)
--- 580,585 ----
***************
*** 620,625 ****
--- 606,612 ----
      struct afs_q vlruq;		/* lru q next and prev */
      struct vcache *nextfree;	/* next on free list (if free) */
      struct vcache *hnext;	/* Hash next */
+     struct vcache *vhnext; /* vol hash next */
      struct VenusFid fid;
      struct mstat {
  	afs_size_t Length;
***************
*** 689,700 ****
  #if	defined(AFS_SUN5_ENV)
      afs_uint32 vstates;		/* vstate bits */
  #endif				/* defined(AFS_SUN5_ENV) */
!     struct vtodc quick;
!     afs_uint32 symhintstamp;
!     union {
! 	struct vcache *symhint;
! 	struct dcache *dchint;
!     } h1;
  #ifdef AFS_LINUX22_ENV
      u_short mapcnt;		/* Number of mappings of this file. */
  #endif
--- 676,682 ----
  #if	defined(AFS_SUN5_ENV)
      afs_uint32 vstates;		/* vstate bits */
  #endif				/* defined(AFS_SUN5_ENV) */
!     struct dcache *dchint;
  #ifdef AFS_LINUX22_ENV
      u_short mapcnt;		/* Number of mappings of this file. */
  #endif
***************
*** 722,730 ****
  #endif
  };
  
- #define afs_symhint_inval(avc)
- 
- 
  #define	DONT_CHECK_MODE_BITS	0
  #define	CHECK_MODE_BITS		1
  #define CMB_ALLOW_EXEC_AS_READ  2	/* For the NFS xlator */
--- 704,709 ----
***************
*** 784,789 ****
--- 763,775 ----
      afs_uint32 states;
  };
  
+ struct vcxstat2 {
+     afs_int32 callerAccess;
+     afs_int32 cbExpires;
+     afs_int32 anyAccess;
+     char mvstat;
+ };
+ 
  struct sbstruct {
      int sb_thisfile;
      int sb_default;
***************
*** 828,833 ****
--- 814,822 ----
  
  #define	NULLIDX	    (-1)	/* null index definition */
  /* struct dcache states bits */
+ #define DRO         1
+ #define DBackup     2
+ #define DRW         4
  #define	DWriting    8		/* file being written (used for cache validation) */
  
  /* dcache data flags */
***************
*** 952,959 ****
      char dflags;		/* Data flags */
      char mflags;		/* Meta flags */
      struct fcache f;		/* disk image */
!     afs_int32 stamp;		/* used with vtodc struct for hints */
! 
      /*
       * Locking rules:
       *
--- 941,947 ----
      char dflags;		/* Data flags */
      char mflags;		/* Meta flags */
      struct fcache f;		/* disk image */
!     afs_int32 bucket;           /* which bucket these dcache entries are in */
      /*
       * Locking rules:
       *
***************
*** 972,981 ****
       * Note that dcache.lock(W) gives you the right to update mflags,
       * as dcache.mflock(W) can only be held with dcache.lock(R).
       *
-      * dcache.stamp is protected by the associated vcache lock, because
-      * it's only purpose is to establish correspondence between vcache
-      * and dcache entries.
-      *
       * dcache.index, dcache.f.fid, dcache.f.chunk and dcache.f.inode are
       * write-protected by afs_xdcache and read-protected by refCount.
       * Once an entry is referenced, these values cannot change, and if
--- 960,965 ----
***************
*** 985,992 ****
       * ensuring noone else has a refCount on it).
       */
  };
- /* this is obsolete and should be removed */
- #define ihint stamp
  
  /* afs_memcache.c */
  struct memCacheEntry {
--- 969,974 ----
***************
*** 1055,1060 ****
--- 1037,1044 ----
  /* don't hash on the cell, our callback-breaking code sometimes fails to compute
      the cell correctly, and only scans one hash bucket */
  #define	VCHash(fid)	(((fid)->Fid.Volume + (fid)->Fid.Vnode) & (VCSIZE-1))
+ /* Hash only on volume to speed up volume callbacks. */
+ #define VCHashV(fid) ((fid)->Fid.Volume & (VCSIZE-1))
  
  extern struct dcache **afs_indexTable;	/*Pointers to in-memory dcache entries */
  extern afs_int32 *afs_indexUnique;	/*dcache entry Fid.Unique */
***************
*** 1064,1069 ****
--- 1048,1054 ----
  extern afs_int32 afs_cacheBlocks;	/*1K blocks in cache */
  extern afs_int32 afs_cacheStats;	/*Stat entries in cache */
  extern struct vcache *afs_vhashT[VCSIZE];	/*Stat cache hash table */
+ extern struct vcache *afs_vhashTV[VCSIZE]; /* cache hash table on volume */
  extern afs_int32 afs_initState;	/*Initialization state */
  extern afs_int32 afs_termState;	/* Termination state */
  extern struct VenusFid afs_rootFid;	/*Root for whole file system */
Index: openafs/src/afs/afs_call.c
diff -c openafs/src/afs/afs_call.c:1.74.2.7 openafs/src/afs/afs_call.c:1.74.2.9
*** openafs/src/afs/afs_call.c:1.74.2.7	Sun Apr  3 14:15:35 2005
--- openafs/src/afs/afs_call.c	Mon May 23 17:16:08 2005
***************
*** 11,17 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_call.c,v 1.74.2.7 2005/04/03 18:15:35 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 11,17 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_call.c,v 1.74.2.9 2005/05/23 21:16:08 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 517,522 ****
--- 517,534 ----
  	DInit(temp);
  	afs_rootFid.Fid.Volume = 0;
  	code = 0;
+     } else if (parm == AFSOP_BUCKETPCT) {
+ 	/* need to enable this now, will disable again before GO
+ 	   if we don't have 100% */
+ 	splitdcache = 1;
+ 	switch (parm2) {
+ 	case 1:
+ 	    afs_tpct1 = parm3;
+ 	    break;
+ 	case 2:
+ 	    afs_tpct2 = parm3;
+ 	    break;
+ 	}           
      } else if (parm == AFSOP_ADDCELL) {
  	/* add a cell.  Parameter 2 is 8 hosts (in net order),  parm 3 is the null-terminated
  	 * name.  Parameter 4 is the length of the name, including the null.  Parm 5 is the
***************
*** 693,698 ****
--- 705,717 ----
  	    afs_osi_Sleep(&afs_initState);
  	afs_initState = 101;
  	afs_setTime = parm2;
+ 	if (afs_tpct1 + afs_tpct2 != 100) {
+ 	    afs_tpct1 = 0;
+ 	    afs_tpct2 = 0;
+ 	    splitdcache = 0;
+ 	} else {        
+ 	    splitdcache = 1;
+ 	}
  	afs_osi_Wakeup(&afs_initState);
  #if	(!defined(AFS_NONFSTRANS)) || defined(AFS_AIX_IAUTH_ENV)
  	afs_nfsclient_init();
***************
*** 1148,1154 ****
  #if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
      struct iparam32 dst32;
  
! #ifdef AFS_SPARC64_LINUX24_ENV
      if (current->thread.flags & SPARC_FLAG_32BIT)
  #elif defined(AFS_SPARC64_LINUX20_ENV)
      if (current->tss.flags & SPARC_FLAG_32BIT)
--- 1167,1175 ----
  #if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
      struct iparam32 dst32;
  
! #ifdef AFS_SPARC64_LINUX26_ENV
!     if (test_thread_flag(TIF_32BIT))
! #elif AFS_SPARC64_LINUX24_ENV
      if (current->thread.flags & SPARC_FLAG_32BIT)
  #elif defined(AFS_SPARC64_LINUX20_ENV)
      if (current->tss.flags & SPARC_FLAG_32BIT)
***************
*** 1326,1332 ****
  })
  
  
! 	if (current->thread.flags & SPARC_FLAG_32BIT) {
  	    AFS_COPYIN((char *)parm4, (char *)eparm32, sizeof(eparm32), code);
  	    eparm[0] = AA(eparm32[0]);
  	    eparm[1] = AA(eparm32[1]);
--- 1347,1358 ----
  })
  
  
! #ifdef AFS_SPARC64_LINUX26_ENV
! 	if (test_thread_flag(TIF_32BIT))
! #else
! 	if (current->thread.flags & SPARC_FLAG_32BIT)
! #endif
! 	{
  	    AFS_COPYIN((char *)parm4, (char *)eparm32, sizeof(eparm32), code);
  	    eparm[0] = AA(eparm32[0]);
  	    eparm[1] = AA(eparm32[1]);
Index: openafs/src/afs/afs_callback.c
diff -c openafs/src/afs/afs_callback.c:1.27 openafs/src/afs/afs_callback.c:1.27.2.2
*** openafs/src/afs/afs_callback.c:1.27	Thu Jun 24 12:56:20 2004
--- openafs/src/afs/afs_callback.c	Mon May 30 00:05:40 2005
***************
*** 17,23 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_callback.c,v 1.27 2004/06/24 16:56:20 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.27.2.2 2005/05/30 04:05:40 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
***************
*** 388,401 ****
  	     * Clear callback for the whole volume.  Zip through the
  	     * hash chain, nullifying entries whose volume ID matches.
  	     */
! 	    for (i = 0; i < VCSIZE; i++)
! 		for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
  		    if (tvc->fid.Fid.Volume == a_fid->Volume) {
  			tvc->callback = NULL;
- 			tvc->quick.stamp = 0;
  			if (!localFid.Cell)
  			    localFid.Cell = tvc->fid.Cell;
! 			tvc->h1.dchint = NULL;	/* invalidate hints */
  			ObtainWriteLock(&afs_xcbhash, 449);
  			afs_DequeueCallback(tvc);
  			tvc->states &= ~(CStatd | CUnique | CBulkFetching);
--- 388,400 ----
  	     * Clear callback for the whole volume.  Zip through the
  	     * hash chain, nullifying entries whose volume ID matches.
  	     */
! 		i = VCHashV(&localFid);
! 		for (tvc = afs_vhashTV[i]; tvc; tvc = tvc->vhnext) {
  		    if (tvc->fid.Fid.Volume == a_fid->Volume) {
  			tvc->callback = NULL;
  			if (!localFid.Cell)
  			    localFid.Cell = tvc->fid.Cell;
! 			tvc->dchint = NULL;	/* invalidate hints */
  			ObtainWriteLock(&afs_xcbhash, 449);
  			afs_DequeueCallback(tvc);
  			tvc->states &= ~(CStatd | CUnique | CBulkFetching);
***************
*** 444,451 ****
  		    && tvc->fid.Fid.Volume == a_fid->Volume
  		    && tvc->fid.Fid.Unique == a_fid->Unique) {
  		    tvc->callback = NULL;
! 		    tvc->quick.stamp = 0;
! 		    tvc->h1.dchint = NULL;	/* invalidate hints */
  		    ObtainWriteLock(&afs_xcbhash, 450);
  		    afs_DequeueCallback(tvc);
  		    tvc->states &= ~(CStatd | CUnique | CBulkFetching);
--- 443,449 ----
  		    && tvc->fid.Fid.Volume == a_fid->Volume
  		    && tvc->fid.Fid.Unique == a_fid->Unique) {
  		    tvc->callback = NULL;
! 		    tvc->dchint = NULL;	/* invalidate hints */
  		    ObtainWriteLock(&afs_xcbhash, 450);
  		    afs_DequeueCallback(tvc);
  		    tvc->states &= ~(CStatd | CUnique | CBulkFetching);
Index: openafs/src/afs/afs_cbqueue.c
diff -c openafs/src/afs/afs_cbqueue.c:1.9 openafs/src/afs/afs_cbqueue.c:1.9.2.1
*** openafs/src/afs/afs_cbqueue.c:1.9	Tue Jul 15 19:14:11 2003
--- openafs/src/afs/afs_cbqueue.c	Mon May 30 00:05:40 2005
***************
*** 75,81 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_cbqueue.c,v 1.9 2003/07/15 23:14:11 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
--- 75,81 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_cbqueue.c,v 1.9.2.1 2005/05/30 04:05:40 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
***************
*** 143,149 ****
  	QRemove(&(avc->callsort));
  	avc->callsort.prev = avc->callsort.next = NULL;
      } else;			/* must have got dequeued in a race */
-     afs_symhint_inval(avc);
  
      return;
  }				/* afs_DequeueCallback */
--- 143,148 ----
***************
*** 226,233 ****
  			    if ((tvc->fid.Fid.Vnode & 1)
  				|| (vType(tvc) == VDIR))
  				osi_dnlc_purgedp(tvc);
! 			    tvc->quick.stamp = 0;
! 			    tvc->h1.dchint = NULL;	/*invalidate em */
  			    afs_ResetVolumeInfo(tvp);
  			    break;
  			}
--- 225,231 ----
  			    if ((tvc->fid.Fid.Vnode & 1)
  				|| (vType(tvc) == VDIR))
  				osi_dnlc_purgedp(tvc);
! 			    tvc->dchint = NULL;	/*invalidate em */
  			    afs_ResetVolumeInfo(tvp);
  			    break;
  			}
***************
*** 309,316 ****
      for (i = 0; i < VCSIZE; i++)	/* reset all the vnodes */
  	for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
  	    tvc->callback = 0;
! 	    tvc->quick.stamp = 0;
! 	    tvc->h1.dchint = NULL;	/* invalidate hints */
  	    tvc->states &= ~(CStatd);
  	    if ((tvc->fid.Fid.Vnode & 1) || (vType(tvc) == VDIR))
  		osi_dnlc_purgedp(tvc);
--- 307,313 ----
      for (i = 0; i < VCSIZE; i++)	/* reset all the vnodes */
  	for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
  	    tvc->callback = 0;
! 	    tvc->dchint = NULL;	/* invalidate hints */
  	    tvc->states &= ~(CStatd);
  	    if ((tvc->fid.Fid.Vnode & 1) || (vType(tvc) == VDIR))
  		osi_dnlc_purgedp(tvc);
***************
*** 339,346 ****
  	for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
  	    if (tvc->callback == srvp) {
  		tvc->callback = 0;
! 		tvc->quick.stamp = 0;
! 		tvc->h1.dchint = NULL;	/* invalidate hints */
  		tvc->states &= ~(CStatd);
  		if ((tvc->fid.Fid.Vnode & 1) || (vType(tvc) == VDIR)) {
  		    osi_dnlc_purgedp(tvc);
--- 336,342 ----
  	for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
  	    if (tvc->callback == srvp) {
  		tvc->callback = 0;
! 		tvc->dchint = NULL;	/* invalidate hints */
  		tvc->states &= ~(CStatd);
  		if ((tvc->fid.Fid.Vnode & 1) || (vType(tvc) == VDIR)) {
  		    osi_dnlc_purgedp(tvc);
Index: openafs/src/afs/afs_dcache.c
diff -c openafs/src/afs/afs_dcache.c:1.42.2.10 openafs/src/afs/afs_dcache.c:1.42.2.12
*** openafs/src/afs/afs_dcache.c:1.42.2.10	Sun Apr  3 14:15:35 2005
--- openafs/src/afs/afs_dcache.c	Mon May 30 00:05:40 2005
***************
*** 14,20 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_dcache.c,v 1.42.2.10 2005/04/03 18:15:35 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.42.2.12 2005/05/30 04:05:40 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
***************
*** 23,36 ****
  #include "afs/afs_osidnlc.h"
  
  /* Forward declarations. */
! static void afs_GetDownD(int anumber, int *aneedSpace);
  static void afs_FreeDiscardedDCache(void);
  static void afs_DiscardDCache(struct dcache *);
  static void afs_FreeDCache(struct dcache *);
  
  /*
   * --------------------- Exported definitions ---------------------
   */
  afs_lock_t afs_xdcache;		/*Lock: alloc new disk cache entries */
  afs_int32 afs_freeDCList;	/*Free list for disk cache entries */
  afs_int32 afs_freeDCCount;	/*Count of elts in freeDCList */
--- 23,53 ----
  #include "afs/afs_osidnlc.h"
  
  /* Forward declarations. */
! static void afs_GetDownD(int anumber, int *aneedSpace, afs_int32 buckethint);
  static void afs_FreeDiscardedDCache(void);
  static void afs_DiscardDCache(struct dcache *);
  static void afs_FreeDCache(struct dcache *);
+ /* For split cache */
+ static afs_int32 afs_DCGetBucket(struct vcache *);
+ static void afs_DCAdjustSize(struct dcache *, afs_int32, afs_int32);
+ static void afs_DCMoveBucket(struct dcache *, afs_int32, afs_int32);
+ static void afs_DCSizeInit(void);
+ static afs_int32 afs_DCWhichBucket(afs_int32, afs_int32);
+ 
  
  /*
   * --------------------- Exported definitions ---------------------
   */
+ /* For split cache */
+ afs_int32 afs_blocksUsed_0;    /*1K blocks in cache - in theory is zero */
+ afs_int32 afs_blocksUsed_1;    /*1K blocks in cache */
+ afs_int32 afs_blocksUsed_2;    /*1K blocks in cache */
+ afs_int32 afs_pct1 = -1;
+ afs_int32 afs_pct2 = -1;
+ afs_uint32 afs_tpct1 = 0;
+ afs_uint32 afs_tpct2 = 0;
+ afs_uint32 splitdcache = 0;
+ 
  afs_lock_t afs_xdcache;		/*Lock: alloc new disk cache entries */
  afs_int32 afs_freeDCList;	/*Free list for disk cache entries */
  afs_int32 afs_freeDCCount;	/*Count of elts in freeDCList */
***************
*** 119,125 ****
--- 136,245 ----
  int cacheDiskType;		/*Type of backing disk for cache */
  struct afs_cacheOps *afs_cacheType;
  
+ static afs_int32
+ afs_DCGetBucket(struct vcache *avc) 
+ {
+   /* This should be replaced with some sort of user configurable function */
+   if (avc->states & CRO) {
+       return 2;
+   } else if (avc->states & CBackup) {
+       return 1;
+   } else {
+     /* RW */
+   }
+   /* main bucket */
+   return 1;
+ }
+ 
+ static void 
+ afs_DCAdjustSize(struct dcache *adc, afs_int32 oldSize, afs_int32 newSize)
+ {
+     afs_int32 adjustSize = newSize - oldSize;
+ 
+     if (!splitdcache) 
+ 	return;
+ 
+     switch (adc->bucket) 
+     {
+     case 0:
+ 	afs_blocksUsed_0 += adjustSize;
+ 	afs_stats_cmperf.cacheBucket0_Discarded += oldSize;
+ 	break;
+     case 1:
+ 	afs_blocksUsed_1 += adjustSize;
+ 	afs_stats_cmperf.cacheBucket1_Discarded += oldSize;
+ 	break;
+     case 2:
+ 	afs_blocksUsed_2 += adjustSize;
+ 	afs_stats_cmperf.cacheBucket2_Discarded += oldSize;
+ 	break;
+     }
+ 
+     return;
+ }
+ 
+ static void 
+ afs_DCMoveBucket(struct dcache *adc, afs_int32 size, afs_int32 newBucket)
+ {
+     if (!splitdcache) 
+ 	return;
+ 
+     switch (adc->bucket) 
+     {
+     case 0:
+ 	afs_blocksUsed_0 -= size;
+ 	break;
+     case 1:
+ 	afs_blocksUsed_1 -= size;
+ 	break;
+     case 2:
+ 	afs_blocksUsed_2 -= size;
+ 	break;
+     }
+ 
+     adc->bucket = newBucket;
+ 
+     switch (adc->bucket) 
+     {
+     case 0:
+ 	afs_blocksUsed_0 += size;
+ 	break;
+     case 1:
+ 	afs_blocksUsed_1 += size;
+ 	break;
+     case 2:
+ 	afs_blocksUsed_2 += size;
+ 	break;
+     }
+     
+     return;
+ }
+ 
+ static void 
+ afs_DCSizeInit(void) 
+ {
+     afs_blocksUsed_0 = afs_blocksUsed_1 = afs_blocksUsed_2 = 0;
+ }
  
+ static afs_int32
+ afs_DCWhichBucket(afs_int32 phase, afs_int32 bucket) 
+ {
+     if (!splitdcache) 
+ 	return 0;
+ 
+     afs_pct1 = afs_blocksUsed_1*100/afs_cacheBlocks;    
+     afs_pct2 = afs_blocksUsed_2*100/afs_cacheBlocks;
+ 
+     /* Short cut: if we don't know about it, try to kill it */
+     if (phase < 2 && afs_blocksUsed_0) 
+ 	return 0;
+     
+     if (afs_pct1 > afs_tpct1) 
+ 	return 1;
+     if (afs_pct2 > afs_tpct2)
+ 	return 2;
+     return 0; /* unlikely */
+ }
  
  
  /*
***************
*** 245,251 ****
  		    afs_blocksUsed - afs_blocksDiscarded - cb_lowat;
  		slots_needed =
  		    dc_hiwat - afs_freeDCCount - afs_discardDCCount;
! 		afs_GetDownD(slots_needed, &space_needed);
  		if ((space_needed <= 0) && (slots_needed <= 0)) {
  		    break;
  		}
--- 365,371 ----
  		    afs_blocksUsed - afs_blocksDiscarded - cb_lowat;
  		slots_needed =
  		    dc_hiwat - afs_freeDCCount - afs_discardDCCount;
! 		afs_GetDownD(slots_needed, &space_needed, 0);
  		if ((space_needed <= 0) && (slots_needed <= 0)) {
  		    break;
  		}
***************
*** 340,345 ****
--- 460,466 ----
      if (!newSize)
  	adc->validPos = 0;
      newSize = ((newSize + afs_fsfragsize) ^ afs_fsfragsize) >> 10;	/* round up */
+     afs_DCAdjustSize(adc, oldSize, newSize);
      if (newSize > oldSize) {
  	/* We're growing the file, wakeup the daemon */
  	afs_MaybeWakeupTruncateDaemon();
***************
*** 376,382 ****
  
  #define	MAXATONCE   16		/* max we can obtain at once */
  static void
! afs_GetDownD(int anumber, int *aneedSpace)
  {
  
      struct dcache *tdc;
--- 497,503 ----
  
  #define	MAXATONCE   16		/* max we can obtain at once */
  static void
! afs_GetDownD(int anumber, int *aneedSpace, afs_int32 buckethint)
  {
  
      struct dcache *tdc;
***************
*** 392,397 ****
--- 513,519 ----
      afs_hyper_t maxVictimTime;	/* youngest (largest LRU time) victim */
      afs_uint32 maxVictimPtr;	/* where it is */
      int discard;
+     int curbucket;
  
      AFS_STATCNT(afs_GetDownD);
      if (CheckLock(&afs_xdcache) != -1)
***************
*** 408,419 ****
      if (anumber > MAXATONCE)
  	anumber = MAXATONCE;	/* all we can do */
  
      /*
       * The phase variable manages reclaims.  Set to 0, the first pass,
!      * we don't reclaim active entries.  Set to 1, we reclaim even active
!      * ones.
       */
!     phase = 0;
      for (i = 0; i < afs_cacheFiles; i++)
  	/* turn off all flags */
  	afs_indexFlags[i] &= ~IFFlag;
--- 530,549 ----
      if (anumber > MAXATONCE)
  	anumber = MAXATONCE;	/* all we can do */
  
+     /* rewrite so phases include a better eligiblity for gc test*/
      /*
       * The phase variable manages reclaims.  Set to 0, the first pass,
!      * we don't reclaim active entries, or other than target bucket.  
!      * Set to 1, we reclaim even active ones in target bucket.
!      * Set to 2, we reclaim any inactive one.
!      * Set to 3, we reclaim even active ones.
       */
!     if (splitdcache) {
! 	phase = 0;
!     } else {
! 	phase = 4;
!     }
! 
      for (i = 0; i < afs_cacheFiles; i++)
  	/* turn off all flags */
  	afs_indexFlags[i] &= ~IFFlag;
***************
*** 422,427 ****
--- 552,558 ----
  	/* find oldest entries for reclamation */
  	maxVictimPtr = victimPtr = 0;
  	hzero(maxVictimTime);
+ 	curbucket = afs_DCWhichBucket(phase, buckethint);
  	/* select victims from access time array */
  	for (i = 0; i < afs_cacheFiles; i++) {
  	    if (afs_indexFlags[i] & (IFDataMod | IFFree | IFDiscarded)) {
***************
*** 429,434 ****
--- 560,570 ----
  		continue;
  	    }
  	    tdc = afs_indexTable[i];
+ 	    if (tdc && (curbucket != tdc->bucket) && (phase < 4))
+ 	    {
+ 		/* Wrong bucket; can't use it! */
+ 	        continue;
+ 	    }
  	    if (tdc && (tdc->refCount != 0)) {
  		/* Referenced; can't use it! */
  		continue;
***************
*** 510,521 ****
  		if (tvc) {
  		    tchunkoffset = AFS_CHUNKTOBASE(tdc->f.chunk);
  		    chunkFlags = afs_indexFlags[tdc->index];
! 		    if (phase == 0 && osi_Active(tvc))
! 			skip = 1;
! 		    if (phase > 0 && osi_Active(tvc)
! 			&& (tvc->states & CDCLock)
! 			&& (chunkFlags & IFAnyPages))
! 			skip = 1;
  		    if (chunkFlags & IFDataMod)
  			skip = 1;
  		    afs_Trace4(afs_iclSetp, CM_TRACE_GETDOWND,
--- 646,657 ----
  		if (tvc) {
  		    tchunkoffset = AFS_CHUNKTOBASE(tdc->f.chunk);
  		    chunkFlags = afs_indexFlags[tdc->index];
! 		    if ((((phase / 2) & 1) == 0) && osi_Active(tvc))
!                         skip = 1;
! 		    if ((((phase / 2) & 1) == 1) && osi_Active(tvc)
!                         && (tvc->states & CDCLock)
!                         && (chunkFlags & IFAnyPages))
!                         skip = 1;
  		    if (chunkFlags & IFDataMod)
  			skip = 1;
  		    afs_Trace4(afs_iclSetp, CM_TRACE_GETDOWND,
***************
*** 647,663 ****
  	    afs_PutDCache(tdc);
  	}
  
! 	if (phase == 0) {
  	    /* Phase is 0 and no one was found, so try phase 1 (ignore
  	     * osi_Active flag) */
  	    if (j == 0) {
! 		phase = 1;
  		for (i = 0; i < afs_cacheFiles; i++)
  		    /* turn off all flags */
  		    afs_indexFlags[i] &= ~IFFlag;
  	    }
  	} else {
! 	    /* found no one in phase 1, we're hosed */
  	    if (victimPtr == 0)
  		break;
  	}
--- 783,799 ----
  	    afs_PutDCache(tdc);
  	}
  
! 	if (phase < 5) {
  	    /* Phase is 0 and no one was found, so try phase 1 (ignore
  	     * osi_Active flag) */
  	    if (j == 0) {
! 		phase++;
  		for (i = 0; i < afs_cacheFiles; i++)
  		    /* turn off all flags */
  		    afs_indexFlags[i] &= ~IFFlag;
  	    }
  	} else {
! 	    /* found no one in phases 0-5, we're hosed */
  	    if (victimPtr == 0)
  		break;
  	}
***************
*** 916,921 ****
--- 1052,1059 ----
      afs_CFileTruncate(tfile, 0);
      afs_CFileClose(tfile);
      afs_AdjustSize(tdc, 0);
+     tdc->f.states &= ~(DRO|DBackup|DRW);
+     afs_DCMoveBucket(tdc, 0, 0);
  
      /*
       * Free the element we just truncated
***************
*** 1020,1036 ****
  #endif
  	    }
  
- 	    tdc->stamp = 0;
- #ifdef IHINT
- 	    if (tdc->ihint) {
- 		struct osi_file *f = (struct osi_file *)tdc->ihint;
- 		tdc->ihint = 0;
- 		afs_UFSClose(f);
- 		nihints--;
- 	    }
- #endif /* IHINT */
- 
- 
  	    /* finally put the entry in the free list */
  	    afs_indexTable[ix] = NULL;
  	    afs_indexFlags[ix] &= ~IFEverUsed;
--- 1158,1163 ----
***************
*** 1214,1219 ****
--- 1341,1347 ----
  		break;		/* leaving refCount high for caller */
  	    }
  	    afs_PutDCache(tdc);
+ 	    tdc = NULL;
  	}
  	index = afs_dcnextTbl[index];
      }
***************
*** 1483,1496 ****
  updateV2DC(int lockVc, struct vcache *v, struct dcache *d, int src)
  {
      if (!lockVc || 0 == NBObtainWriteLock(&v->lock, src)) {
! 	if (hsame(v->m.DataVersion, d->f.versionNo) && v->callback) {
! 	    v->quick.dc = d;
! 	    v->quick.stamp = d->stamp = MakeStamp();
! 	    v->quick.minLoc = AFS_CHUNKTOBASE(d->f.chunk);
! 	    /* Don't think I need these next two lines forever */
! 	    v->quick.len = d->f.chunkBytes;
! 	    v->h1.dchint = d;
! 	}
  	if (lockVc)
  	    ReleaseWriteLock(&v->lock);
      }
--- 1611,1618 ----
  updateV2DC(int lockVc, struct vcache *v, struct dcache *d, int src)
  {
      if (!lockVc || 0 == NBObtainWriteLock(&v->lock, src)) {
! 	if (hsame(v->m.DataVersion, d->f.versionNo) && v->callback)
! 	    v->dchint = d;
  	if (lockVc)
  	    ReleaseWriteLock(&v->lock);
      }
***************
*** 1582,1588 ****
      shortcut = 0;
  
      /* check hints first! (might could use bcmp or some such...) */
!     if ((tdc = avc->h1.dchint)) {
  	int dcLocked;
  
  	/*
--- 1704,1710 ----
      shortcut = 0;
  
      /* check hints first! (might could use bcmp or some such...) */
!     if ((tdc = avc->dchint)) {
  	int dcLocked;
  
  	/*
***************
*** 1707,1713 ****
  		while (1) {
  		    if (!setLocks)
  			avc->states |= CDCLock;
! 		    afs_GetDownD(5, (int *)0);	/* just need slots */
  		    if (!setLocks)
  			avc->states &= ~CDCLock;
  		    if (afs_discardDCList != NULLIDX
--- 1829,1836 ----
  		while (1) {
  		    if (!setLocks)
  			avc->states |= CDCLock;
! 		    /* just need slots */
! 		    afs_GetDownD(5, (int *)0, afs_DCGetBucket(avc));
  		    if (!setLocks)
  			avc->states &= ~CDCLock;
  		    if (afs_discardDCList != NULLIDX
***************
*** 1748,1753 ****
--- 1871,1878 ----
  		size =
  		    ((tdc->f.chunkBytes +
  		      afs_fsfragsize) ^ afs_fsfragsize) >> 10;
+ 		tdc->f.states &= ~(DRO|DBackup|DRW);
+ 		afs_DCMoveBucket(tdc, size, 0);
  		afs_blocksDiscarded -= size;
  		afs_stats_cmperf.cacheBlocksDiscarded = afs_blocksDiscarded;
  		if (aflags & 2) {
***************
*** 1772,1777 ****
--- 1897,1909 ----
  	     */
  	    afs_indexFlags[tdc->index] &= ~(IFDirtyPages | IFAnyPages);
  	    tdc->f.fid = avc->fid;
+ 	    if (avc->states & CRO) 
+ 		tdc->f.states = DRO;
+ 	    else if (avc->states & CBackup) 
+ 		tdc->f.states = DBackup;
+ 	    else 
+ 		tdc->f.states = DRW;
+ 	    afs_DCMoveBucket(tdc, 0, afs_DCGetBucket(avc));
  	    afs_indexUnique[tdc->index] = tdc->f.fid.Fid.Unique;
  	    hones(tdc->f.versionNo);	/* invalid value */
  	    tdc->f.chunk = chunk;
***************
*** 1791,1797 ****
  	    afs_dvhashTbl[i] = tdc->index;
  	    tdc->dflags = DFEntryMod;
  	    tdc->mflags = 0;
- 	    tdc->f.states = 0;
  	    afs_MaybeWakeupTruncateDaemon();
  	    MReleaseWriteLock(&afs_xdcache);
  	    ConvertWToSLock(&tdc->lock);
--- 1923,1928 ----
***************
*** 2036,2055 ****
  	 * fetch the whole file.
  	 */
  	DZap(tdc);	/* pages in cache may be old */
! #ifdef  IHINT
! 	if (file = tdc->ihint) {
! 	    if (tdc->f.inode == file->inum)
! 		usedihint++;
! 	    else {
! 		tdc->ihint = 0;
! 		afs_UFSClose(file);
! 		file = 0;
! 		nihints--;
! 		file = osi_UFSOpen(tdc->f.inode);
! 	    }
! 	} else
! #endif /* IHINT */
! 	    file = afs_CFileOpen(tdc->f.inode);
  	afs_RemoveVCB(&avc->fid);
  	tdc->f.states |= DWriting;
  	tdc->dflags |= DFFetching;
--- 2167,2173 ----
  	 * fetch the whole file.
  	 */
  	DZap(tdc);	/* pages in cache may be old */
! 	file = afs_CFileOpen(tdc->f.inode);
  	afs_RemoveVCB(&avc->fid);
  	tdc->f.states |= DWriting;
  	tdc->dflags |= DFFetching;
***************
*** 2414,2419 ****
--- 2532,2539 ----
  	    if (vType(avc) == VDIR) {
  		DZap(tdc);
  	    }
+ 	    tdc->f.states &= ~(DRO|DBackup|DRW);
+ 	    afs_DCMoveBucket(tdc, 0, 0);
  	    ReleaseWriteLock(&tdc->lock);
  	    afs_PutDCache(tdc);
  	    ObtainWriteLock(&afs_xcbhash, 454);
***************
*** 2427,2432 ****
--- 2547,2554 ----
  	     * avc->lock(W); assert(!setLocks || slowPass)
  	     */
  	    osi_Assert(!setLocks || slowPass);
+ 	    tdc->f.states &= ~(DRO|DBackup|DRW);
+ 	    afs_DCMoveBucket(tdc, 0, 0);
  	    tdc = NULL;
  	    goto done;
  	}
***************
*** 2809,2815 ****
      } else {
  	tdc = tmpdc;
  	tdc->f.states = 0;
- 	tdc->ihint = 0;
      }
  
      /*
--- 2931,2936 ----
***************
*** 2837,2842 ****
--- 2958,2975 ----
  #endif
  	lasterrtime = osi_Time();
  	afs_indexUnique[aslot] = tdc->f.fid.Fid.Unique;
+ 	tdc->f.states &= ~(DRO|DBackup|DRW);
+ 	afs_DCMoveBucket(tdc, 0, 0);
+     } else {
+ 	if (&tdc->f != 0) {
+ 	    if (tdc->f.states & DRO) {
+ 		afs_DCMoveBucket(tdc, 0, 2);
+ 	    } else if (tdc->f.states & DBackup) {
+ 		afs_DCMoveBucket(tdc, 0, 1);
+ 	    } else {
+ 		afs_DCMoveBucket(tdc, 0, 1); 
+ 	    }
+ 	} 
      }
      tdc->refCount = 1;
      tdc->index = aslot;
***************
*** 3060,3065 ****
--- 3193,3200 ----
  	tdc->f.fid.Fid.Volume = 0;	/* not in the hash table */
  	if (tstat.size != 0)
  	    osi_UFSTruncate(tfile, 0);
+ 	tdc->f.states &= ~(DRO|DBackup|DRW);
+ 	afs_DCMoveBucket(tdc, 0, 0);
  	/* put entry in free cache slot list */
  	afs_dvnextTbl[tdc->index] = afs_freeDCList;
  	afs_freeDCList = index;
***************
*** 3234,3239 ****
--- 3369,3378 ----
  
      afs_dcentries = aDentries;
      afs_blocksUsed = 0;
+     afs_stats_cmperf.cacheBucket0_Discarded = 
+ 	afs_stats_cmperf.cacheBucket1_Discarded = 
+ 	afs_stats_cmperf.cacheBucket2_Discarded = 0;
+     afs_DCSizeInit();
      QInit(&afs_DLRU);
  }
  
***************
*** 3274,3279 ****
--- 3413,3421 ----
      afs_osi_Free(afs_dchashTbl, afs_dhashsize * sizeof(afs_int32));
  
      afs_blocksUsed = afs_dcentries = 0;
+     afs_stats_cmperf.cacheBucket0_Discarded = 
+ 	afs_stats_cmperf.cacheBucket1_Discarded = 
+ 	afs_stats_cmperf.cacheBucket2_Discarded = 0;
      hzero(afs_indexCounter);
  
      afs_freeDCCount = 0;
Index: openafs/src/afs/afs_memcache.c
diff -c openafs/src/afs/afs_memcache.c:1.15.2.3 openafs/src/afs/afs_memcache.c:1.15.2.4
*** openafs/src/afs/afs_memcache.c:1.15.2.3	Sun Apr  3 14:15:36 2005
--- openafs/src/afs/afs_memcache.c	Mon May 30 00:36:58 2005
***************
*** 11,17 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_memcache.c,v 1.15.2.3 2005/04/03 18:15:36 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #ifndef AFS_LINUX22_ENV
--- 11,17 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_memcache.c,v 1.15.2.4 2005/05/30 04:36:58 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #ifndef AFS_LINUX22_ENV
***************
*** 103,111 ****
  	osi_Panic("afs_MemCacheOpen: invalid block #");
      }
      mep = (memCache + blkno);
!     afs_Trace4(afs_iclSetp, CM_TRACE_MEMOPEN, ICL_TYPE_INT32, blkno,
! 	       ICL_TYPE_POINTER, mep, ICL_TYPE_POINTER, mep->data,
! 	       ICL_TYPE_STRING, mep->data);
      return (void *)mep;
  }
  
--- 103,110 ----
  	osi_Panic("afs_MemCacheOpen: invalid block #");
      }
      mep = (memCache + blkno);
!     afs_Trace3(afs_iclSetp, CM_TRACE_MEMOPEN, ICL_TYPE_INT32, blkno,
! 	       ICL_TYPE_POINTER, mep, ICL_TYPE_POINTER, mep ? mep->data : 0);
      return (void *)mep;
  }
  
Index: openafs/src/afs/afs_osi.h
diff -c openafs/src/afs/afs_osi.h:1.22.2.8 openafs/src/afs/afs_osi.h:1.22.2.9
*** openafs/src/afs/afs_osi.h:1.22.2.8	Sun Apr 24 19:40:40 2005
--- openafs/src/afs/afs_osi.h	Mon May 23 17:09:37 2005
***************
*** 190,195 ****
--- 190,197 ----
  typedef struct timeval osi_timeval_t;
  #endif /* AFS_SGI61_ENV */
  
+ #define osi_getpid() 		getpid()
+ 
  /*
   * osi_ThreadUnique() should yield a value that can be found in ps
   * output in order to draw correspondences between ICL traces and what
Index: openafs/src/afs/afs_osi_pag.c
diff -c openafs/src/afs/afs_osi_pag.c:1.21.2.3 openafs/src/afs/afs_osi_pag.c:1.21.2.4
*** openafs/src/afs/afs_osi_pag.c:1.21.2.3	Sun Jan 30 23:19:20 2005
--- openafs/src/afs/afs_osi_pag.c	Mon May 23 17:09:37 2005
***************
*** 23,29 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_osi_pag.c,v 1.21.2.3 2005/01/31 04:19:20 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/afs_osi_pag.c,v 1.21.2.4 2005/05/23 21:09:37 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 141,179 ****
  
  static int afs_pag_sleepcnt = 0;
  
! static int 
! afs_pag_sleep(struct AFS_UCRED **acred) 
  {
!   int rv = 0;
!   if(!afs_suser(acred)) {
!     if(osi_Time() - pag_epoch < pagCounter) {
!       rv = 1;
      }
-   }
  
!   return rv;
  }
  
! static int 
  afs_pag_wait(struct AFS_UCRED **acred)
  {
!   if(afs_pag_sleep(acred)) {
!     if(!afs_pag_sleepcnt) {
!       printf("%s() PAG throttling triggered, pid %d... sleeping.  sleepcnt %d\n",
! 	     "afs_pag_wait", getpid(), afs_pag_sleepcnt);
!     }
!     
!     afs_pag_sleepcnt++;
!     
!     do {
!       /* XXX spins on EINTR */
!       afs_osi_Wait(1000, (struct afs_osi_WaitHandle *)0, 0);
!     } while(afs_pag_sleep(acred));
!     
!     afs_pag_sleepcnt--;
!   }
  
!   return 0;
  }
  
  int
--- 141,180 ----
  
  static int afs_pag_sleepcnt = 0;
  
! static int
! afs_pag_sleep(struct AFS_UCRED **acred)
  {
!     int rv = 0;
! 
!     if (!afs_suser(acred)) {
! 	if(osi_Time() - pag_epoch < pagCounter) {
! 	    rv = 1;
! 	}
      }
  
!     return rv;
  }
  
! static int
  afs_pag_wait(struct AFS_UCRED **acred)
  {
!     if (afs_pag_sleep(acred)) {
! 	if (!afs_pag_sleepcnt) {
! 	    printf("%s() PAG throttling triggered, pid %d... sleeping.  sleepcnt %d\n",
! 		   "afs_pag_wait", osi_getpid(), afs_pag_sleepcnt);
! 	}
! 
! 	afs_pag_sleepcnt++;
  
! 	do {
! 	    /* XXX spins on EINTR */
! 	    afs_osi_Wait(1000, (struct afs_osi_WaitHandle *)0, 0);
! 	} while (afs_pag_sleep(acred));
! 
! 	afs_pag_sleepcnt--;
!     }
! 
!     return 0;
  }
  
  int
Index: openafs/src/afs/afs_pioctl.c
diff -c openafs/src/afs/afs_pioctl.c:1.81.2.13 openafs/src/afs/afs_pioctl.c:1.81.2.17
*** openafs/src/afs/afs_pioctl.c:1.81.2.13	Sun Apr 24 16:12:39 2005
--- openafs/src/afs/afs_pioctl.c	Mon May 30 00:05:41 2005
***************
*** 11,17 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_pioctl.c,v 1.81.2.13 2005/04/24 20:12:39 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.81.2.17 2005/05/30 04:05:41 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #ifdef AFS_OBSD_ENV
***************
*** 71,76 ****
--- 71,77 ----
  DECL_PIOCTL(PSetCellStatus);
  DECL_PIOCTL(PFlushVolumeData);
  DECL_PIOCTL(PGetVnodeXStatus);
+ DECL_PIOCTL(PGetVnodeXStatus2);
  DECL_PIOCTL(PSetSysName);
  DECL_PIOCTL(PSetSPrefs);
  DECL_PIOCTL(PSetSPrefs33);
***************
*** 183,188 ****
--- 184,190 ----
  	PPrefetchFromTape,	/* 66 -- MR-AFS: prefetch file from tape */
  	PResidencyCmd,		/* 67 -- MR-AFS: generic commnd interface */
  	PBogus,			/* 68 -- arla: fetch stats */
+ 	PGetVnodeXStatus2,	/* 69 - get caller access and some vcache status */
  };
  
  static int (*(CpioctlSw[])) () = {
***************
*** 263,269 ****
  #if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
      struct afs_ioctl32 dst32;
  
! #ifdef AFS_SPARC64_LINUX24_ENV
      if (current->thread.flags & SPARC_FLAG_32BIT)
  #elif defined(AFS_SPARC64_LINUX20_ENV)
      if (current->tss.flags & SPARC_FLAG_32BIT)
--- 265,273 ----
  #if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
      struct afs_ioctl32 dst32;
  
! #ifdef AFS_SPARC64_LINUX26_ENV
!     if (test_thread_flag(TIF_32BIT))
! #elif AFS_SPARC64_LINUX24_ENV
      if (current->thread.flags & SPARC_FLAG_32BIT)
  #elif defined(AFS_SPARC64_LINUX20_ENV)
      if (current->tss.flags & SPARC_FLAG_32BIT)
***************
*** 1665,1671 ****
      /* now find the disk cache entries */
      afs_TryToSmush(avc, *acred, 1);
      osi_dnlc_purgedp(avc);
-     afs_symhint_inval(avc);
      if (avc->linkData && !(avc->states & CCore)) {
  	afs_osi_Free(avc->linkData, strlen(avc->linkData) + 1);
  	avc->linkData = NULL;
--- 1669,1674 ----
***************
*** 2539,2546 ****
       * the vcaches associated with the volume.
       */
      ObtainReadLock(&afs_xvcache);
!     for (i = 0; i < VCSIZE; i++) {
! 	for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
  	    if (tvc->fid.Fid.Volume == volume && tvc->fid.Cell == cell) {
  #if	defined(AFS_SGI_ENV) || defined(AFS_OSF_ENV)  || defined(AFS_SUN5_ENV)  || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
  		VN_HOLD(AFSTOV(tvc));
--- 2542,2549 ----
       * the vcaches associated with the volume.
       */
      ObtainReadLock(&afs_xvcache);
!     i = VCHashV(&avc->fid);
!     for (tvc = afs_vhashT[i]; tvc; tvc = tvc->vhnext) {
  	    if (tvc->fid.Fid.Volume == volume && tvc->fid.Cell == cell) {
  #if	defined(AFS_SGI_ENV) || defined(AFS_OSF_ENV)  || defined(AFS_SUN5_ENV)  || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
  		VN_HOLD(AFSTOV(tvc));
***************
*** 2573,2579 ****
  		AFS_FAST_RELE(tvc);
  	    }
  	}
-     }
      ReleaseReadLock(&afs_xvcache);
  
  
--- 2576,2581 ----
***************
*** 2640,2645 ****
--- 2642,2649 ----
  	mode = PRSFS_READ;
      if (!afs_AccessOK(avc, mode, areq, CHECK_MODE_BITS))
  	return EACCES;
+ 
+     memset(&stat, 0, sizeof(struct vcxstat));
      stat.fid = avc->fid;
      hset32(stat.DataVersion, hgetlo(avc->m.DataVersion));
      stat.lock = avc->lock;
***************
*** 2670,2675 ****
--- 2674,2709 ----
  }
  
  
+ DECL_PIOCTL(PGetVnodeXStatus2)
+ {
+     register afs_int32 code;
+     struct vcxstat2 stat;
+     afs_int32 mode;
+ 
+     if (!avc)
+         return EINVAL;
+     code = afs_VerifyVCache(avc, areq);
+     if (code)
+         return code;
+     if (vType(avc) == VDIR)
+         mode = PRSFS_LOOKUP;
+     else
+         mode = PRSFS_READ;
+     if (!afs_AccessOK(avc, mode, areq, CHECK_MODE_BITS))
+         return EACCES;
+ 
+     memset(&stat, 0, sizeof(struct vcxstat2));
+ 
+     stat.cbExpires = avc->cbExpires;
+     stat.anyAccess = avc->anyAccess;
+     stat.mvstat = avc->mvstat;
+     stat.callerAccess = afs_GetAccessBits(avc, ~0, areq);
+ 
+     memcpy(aout, (char *)&stat, sizeof(struct vcxstat2));
+     *aoutSize = sizeof(struct vcxstat2);
+     return 0;
+ }
+ 
  /* We require root for local sysname changes, but not for remote */
  /* (since we don't really believe remote uids anyway) */
   /* outname[] shouldn't really be needed- this is left as an excercise */
***************
*** 3526,3532 ****
      /* now find the disk cache entries */
      afs_TryToSmush(tvc, *acred, 1);
      osi_dnlc_purgedp(tvc);
-     afs_symhint_inval(tvc);
      if (tvc->linkData && !(tvc->states & CCore)) {
  	afs_osi_Free(tvc->linkData, strlen(tvc->linkData) + 1);
  	tvc->linkData = NULL;
--- 3560,3565 ----
Index: openafs/src/afs/afs_prototypes.h
diff -c openafs/src/afs/afs_prototypes.h:1.53.2.7 openafs/src/afs/afs_prototypes.h:1.53.2.8
*** openafs/src/afs/afs_prototypes.h:1.53.2.7	Sun Apr 24 16:11:14 2005
--- openafs/src/afs/afs_prototypes.h	Sun May  8 01:04:14 2005
***************
*** 297,302 ****
--- 297,303 ----
  extern afs_int32 afs_blocksDiscarded;
  extern int afs_WaitForCacheDrain;
  extern int cacheDiskType;
+ extern afs_uint32 afs_tpct1, afs_tpct2, splitdcache;
  extern unsigned char *afs_indexFlags;
  extern struct afs_cacheOps *afs_cacheType;
  extern ino_t cacheInode;
Index: openafs/src/afs/afs_stats.h
diff -c openafs/src/afs/afs_stats.h:1.11.2.2 openafs/src/afs/afs_stats.h:1.11.2.3
*** openafs/src/afs/afs_stats.h:1.11.2.2	Tue Dec  7 01:12:12 2004
--- openafs/src/afs/afs_stats.h	Sun May  8 01:04:14 2005
***************
*** 802,811 ****
      afs_uint32 cbloops;
      afs_uint32 osiread_efaults;
      afs_int32 cacheBlocksDiscarded;	/*# cache blocks free but not truncated */
      /*
       * Spares for future expansion.
       */
!     afs_int32 spare[13];	/*Spares */
  };
  
  
--- 802,815 ----
      afs_uint32 cbloops;
      afs_uint32 osiread_efaults;
      afs_int32 cacheBlocksDiscarded;	/*# cache blocks free but not truncated */
+     afs_int32 cacheBucket0_Discarded;  
+     afs_int32 cacheBucket1_Discarded;  
+     afs_int32 cacheBucket2_Discarded;  
+ 
      /*
       * Spares for future expansion.
       */
!     afs_int32 spare[10];	/*Spares */
  };
  
  
Index: openafs/src/afs/afs_trace.et
diff -c openafs/src/afs/afs_trace.et:1.17 openafs/src/afs/afs_trace.et:1.17.2.1
*** openafs/src/afs/afs_trace.et:1.17	Wed Jul 16 18:22:54 2003
--- openafs/src/afs/afs_trace.et	Mon May 30 00:36:58 2005
***************
*** 145,151 ****
  	ec	CM_TRACE_MEMFETCH, "MemFetch: vp 0x%lx  mceP 0x%lx offset (0x%x, 0x%x) length 0x%x"
  	ec	CM_TRACE_VMWRITE3, "afs_vm_rdwr: vp 0x%lx code %d"
  	ec	CM_TRACE_STOREALL2, "StoreAll 2 vp 0x%lx chunk 0x%x index %d inode %d"
! 	ec	CM_TRACE_MEMOPEN, "MemOpen blkno %d mceP 0x%x data 0x%x = %s"
  	ec	CM_TRACE_VCACHE2INODE, "vcache2inode: avc 0x%x event %d"
  	ec	CM_TRACE_STOREDATA64, "StoreData64: fid (%d:%d.%d.%d) offs (0x%x, 0x%x) len (0x%x, 0x%x) file length (0x%x, 0x%x)"
  	ec	CM_TRACE_RESIDCMD, "ResidencyCmd tvc 0x%x command %d fid (%d:%d.%d.%d)"
--- 145,151 ----
  	ec	CM_TRACE_MEMFETCH, "MemFetch: vp 0x%lx  mceP 0x%lx offset (0x%x, 0x%x) length 0x%x"
  	ec	CM_TRACE_VMWRITE3, "afs_vm_rdwr: vp 0x%lx code %d"
  	ec	CM_TRACE_STOREALL2, "StoreAll 2 vp 0x%lx chunk 0x%x index %d inode %d"
! 	ec	CM_TRACE_MEMOPEN, "MemOpen blkno %d mceP 0x%x data 0x%x"
  	ec	CM_TRACE_VCACHE2INODE, "vcache2inode: avc 0x%x event %d"
  	ec	CM_TRACE_STOREDATA64, "StoreData64: fid (%d:%d.%d.%d) offs (0x%x, 0x%x) len (0x%x, 0x%x) file length (0x%x, 0x%x)"
  	ec	CM_TRACE_RESIDCMD, "ResidencyCmd tvc 0x%x command %d fid (%d:%d.%d.%d)"
Index: openafs/src/afs/afs_vcache.c
diff -c openafs/src/afs/afs_vcache.c:1.65.2.18 openafs/src/afs/afs_vcache.c:1.65.2.20
*** openafs/src/afs/afs_vcache.c:1.65.2.18	Sat Apr 23 20:58:04 2005
--- openafs/src/afs/afs_vcache.c	Mon May 30 00:05:41 2005
***************
*** 39,45 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_vcache.c,v 1.65.2.18 2005/04/24 00:58:04 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
--- 39,45 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_vcache.c,v 1.65.2.20 2005/05/30 04:05:41 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
***************
*** 69,74 ****
--- 69,75 ----
  afs_int32 vcachegen = 0;
  unsigned int afs_paniconwarn = 0;
  struct vcache *afs_vhashT[VCSIZE];
+ struct vcache *afs_vhashTV[VCSIZE];
  static struct afs_cbr *afs_cbrHashT[CBRSIZE];
  afs_int32 afs_bulkStatsLost;
  int afs_norefpanic = 0;
***************
*** 129,136 ****
  afs_FlushVCache(struct vcache *avc, int *slept)
  {				/*afs_FlushVCache */
  
!     register afs_int32 i, code;
!     register struct vcache **uvc, *wvc;
  
      *slept = 0;
      AFS_STATCNT(afs_FlushVCache);
--- 130,137 ----
  afs_FlushVCache(struct vcache *avc, int *slept)
  {				/*afs_FlushVCache */
  
!     afs_int32 i, code, j;
!     struct vcache **uvc, *wvc, **uvc2, *wvc2;
  
      *slept = 0;
      AFS_STATCNT(afs_FlushVCache);
***************
*** 174,180 ****
  	    break;
  	}
      }
!     if (!wvc)
  	osi_Panic("flushvcache");	/* not in correct hash bucket */
      if (avc->mvid)
  	osi_FreeSmallSpace(avc->mvid);
--- 175,192 ----
  	    break;
  	}
      }
! 
!     /* remove entry from the volume hash table */
!     j = VCHashV(&avc->fid);
!     uvc2 = &afs_vhashTV[j];
!     for (wvc2 = *uvc2; wvc2; uvc2 = &wvc2->vhnext, wvc2 = *uvc2) {
!         if (avc == wvc2) {
!             *uvc2 = avc->vhnext;
!             avc->vhnext = (struct vcache *)NULL;
!             break;
!         }
!     }
!     if (!wvc || !wvc2)
  	osi_Panic("flushvcache");	/* not in correct hash bucket */
      if (avc->mvid)
  	osi_FreeSmallSpace(avc->mvid);
***************
*** 204,210 ****
      afs_DequeueCallback(avc);	/* remove it from queued callbacks list */
      avc->states &= ~(CStatd | CUnique);
      ReleaseWriteLock(&afs_xcbhash);
-     afs_symhint_inval(avc);
      if ((avc->states & CForeign) || (avc->fid.Fid.Vnode & 1))
  	osi_dnlc_purgedp(avc);	/* if it (could be) a directory */
      else
--- 216,221 ----
***************
*** 576,582 ****
  afs_NewVCache(struct VenusFid *afid, struct server *serverp)
  {
      struct vcache *tvc;
!     afs_int32 i;
      afs_int32 anumber = VCACHE_FREE;
  #ifdef	AFS_AIX_ENV
      struct gnode *gnodepnt;
--- 587,593 ----
  afs_NewVCache(struct VenusFid *afid, struct server *serverp)
  {
      struct vcache *tvc;
!     afs_int32 i, j;
      afs_int32 anumber = VCACHE_FREE;
  #ifdef	AFS_AIX_ENV
      struct gnode *gnodepnt;
***************
*** 854,860 ****
      tvc->fid = *afid;
      tvc->asynchrony = -1;
      tvc->vc_error = 0;
-     afs_symhint_inval(tvc);
  #ifdef AFS_TEXT_ENV
      tvc->flushDV.low = tvc->flushDV.high = AFS_MAXDV;
  #endif
--- 865,870 ----
***************
*** 1068,1082 ****
      vn_initlist((struct vnlist *)&tvc->v);
      tvc->lastr = 0;
  #endif /* AFS_SGI_ENV */
!     tvc->h1.dchint = 0;
      osi_dnlc_purgedp(tvc);	/* this may be overkill */
-     memset((char *)&(tvc->quick), 0, sizeof(struct vtodc));
      memset((char *)&(tvc->callsort), 0, sizeof(struct afs_q));
      tvc->slocks = NULL;
      i = VCHash(afid);
  
      tvc->hnext = afs_vhashT[i];
!     afs_vhashT[i] = tvc;
      if ((VLRU.next->prev != &VLRU) || (VLRU.prev->next != &VLRU)) {
  	refpanic("NewVCache VLRU inconsistent");
      }
--- 1078,1094 ----
      vn_initlist((struct vnlist *)&tvc->v);
      tvc->lastr = 0;
  #endif /* AFS_SGI_ENV */
!     tvc->dchint = NULL;
      osi_dnlc_purgedp(tvc);	/* this may be overkill */
      memset((char *)&(tvc->callsort), 0, sizeof(struct afs_q));
      tvc->slocks = NULL;
      i = VCHash(afid);
+     j = VCHashV(afid);
  
      tvc->hnext = afs_vhashT[i];
!     tvc->vhnext = afs_vhashTV[j];
!     afs_vhashT[i] = afs_vhashTV[j] = tvc;
! 
      if ((VLRU.next->prev != &VLRU) || (VLRU.prev->next != &VLRU)) {
  	refpanic("NewVCache VLRU inconsistent");
      }
***************
*** 2224,2231 ****
      XSTATS_DECLS;
      do {
  	tc = afs_Conn(afid, areq, SHARED_LOCK);
! 	avc->quick.stamp = 0;
! 	avc->h1.dchint = NULL;	/* invalidate hints */
  	if (tc) {
  	    avc->callback = tc->srvr->server;
  	    start = osi_Time();
--- 2236,2242 ----
      XSTATS_DECLS;
      do {
  	tc = afs_Conn(afid, areq, SHARED_LOCK);
! 	avc->dchint = NULL;	/* invalidate hints */
  	if (tc) {
  	    avc->callback = tc->srvr->server;
  	    start = osi_Time();
***************
*** 2861,2867 ****
  
  		afs_FreeAllAxs(&(tvc->Access));
  	    }
! 	    afs_vhashT[i] = 0;
  	}
      }
      /*
--- 2872,2878 ----
  
  		afs_FreeAllAxs(&(tvc->Access));
  	    }
! 	    afs_vhashT[i] = afs_vhashTV[i] = 0;
  	}
      }
      /*
Index: openafs/src/afs/FBSD/osi_machdep.h
diff -c openafs/src/afs/FBSD/osi_machdep.h:1.9.2.2 openafs/src/afs/FBSD/osi_machdep.h:1.9.2.3
*** openafs/src/afs/FBSD/osi_machdep.h:1.9.2.2	Sat Apr 23 20:58:05 2005
--- openafs/src/afs/FBSD/osi_machdep.h	Mon May 23 17:09:37 2005
***************
*** 72,84 ****
  extern struct vop_vector afs_vnodeops;
  #endif
  
  #if defined(AFS_FBSD50_ENV)
  #define VT_AFS		"afs"
  #define VROOT		VV_ROOT
  #define v_flag		v_vflag
  #define osi_curcred()	(curthread->td_ucred)
  #define afs_suser(x)	(!suser(curthread))
! #define getpid()	(curthread->td_proc->p_pid)
  #define simple_lock(x)	mtx_lock(x)
  #define simple_unlock(x) mtx_unlock(x)
  #define        gop_rdwr(rw,gp,base,len,offset,segflg,unit,cred,aresid) \
--- 72,85 ----
  extern struct vop_vector afs_vnodeops;
  #endif
  
+ #undef osi_getpid
  #if defined(AFS_FBSD50_ENV)
  #define VT_AFS		"afs"
  #define VROOT		VV_ROOT
  #define v_flag		v_vflag
  #define osi_curcred()	(curthread->td_ucred)
  #define afs_suser(x)	(!suser(curthread))
! #define osi_getpid()	(curthread->td_proc->p_pid)
  #define simple_lock(x)	mtx_lock(x)
  #define simple_unlock(x) mtx_unlock(x)
  #define        gop_rdwr(rw,gp,base,len,offset,segflg,unit,cred,aresid) \
***************
*** 93,99 ****
  
  #define osi_curcred()	(curproc->p_cred->pc_ucred)
  #define afs_suser(x)	(!suser(curproc))
! #define getpid()	(curproc->p_pid)
  #define        gop_rdwr(rw,gp,base,len,offset,segflg,unit,cred,aresid) \
    vn_rdwr((rw),(gp),(base),(len),(offset),(segflg),(unit),(cred),(aresid), curproc)
  extern struct proc *afs_global_owner;
--- 94,100 ----
  
  #define osi_curcred()	(curproc->p_cred->pc_ucred)
  #define afs_suser(x)	(!suser(curproc))
! #define osi_getpid()	(curproc->p_pid)
  #define        gop_rdwr(rw,gp,base,len,offset,segflg,unit,cred,aresid) \
    vn_rdwr((rw),(gp),(base),(len),(offset),(segflg),(unit),(cred),(aresid), curproc)
  extern struct proc *afs_global_owner;
Index: openafs/src/afs/FBSD/osi_module.c
diff -c openafs/src/afs/FBSD/osi_module.c:1.5.2.1 openafs/src/afs/FBSD/osi_module.c:1.5.2.2
*** openafs/src/afs/FBSD/osi_module.c:1.5.2.1	Tue Nov  9 12:11:34 2004
--- openafs/src/afs/FBSD/osi_module.c	Mon May 23 17:23:53 2005
***************
*** 12,41 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/FBSD/osi_module.c,v 1.5.2.1 2004/11/09 17:11:34 shadow Exp $");
  
  #include <afs/sysincludes.h>
  #include <afsincludes.h>
  #include <sys/module.h>
  #include <sys/sysproto.h>
  #include <sys/syscall.h>
- #include <sys/sysent.h>
  
  extern struct vfsops afs_vfsops;
  extern struct vnodeopv_desc afs_vnodeop_opv_desc;
  extern struct mount *afs_globalVFS;
- static struct vfsconf afs_vfsconf;
  
  MALLOC_DEFINE(M_AFS, "afsmisc", "memory used by the AFS filesystem");
  
! extern int afs3_syscall();
! extern int Afs_xsetgroups();
! extern int afs_xioctl();
  
  int
  afs_module_handler(module_t mod, int what, void *arg)
  {
-     static sy_call_t *old_handler;
      static int inited = 0;
      int error = 0;
  
--- 12,50 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/FBSD/osi_module.c,v 1.5.2.2 2005/05/23 21:23:53 shadow Exp $");
  
  #include <afs/sysincludes.h>
  #include <afsincludes.h>
  #include <sys/module.h>
  #include <sys/sysproto.h>
  #include <sys/syscall.h>
  
  extern struct vfsops afs_vfsops;
  extern struct vnodeopv_desc afs_vnodeop_opv_desc;
  extern struct mount *afs_globalVFS;
  
  MALLOC_DEFINE(M_AFS, "afsmisc", "memory used by the AFS filesystem");
  
! #ifdef AFS_FBSD60_ENV
! VFS_SET(afs_vfsops, afs, VFCF_NETWORK);
! #else
! int afs_module_handler(module_t mod, int what, void *arg);
! 
! static struct vfsconf afs_vfsconf;
! static moduledata_t afs_mod = {
!     "afs",
!     afs_module_handler,
!     &afs_mod
! };
  
+ DECLARE_MODULE(afs, afs_mod, SI_SUB_VFS, SI_ORDER_MIDDLE);
+ #endif
+ 
+ #ifndef AFS_FBSD60_ENV
  int
  afs_module_handler(module_t mod, int what, void *arg)
  {
      static int inited = 0;
      int error = 0;
  
***************
*** 46,57 ****
  	    error = EBUSY;
  	    break;
  	}
- 	if (sysent[AFS_SYSCALL].sy_call != nosys
- 	    && sysent[AFS_SYSCALL].sy_call != lkmnosys) {
- 	    printf("AFS_SYSCALL in use. aborting\n");
- 	    error = EBUSY;
- 	    break;
- 	}
  	memset(&afs_vfsconf, 0, sizeof(struct vfsconf));
  #ifdef AFS_FBSD53_ENV
  	afs_vfsconf.vfc_version = VFS_VERSION;
--- 55,60 ----
***************
*** 63,76 ****
  	if ((error = vfs_register(&afs_vfsconf)) != 0)
  	    break;
  	vfs_add_vnodeops(&afs_vnodeop_opv_desc);
- 	osi_Init();
- #if 0
- 	sysent[SYS_setgroups].sy_call = Afs_xsetgroups;
- 	sysent[SYS_ioctl].sy_call = afs_xioctl;
- #endif
- 	old_handler = sysent[AFS_SYSCALL].sy_call;
- 	sysent[AFS_SYSCALL].sy_call = afs3_syscall;
- 	sysent[AFS_SYSCALL].sy_narg = 5;
  	inited = 1;
  	break;
      case MOD_UNLOAD:
--- 66,71 ----
***************
*** 83,113 ****
  	    error = 0;
  	    break;
  	}
- 	if (afs_globalVFS) {
- 	    error = EBUSY;
- 	    break;
- 	}
  	if ((error = vfs_unregister(&afs_vfsconf)) != 0) {
  	    break;
  	}
  	vfs_rm_vnodeops(&afs_vnodeop_opv_desc);
- #if 0
- 	sysent[SYS_ioctl].sy_call = ioctl;
- 	sysent[SYS_setgroups].sy_call = setgroups;
- #endif
- 	sysent[AFS_SYSCALL].sy_narg = 0;
- 	sysent[AFS_SYSCALL].sy_call = old_handler;
  	break;
      }
  
      return (error);
  }
! 
! 
! static moduledata_t afs_mod = {
!     "afs",
!     afs_module_handler,
!     &afs_mod
! };
! 
! DECLARE_MODULE(afs, afs_mod, SI_SUB_VFS, SI_ORDER_MIDDLE);
--- 78,90 ----
  	    error = 0;
  	    break;
  	}
  	if ((error = vfs_unregister(&afs_vfsconf)) != 0) {
  	    break;
  	}
  	vfs_rm_vnodeops(&afs_vnodeop_opv_desc);
  	break;
      }
  
      return (error);
  }
! #endif
Index: openafs/src/afs/FBSD/osi_prototypes.h
diff -c openafs/src/afs/FBSD/osi_prototypes.h:1.5.2.1 openafs/src/afs/FBSD/osi_prototypes.h:1.5.2.2
*** openafs/src/afs/FBSD/osi_prototypes.h:1.5.2.1	Fri Mar 11 01:50:37 2005
--- openafs/src/afs/FBSD/osi_prototypes.h	Mon May 23 17:23:53 2005
***************
*** 24,29 ****
--- 24,31 ----
  extern void osi_fbsd_free(void *p);
  
  /* osi_vfsops.c */
+ int afs_init(struct vfsconf *vfc);
+ int afs_uninit(struct vfsconf *vfc);
  #ifdef AFS_FBSD50_ENV
  extern int afs_statfs(struct mount *mp, struct statfs *abp, struct thread *th);
  #else
Index: openafs/src/afs/FBSD/osi_vfsops.c
diff -c openafs/src/afs/FBSD/osi_vfsops.c:1.16.2.2 openafs/src/afs/FBSD/osi_vfsops.c:1.16.2.4
*** openafs/src/afs/FBSD/osi_vfsops.c:1.16.2.2	Sat Apr 23 20:58:05 2005
--- openafs/src/afs/FBSD/osi_vfsops.c	Mon May 23 17:26:40 2005
***************
*** 2,8 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/FBSD/osi_vfsops.c,v 1.16.2.2 2005/04/24 00:58:05 shadow Exp $");
  
  #include <afs/sysincludes.h>	/* Standard vendor system headers */
  #include <afsincludes.h>	/* Afs-based standard headers */
--- 2,8 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/FBSD/osi_vfsops.c,v 1.16.2.4 2005/05/23 21:26:40 shadow Exp $");
  
  #include <afs/sysincludes.h>	/* Standard vendor system headers */
  #include <afsincludes.h>	/* Afs-based standard headers */
***************
*** 10,16 ****
--- 10,19 ----
  #include <sys/malloc.h>
  #include <sys/namei.h>
  #include <sys/conf.h>
+ #include <sys/module.h>
+ #include <sys/sysproto.h>
  #include <sys/syscall.h>
+ #include <sys/sysent.h>
  
  struct vcache *afs_globalVp = NULL;
  struct mount *afs_globalVFS = NULL;
***************
*** 22,43 ****
  #define	THREAD_OR_PROC struct proc *p
  #endif
  
  int
! afs_start(struct mount *mp, int flags, THREAD_OR_PROC)
  {
      afs_pbuf_freecnt = nswbuf / 2 + 1;
!     return (0);			/* nothing to do. ? */
  }
  
- #ifdef AFS_FBSD53_ENV
  int
! afs_mount(struct mount *mp, struct thread *td)
  {
!     int afs_omount(struct mount *mp, char *path, caddr_t data, struct thread *p);
  
!     return afs_omount(mp, NULL, NULL, td);
  }
- #endif
  
  int
  #ifdef AFS_FBSD53_ENV
--- 25,76 ----
  #define	THREAD_OR_PROC struct proc *p
  #endif
  
+ extern int afs3_syscall();
+ extern int Afs_xsetgroups();
+ extern int afs_xioctl();
+ 
+ static sy_call_t *old_handler;
+ 
+ 
  int
! afs_init(struct vfsconf *vfc)
  {
+     if (sysent[AFS_SYSCALL].sy_call != nosys
+ 	&& sysent[AFS_SYSCALL].sy_call != lkmnosys) {
+ 	printf("AFS_SYSCALL in use. aborting\n");
+ 	return EBUSY;
+     }
+     osi_Init();
      afs_pbuf_freecnt = nswbuf / 2 + 1;
! #if 0
!     sysent[SYS_setgroups].sy_call = Afs_xsetgroups;
!     sysent[SYS_ioctl].sy_call = afs_xioctl;
! #endif
!     old_handler = sysent[AFS_SYSCALL].sy_call;
!     sysent[AFS_SYSCALL].sy_call = afs3_syscall;
!     sysent[AFS_SYSCALL].sy_narg = 5;
!     return 0;
  }
  
  int
! afs_uninit(struct vfsconf *vfc)
  {
!     if (afs_globalVFS)
! 	return EBUSY;
! #if 0
!     sysent[SYS_ioctl].sy_call = ioctl;
!     sysent[SYS_setgroups].sy_call = setgroups;
! #endif
!     sysent[AFS_SYSCALL].sy_narg = 0;
!     sysent[AFS_SYSCALL].sy_call = old_handler;
!     return 0;
! }
  
! int
! afs_start(struct mount *mp, int flags, THREAD_OR_PROC)
! {
!     return (0);			/* nothing to do. ? */
  }
  
  int
  #ifdef AFS_FBSD53_ENV
***************
*** 67,84 ****
      vfs_getnewfsid(mp);
      mp->mnt_stat.f_iosize = 8192;
  
!     if (path)
! 	(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
      memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size);
      memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN);
      strcpy(mp->mnt_stat.f_mntfromname, "AFS");
      /* null terminated string "AFS" will fit, just leave it be. */
      strcpy(mp->mnt_stat.f_fstypename, "afs");
      AFS_GUNLOCK();
!     (void)afs_statfs(mp, &mp->mnt_stat, p);
      return 0;
  }
  
  #ifdef AFS_FBSD60_ENV
  static int
  afs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td)
--- 100,127 ----
      vfs_getnewfsid(mp);
      mp->mnt_stat.f_iosize = 8192;
  
!     if (path != NULL)
! 	copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
!     else
! 	bcopy("/afs", mp->mnt_stat.f_mntonname, size = 4);
      memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size);
      memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN);
      strcpy(mp->mnt_stat.f_mntfromname, "AFS");
      /* null terminated string "AFS" will fit, just leave it be. */
      strcpy(mp->mnt_stat.f_fstypename, "afs");
      AFS_GUNLOCK();
!     afs_statfs(mp, &mp->mnt_stat, p);
      return 0;
  }
  
+ #ifdef AFS_FBSD53_ENV
+ int
+ afs_mount(struct mount *mp, struct thread *td)
+ {
+     return afs_omount(mp, NULL, NULL, td);
+ }
+ #endif
+ 
  #ifdef AFS_FBSD60_ENV
  static int
  afs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td)
***************
*** 228,239 ****
      return 0;
  }
  
- int
- afs_init(struct vfsconf *vfc)
- {
-     return 0;
- }
- 
  #ifdef AFS_FBSD60_ENV
  struct vfsops afs_vfsops = {
  	.vfs_init =		afs_init,
--- 271,276 ----
***************
*** 242,248 ****
  	.vfs_root =		afs_root,
  	.vfs_statfs =		afs_statfs,
  	.vfs_sync =		afs_sync,
! 	.vfs_uninit =		vfs_stduninit,
  	.vfs_unmount =		afs_unmount,
  	.vfs_sysctl =		vfs_stdsysctl,
  };
--- 279,285 ----
  	.vfs_root =		afs_root,
  	.vfs_statfs =		afs_statfs,
  	.vfs_sync =		afs_sync,
! 	.vfs_uninit =		afs_uninit,
  	.vfs_unmount =		afs_unmount,
  	.vfs_sysctl =		vfs_stdsysctl,
  };
***************
*** 263,269 ****
      vfs_stdcheckexp,
      vfs_stdvptofh,
      afs_init,
!     vfs_stduninit,
      vfs_stdextattrctl,
  #ifdef AFS_FBSD50_ENV
      vfs_stdsysctl,
--- 300,306 ----
      vfs_stdcheckexp,
      vfs_stdvptofh,
      afs_init,
!     afs_uninit,
      vfs_stdextattrctl,
  #ifdef AFS_FBSD50_ENV
      vfs_stdsysctl,
Index: openafs/src/afs/FBSD/osi_vm.c
diff -c openafs/src/afs/FBSD/osi_vm.c:1.11.2.1 openafs/src/afs/FBSD/osi_vm.c:1.11.2.2
*** openafs/src/afs/FBSD/osi_vm.c:1.11.2.1	Sun Apr  3 14:15:37 2005
--- openafs/src/afs/FBSD/osi_vm.c	Mon May 23 17:23:53 2005
***************
*** 22,28 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/FBSD/osi_vm.c,v 1.11.2.1 2005/04/03 18:15:37 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/FBSD/osi_vm.c,v 1.11.2.2 2005/05/23 21:23:53 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 48,53 ****
--- 48,57 ----
   * rather than an explicit lock.
   */
  
+ #ifdef AFS_FBSD60_ENV
+ #define VOP_GETVOBJECT(vp, objp) (*(objp) = (vp)->v_object)
+ #endif
+ 
  #ifdef AFS_FBSD50_ENV
  #define	lock_vnode(v)	vn_lock((v), LK_EXCLUSIVE | LK_RETRY, curthread)
  #define unlock_vnode(v)	VOP_UNLOCK((v), 0, curthread)
Index: openafs/src/afs/FBSD/osi_vnodeops.c
diff -c openafs/src/afs/FBSD/osi_vnodeops.c:1.18.2.2 openafs/src/afs/FBSD/osi_vnodeops.c:1.18.2.4
*** openafs/src/afs/FBSD/osi_vnodeops.c:1.18.2.2	Sat Apr 23 20:58:05 2005
--- openafs/src/afs/FBSD/osi_vnodeops.c	Mon May 23 17:26:40 2005
***************
*** 48,54 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/FBSD/osi_vnodeops.c,v 1.18.2.2 2005/04/24 00:58:05 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.18.2.4 2005/05/23 21:26:40 shadow Exp $");
  
  #include <afs/sysincludes.h>	/* Standard vendor system headers */
  #include <afsincludes.h>	/* Afs-based standard headers */
***************
*** 491,507 ****
  				 * } */ *ap;
  {
      int error;
-     int bad;
      struct vcache *vc = VTOAFS(ap->a_vp);
!     bad = 0;
      AFS_GLOCK();
      error = afs_open(&vc, ap->a_mode, ap->a_cred);
  #ifdef DIAGNOSTIC
      if (AFSTOV(vc) != ap->a_vp)
  	panic("AFS open changed vnode!");
  #endif
-     osi_FlushPages(vc, ap->a_cred);
      AFS_GUNLOCK();
      return error;
  }
  
--- 491,509 ----
  				 * } */ *ap;
  {
      int error;
      struct vcache *vc = VTOAFS(ap->a_vp);
! 
      AFS_GLOCK();
      error = afs_open(&vc, ap->a_mode, ap->a_cred);
  #ifdef DIAGNOSTIC
      if (AFSTOV(vc) != ap->a_vp)
  	panic("AFS open changed vnode!");
  #endif
      AFS_GUNLOCK();
+ #ifdef AFS_FBSD60_ENV
+     vnode_create_vobject(ap->a_vp, vc->m.Length, ap->a_td);
+ #endif
+     osi_FlushPages(vc, ap->a_cred);
      return error;
  }
  
***************
*** 1355,1363 ****
       */
      if (code)
  	printf("afs_vop_reclaim: afs_FlushVCache failed code %d\n", code);
- 
  #ifdef AFS_FBSD60_ENV
!     vnode_destroy_vobject(vp);
  #endif
      return 0;
  }
--- 1357,1365 ----
       */
      if (code)
  	printf("afs_vop_reclaim: afs_FlushVCache failed code %d\n", code);
  #ifdef AFS_FBSD60_ENV
!     else
! 	vnode_destroy_vobject(vp);
  #endif
      return 0;
  }
Index: openafs/src/afs/LINUX/osi_machdep.h
diff -c openafs/src/afs/LINUX/osi_machdep.h:1.22.2.8 openafs/src/afs/LINUX/osi_machdep.h:1.22.2.9
*** openafs/src/afs/LINUX/osi_machdep.h:1.22.2.8	Wed Apr 27 17:56:12 2005
--- openafs/src/afs/LINUX/osi_machdep.h	Sun May  8 01:48:40 2005
***************
*** 111,116 ****
--- 111,118 ----
  /* We often need to pretend we're in user space to get memory transfers
   * right for the kernel calls we use.
   */
+ #include <asm/uaccess.h>
+ 
  #ifdef KERNEL_SPACE_DECL
  #undef KERNEL_SPACE_DECL
  #undef TO_USER_SPACE
***************
*** 120,133 ****
  #define TO_USER_SPACE() { _fs_space_decl = get_fs(); set_fs(get_ds()); }
  #define TO_KERNEL_SPACE() set_fs(_fs_space_decl)
  
! /* Backwards compatibilty macros - copyin/copyout are redone because macro
!  * inside parentheses is not evalutated.
!  */
! #define memcpy_fromfs copy_from_user
! #define memcpy_tofs copy_to_user
! #define copyin(F, T, C)  (copy_from_user ((char*)(T), (char*)(F), (C)), 0)
! #define copyinstr(F, T, C, L) (copyin(F, T, C), *(L)=strlen(T), 0)
! #define copyout(F, T, C) (copy_to_user ((char*)(T), (char*)(F), (C)), 0)
  
  /* kernel print statements */
  #define printf printk
--- 122,137 ----
  #define TO_USER_SPACE() { _fs_space_decl = get_fs(); set_fs(get_ds()); }
  #define TO_KERNEL_SPACE() set_fs(_fs_space_decl)
  
! #define copyin(F, T, C)  (copy_from_user ((char*)(T), (char*)(F), (C)) > 0 ? EFAULT : 0)
! static inline long copyinstr(char *from, char *to, int count, int *length) {
!     long tmp;
!     tmp = strncpy_from_user(to, from, count);
!     if (tmp < 0)
!             return EFAULT;
!     *length = tmp;
!     return 0;
! }
! #define copyout(F, T, C) (copy_to_user ((char*)(T), (char*)(F), (C)) > 0 ? EFAULT : 0)
  
  /* kernel print statements */
  #define printf printk
Index: openafs/src/afs/LINUX/osi_module.c
diff -c openafs/src/afs/LINUX/osi_module.c:1.52.2.14 openafs/src/afs/LINUX/osi_module.c:1.52.2.18
*** openafs/src/afs/LINUX/osi_module.c:1.52.2.14	Sun Apr 24 19:53:44 2005
--- openafs/src/afs/LINUX/osi_module.c	Mon May 30 01:28:19 2005
***************
*** 15,21 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_module.c,v 1.52.2.14 2005/04/24 23:53:44 shadow Exp $");
  
  #include <linux/module.h> /* early to avoid printf->printk mapping */
  #include "afs/sysincludes.h"
--- 15,21 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_module.c,v 1.52.2.18 2005/05/30 05:28:19 shadow Exp $");
  
  #include <linux/module.h> /* early to avoid printf->printk mapping */
  #include "afs/sysincludes.h"
***************
*** 34,39 ****
--- 34,43 ----
  #include <linux/sched.h>
  #endif
  
+ #ifdef HAVE_KERNEL_LINUX_SEQ_FILE_H
+ #include <linux/seq_file.h>
+ #endif
+ 
  extern struct file_system_type afs_fs_type;
  
  #if !defined(AFS_LINUX24_ENV)
***************
*** 67,72 ****
--- 71,156 ----
  #endif
  };
  
+ #ifdef HAVE_KERNEL_LINUX_SEQ_FILE_H
+ static void *c_start(struct seq_file *m, loff_t *pos)
+ {
+ 	struct afs_q *cq, *tq;
+ 	loff_t n = 0;
+ 
+ 	ObtainReadLock(&afs_xcell);
+ 	for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
+ 		tq = QNext(cq);
+ 
+ 		if (n++ == *pos)
+ 			break;
+ 	}
+ 	if (cq == &CellLRU)
+ 		return NULL;
+ 
+ 	return cq;
+ }
+ 
+ static void *c_next(struct seq_file *m, void *p, loff_t *pos)
+ {
+ 	struct afs_q *cq = p, *tq;
+ 
+ 	(*pos)++;
+ 	tq = QNext(cq);
+ 
+ 	if (tq == &CellLRU)
+ 		return NULL;
+ 
+ 	return tq;
+ }
+ 
+ static void c_stop(struct seq_file *m, void *p)
+ {
+ 	ReleaseReadLock(&afs_xcell);
+ }
+ 
+ static int c_show(struct seq_file *m, void *p)
+ {
+ 	struct afs_q *cq = p;
+ 	struct cell *tc = QTOC(cq);
+ 	int j;
+ 
+ 	seq_printf(m, ">%s #(%d/%d)\n", tc->cellName,
+ 		   tc->cellNum, tc->cellIndex);
+ 
+ 	for (j = 0; j < MAXCELLHOSTS; j++) {
+ 		afs_uint32 addr;
+ 
+ 		if (!tc->cellHosts[j]) break;
+ 
+ 		addr = tc->cellHosts[j]->addr->sa_ip;
+ 		seq_printf(m, "%u.%u.%u.%u #%u.%u.%u.%u\n",
+ 			   NIPQUAD(addr), NIPQUAD(addr));
+ 	}
+ 
+ 	return 0;
+ }
+ 
+ static struct seq_operations afs_csdb_op = {
+ 	.start		= c_start,
+ 	.next		= c_next,
+ 	.stop		= c_stop,
+ 	.show		= c_show,
+ };
+ 
+ static int afs_csdb_open(struct inode *inode, struct file *file)
+ {
+ 	return seq_open(file, &afs_csdb_op);
+ }
+ 
+ static struct file_operations afs_csdb_operations = {
+ 	.open		= afs_csdb_open,
+ 	.read		= seq_read,
+ 	.llseek		= seq_lseek,
+ 	.release	= seq_release,
+ };
+ 
+ #else /* HAVE_KERNEL_LINUX_SEQ_FILE_H */
+ 
  int
  csdbproc_info(char *buffer, char **start, off_t offset, int
  length)
***************
*** 134,178 ****
      return len;
  }
  
! 
! int
! csdbproc_read(char *buffer, char **start, off_t offset, int count,
! 	      int *eof, void *data)
! {
!     int len, j;
!     struct afs_q *cq, *tq;
!     struct cell *tc;
!     char tbuffer[16];
!     afs_uint32 addr;
!     
!     len = 0;
!     ObtainReadLock(&afs_xcell);
!     for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
! 	tc = QTOC(cq); tq = QNext(cq);
! 	len += sprintf(buffer + len, ">%s #(%d/%d)\n", tc->cellName, 
! 		       tc->cellNum, tc->cellIndex);
! 	for (j = 0; j < MAXCELLHOSTS; j++) {
! 	    if (!tc->cellHosts[j]) break;
! 	    addr = ntohl(tc->cellHosts[j]->addr->sa_ip);
! 	    sprintf(tbuffer, "%d.%d.%d.%d", 
! 		    (int)((addr>>24) & 0xff), (int)((addr>>16) & 0xff),
! 		    (int)((addr>>8)  & 0xff), (int)( addr      & 0xff));
!             len += sprintf(buffer + len, "%s #%s\n", tbuffer, tbuffer);
! 	}
!     }
!     ReleaseReadLock(&afs_xcell);
!     
!     if (offset >= len) {
! 	*start = buffer;
! 	*eof = 1;
! 	return 0;
!     }
!     *start = buffer + offset;
!     if ((len -= offset) > count)
! 	return count;
!     *eof = 1;
!     return len;
! }
  
  static struct proc_dir_entry *openafs_procfs;
  #if defined(NEED_IOCTL32) && !defined(HAVE_COMPAT_IOCTL)
--- 218,224 ----
      return len;
  }
  
! #endif /* HAVE_KERNEL_LINUX_SEQ_FILE_H */
  
  static struct proc_dir_entry *openafs_procfs;
  #if defined(NEED_IOCTL32) && !defined(HAVE_COMPAT_IOCTL)
***************
*** 193,199 ****
--- 239,251 ----
  
      entry1->owner = THIS_MODULE;
  
+ #ifdef HAVE_KERNEL_LINUX_SEQ_FILE_H
+     entry2 = create_proc_entry(PROC_CELLSERVDB_NAME, 0, openafs_procfs);
+     if (entry2)
+ 	entry2->proc_fops = &afs_csdb_operations;
+ #else
      entry2 = create_proc_info_entry(PROC_CELLSERVDB_NAME, (S_IFREG|S_IRUGO), openafs_procfs, csdbproc_info);
+ #endif
  
  #if defined(NEED_IOCTL32) && !defined(HAVE_COMPAT_IOCTL)
      if (register_ioctl32_conversion(VIOC_SYSCALL32, NULL) == 0) 
***************
*** 341,346 ****
--- 393,399 ----
  }
  
  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+ MODULE_LICENSE("http://www.openafs.org/dl/license10.html");
  module_init(afs_init);
  module_exit(afs_cleanup);
  #endif
Index: openafs/src/afs/LINUX/osi_syscall.c
diff -c openafs/src/afs/LINUX/osi_syscall.c:1.1.2.5 openafs/src/afs/LINUX/osi_syscall.c:1.1.2.6
*** openafs/src/afs/LINUX/osi_syscall.c:1.1.2.5	Sun Apr  3 15:32:39 2005
--- openafs/src/afs/LINUX/osi_syscall.c	Mon May 23 17:16:10 2005
***************
*** 15,21 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_syscall.c,v 1.1.2.5 2005/04/03 19:32:39 shadow Exp $");
  
  #ifdef AFS_LINUX24_ENV
  #include <linux/module.h> /* early to avoid printf->printk mapping */
--- 15,21 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_syscall.c,v 1.1.2.6 2005/05/23 21:16:10 shadow Exp $");
  
  #ifdef AFS_LINUX24_ENV
  #include <linux/module.h> /* early to avoid printf->printk mapping */
***************
*** 128,146 ****
--- 128,160 ----
  
  /***** SPARC64 *****/
  #ifdef AFS_SPARC64_LINUX20_ENV
+ #ifdef AFS_SPARC64_LINUX26_ENV
+ static SYSCALLTYPE *afs_sys_call_table32;
+ #else
  extern SYSCALLTYPE *afs_sys_call_table32;
+ #endif
  static SYSCALLTYPE afs_ni_syscall32 = 0;
  
  extern int afs32_xsetgroups();
+ #ifdef AFS_SPARC64_LINUX26_ENV
+ asmlinkage int (*sys32_setgroupsp) (int gidsetsize,
+ 				    __kernel_gid32_t * grouplist);
+ #else
  asmlinkage int (*sys32_setgroupsp) (int gidsetsize,
  				    __kernel_gid_t32 * grouplist);
+ #endif
  #ifdef AFS_LINUX24_ENV
  /* This number is not exported for some bizarre reason. */
  #define __NR_setgroups32      82
  extern int afs32_xsetgroups32();
+ #ifdef AFS_SPARC64_LINUX26_ENV
+ asmlinkage int (*sys32_setgroups32p) (int gidsetsize,
+ 				      __kernel_gid32_t * grouplist);
+ #else
  asmlinkage int (*sys32_setgroups32p) (int gidsetsize,
  				      __kernel_gid_t32 * grouplist);
  #endif
+ #endif
  
  asmlinkage int
  afs_syscall32(long syscall, long parm1, long parm2, long parm3, long parm4,
Index: openafs/src/afs/LINUX/osi_sysctl.c
diff -c openafs/src/afs/LINUX/osi_sysctl.c:1.7 openafs/src/afs/LINUX/osi_sysctl.c:1.7.2.1
*** openafs/src/afs/LINUX/osi_sysctl.c:1.7	Fri Aug  8 15:55:05 2003
--- openafs/src/afs/LINUX/osi_sysctl.c	Sun May  8 01:04:14 2005
***************
*** 1,7 ****
  /*
   * osi_sysctl.c: Linux sysctl interface to OpenAFS
   *
!  * $Id: osi_sysctl.c,v 1.7 2003/08/08 19:55:05 shadow Exp $
   *
   * Written Jan 30, 2002 by Kris Van Hees (Sine Nomine Associates)
   */
--- 1,7 ----
  /*
   * osi_sysctl.c: Linux sysctl interface to OpenAFS
   *
!  * $Id: osi_sysctl.c,v 1.7.2.1 2005/05/08 05:04:14 shadow Exp $
   *
   * Written Jan 30, 2002 by Kris Van Hees (Sine Nomine Associates)
   */
***************
*** 20,25 ****
--- 20,30 ----
  extern afs_int32 hm_retry_RO;
  extern afs_int32 hm_retry_RW;
  extern afs_int32 hm_retry_int;
+ extern afs_int32 afs_blocksUsed_0;
+ extern afs_int32 afs_blocksUsed_1;
+ extern afs_int32 afs_blocksUsed_2;
+ extern afs_int32 afs_pct1;
+ extern afs_int32 afs_pct2;
  
  #ifdef CONFIG_SYSCTL
  static struct ctl_table_header *afs_sysctl = NULL;
***************
*** 49,54 ****
--- 54,87 ----
       &afs_bkvolpref, sizeof(afs_int32), 0644, NULL,
       &proc_dointvec}
      ,
+     {7, "afs_blocksUsed",
+      &afs_blocksUsed, sizeof(afs_int32), 0444, NULL,
+      &proc_dointvec}
+     ,
+     {8, "afs_blocksUsed_0",
+      &afs_blocksUsed_0, sizeof(afs_int32), 0644, NULL,
+      &proc_dointvec}
+     ,
+     {9, "afs_blocksUsed_1",
+      &afs_blocksUsed_1, sizeof(afs_int32), 0644, NULL,
+      &proc_dointvec}
+     ,
+     {10, "afs_blocksUsed_2",
+      &afs_blocksUsed_2, sizeof(afs_int32), 0644, NULL,
+      &proc_dointvec}
+     ,
+     {11, "afs_pct1",
+      &afs_pct1, sizeof(afs_int32), 0644, NULL,
+      &proc_dointvec}
+     ,
+     {12, "afs_pct2",
+      &afs_pct2, sizeof(afs_int32), 0644, NULL,
+      &proc_dointvec}
+     ,
+     {13, "afs_cacheBlocks",
+      &afs_cacheBlocks, sizeof(afs_int32), 0644, NULL,
+      &proc_dointvec}
+     ,
      {0}
  };
  
Index: openafs/src/afs/LINUX/osi_vnodeops.c
diff -c openafs/src/afs/LINUX/osi_vnodeops.c:1.81.2.19 openafs/src/afs/LINUX/osi_vnodeops.c:1.81.2.23
*** openafs/src/afs/LINUX/osi_vnodeops.c:1.81.2.19	Mon Apr 25 10:55:47 2005
--- openafs/src/afs/LINUX/osi_vnodeops.c	Tue May 31 17:12:51 2005
***************
*** 22,28 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_vnodeops.c,v 1.81.2.19 2005/04/25 14:55:47 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.81.2.23 2005/05/31 21:12:51 shadow Exp $");
  
  #include "afs/sysincludes.h"
  #include "afsincludes.h"
***************
*** 864,873 ****
  afs_linux_dentry_revalidate(struct dentry *dp)
  #endif
  {
-     cred_t *credp = NULL;
      struct vrequest treq;
!     int code, bad_dentry;
!     struct vcache *vcp, *parentvcp;
  
  #ifdef AFS_LINUX24_ENV
      lock_kernel();
--- 864,873 ----
  afs_linux_dentry_revalidate(struct dentry *dp)
  #endif
  {
      struct vrequest treq;
!     cred_t *credp = NULL;
!     struct vcache *vcp, *pvcp, *tvc = NULL;
!     int valid;
  
  #ifdef AFS_LINUX24_ENV
      lock_kernel();
***************
*** 875,938 ****
      AFS_GLOCK();
  
      vcp = ITOAFS(dp->d_inode);
!     parentvcp = ITOAFS(dp->d_parent->d_inode);		/* dget_parent()? */
  
!     /* If it's a negative dentry, it's never valid */
!     if (!vcp || !parentvcp) {
! 	bad_dentry = 1;
! 	goto done;
!     }
  
!     /* If it's @sys, perhaps it has been changed */
!     if (!afs_ENameOK(dp->d_name.name)) {
! 	bad_dentry = 10;
! 	goto done;
!     }
  
!     /* If it's the AFS root no chance it needs revalidating */
!     if (vcp == afs_globalVp)
! 	goto good_dentry;
  
!     /* Get a validated vcache entry */
!     credp = crref();
!     code = afs_InitReq(&treq, credp);
!     if (code) {
! 	bad_dentry = 2;
! 	goto done;
!     }
!     code = afs_VerifyVCache(vcp, &treq);
!     if (code) {
! 	bad_dentry = 3;
! 	goto done;
!     }
  
!     /* If we aren't the last looker, verify access */
!     if (vcp->last_looker != treq.uid) {
! 	if (!afs_AccessOK(vcp, (vType(vcp) == VREG) ? PRSFS_READ : PRSFS_LOOKUP, &treq, CHECK_MODE_BITS)) {
! 	    bad_dentry = 5;
! 	    goto done;
  	}
  
! 	vcp->last_looker = treq.uid;
      }
  
    good_dentry:
!     bad_dentry = 0;
  
    done:
      /* Clean up */
      AFS_GUNLOCK();
!     if (bad_dentry) {
  	shrink_dcache_parent(dp);
  	d_drop(dp);
      }
  #ifdef AFS_LINUX24_ENV
      unlock_kernel();
  #endif
!     if (credp)
! 	crfree(credp);
  
!     return !bad_dentry;
  }
  
  #if !defined(AFS_LINUX26_ENV)
--- 875,953 ----
      AFS_GLOCK();
  
      vcp = ITOAFS(dp->d_inode);
!     pvcp = ITOAFS(dp->d_parent->d_inode);		/* dget_parent()? */
  
!     if (vcp) {
  
! 	/* If it's the AFS root no chance it needs revalidating */
! 	if (vcp == afs_globalVp)
! 	    goto good_dentry;
! 
! 	/* check_bad_parent()? */
! 
! #ifdef notdef
! 	/* If the last looker changes, we should make sure the current
! 	 * looker still has permission to examine this file.  This would
! 	 * always require a crref() which would be "slow".
! 	 */
! 	if (vcp->last_looker != treq.uid) {
! 	    if (!afs_AccessOK(vcp, (vType(vcp) == VREG) ? PRSFS_READ : PRSFS_LOOKUP, &treq, CHECK_MODE_BITS))
! 		goto bad_dentry;
  
! 	    vcp->last_looker = treq.uid;
! 	}
! #endif
  
! 	/* If the parent's DataVersion has changed or the vnode
! 	 * is longer valid, we need to do a full lookup.  VerifyVCache
! 	 * isn't enough since the vnode may have been renamed.
! 	 */
! 	if (hgetlo(pvcp->m.DataVersion) > dp->d_time || !(vcp->states & CStatd)) {
  
! 	    credp = crref();
! 	    if (afs_InitReq(&treq, credp))
! 		goto bad_dentry;
! 	    afs_lookup(pvcp, dp->d_name.name, &tvc, credp);
! 	    if (!tvc || tvc != vcp)
! 		goto bad_dentry;
! 	    if (afs_VerifyVCache(vcp, &treq))	/* update inode attributes */
! 		goto bad_dentry;
! 
! 	    dp->d_time = hgetlo(pvcp->m.DataVersion);
  	}
  
!     } else {
! 	if (hgetlo(pvcp->m.DataVersion) > dp->d_time)
! 	    goto bad_dentry;
! 
! 	/* No change in parent's DataVersion so this negative
! 	 * lookup is still valid.
! 	 */
      }
  
    good_dentry:
!     valid = 1;
  
    done:
      /* Clean up */
+     if (tvc)
+ 	afs_PutVCache(tvc);
      AFS_GUNLOCK();
!     if (credp)
! 	crfree(credp);
! 
!     if (!valid) {
  	shrink_dcache_parent(dp);
  	d_drop(dp);
      }
  #ifdef AFS_LINUX24_ENV
      unlock_kernel();
  #endif
!     return valid;
  
!   bad_dentry:
!     valid = 0;
!     goto done;
  }
  
  #if !defined(AFS_LINUX26_ENV)
***************
*** 1024,1029 ****
--- 1039,1045 ----
  #endif
  
  	dp->d_op = &afs_dentry_operations;
+ 	dp->d_time = hgetlo(ITOAFS(dip)->m.DataVersion);
  	d_instantiate(dp, ip);
      }
  
***************
*** 1054,1059 ****
--- 1070,1078 ----
      cred_t *credp = crref();
      struct vcache *vcp = NULL;
      const char *comp = dp->d_name.name;
+ #if 1
+     struct dentry *res = 0;
+ #endif
  
  #if defined(AFS_LINUX26_ENV)
      lock_kernel();
***************
*** 1073,1078 ****
--- 1092,1099 ----
  	} else if (S_ISDIR(ip->i_mode)) {
  	    ip->i_op = &afs_dir_iops;
  	    ip->i_fop = &afs_dir_fops;
+             d_prune_aliases(ip);
+             res = d_find_alias(ip);
  	} else if (S_ISLNK(ip->i_mode)) {
  	    ip->i_op = &afs_symlink_iops;
  	    ip->i_data.a_ops = &afs_symlink_aops;
***************
*** 1095,1100 ****
--- 1116,1128 ----
  #endif
      }
      dp->d_op = &afs_dentry_operations;
+     dp->d_time = hgetlo(ITOAFS(dip)->m.DataVersion);
+ #if defined(AFS_LINUX24_ENV)
+     if (res) {
+ 	if (d_unhashed(res))
+ 	    d_rehash(res);
+     } else
+ #endif
      d_add(dp, AFSTOI(vcp));
  
  #if defined(AFS_LINUX26_ENV)
***************
*** 1105,1110 ****
--- 1133,1142 ----
      /* It's ok for the file to not be found. That's noted by the caller by
       * seeing that the dp->d_inode field is NULL.
       */
+ #if defined(AFS_LINUX24_ENV)
+     if (code == 0)
+         return res;
+ #endif
  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,10)
      if (code == ENOENT)
  	return ERR_PTR(0);
***************
*** 1185,1192 ****
  	}
  	AFS_GUNLOCK();
  
! 	if (!code)
  	    d_move(dp, __dp);
  	dput(__dp);
  
  	goto out;
--- 1217,1226 ----
  	}
  	AFS_GUNLOCK();
  
! 	if (!code) {
! 	    __dp->d_time = hgetlo(ITOAFS(dip)->m.DataVersion);
  	    d_move(dp, __dp);
+ 	}
  	dput(__dp);
  
  	goto out;
***************
*** 1252,1257 ****
--- 1286,1292 ----
  	tvcp->v.v_fop = &afs_dir_fops;
  #endif
  	dp->d_op = &afs_dentry_operations;
+ 	dp->d_time = hgetlo(ITOAFS(dip)->m.DataVersion);
  	d_instantiate(dp, AFSTOI(tvcp));
      }
  
Index: openafs/src/afs/OBSD/osi_machdep.h
diff -c openafs/src/afs/OBSD/osi_machdep.h:1.16.2.4 openafs/src/afs/OBSD/osi_machdep.h:1.16.2.5
*** openafs/src/afs/OBSD/osi_machdep.h:1.16.2.4	Sun Apr 24 19:40:44 2005
--- openafs/src/afs/OBSD/osi_machdep.h	Mon May 23 17:17:29 2005
***************
*** 16,22 ****
   * afs_osi.h.
   */
  
! /* $Id: osi_machdep.h,v 1.16.2.4 2005/04/24 23:40:44 shadow Exp $ */
  
  #ifndef _OSI_MACHDEP_H_
  #define _OSI_MACHDEP_H_
--- 16,22 ----
   * afs_osi.h.
   */
  
! /* $Id: osi_machdep.h,v 1.16.2.5 2005/05/23 21:17:29 shadow Exp $ */
  
  #ifndef _OSI_MACHDEP_H_
  #define _OSI_MACHDEP_H_
***************
*** 69,75 ****
  #define p_rcred         p_ucred
  
  /* time */
- extern struct timeval time;
  #define	afs_hz		hz
  #define osi_GetTime(x)	microtime(x)
  #define osi_Time()	(time.tv_sec)
--- 69,74 ----
Index: openafs/src/afs/VNOPS/afs_vnop_dirops.c
diff -c openafs/src/afs/VNOPS/afs_vnop_dirops.c:1.14.2.4 openafs/src/afs/VNOPS/afs_vnop_dirops.c:1.14.2.5
*** openafs/src/afs/VNOPS/afs_vnop_dirops.c:1.14.2.4	Sun Jan 30 22:49:15 2005
--- openafs/src/afs/VNOPS/afs_vnop_dirops.c	Mon May 30 00:05:44 2005
***************
*** 21,27 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_dirops.c,v 1.14.2.4 2005/01/31 03:49:15 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.14.2.5 2005/05/30 04:05:44 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 286,295 ****
      }
  
  
!     if (tvc) {
  	osi_dnlc_purgedp(tvc);	/* get rid of any entries for this directory */
! 	afs_symhint_inval(tvc);
!     } else
  	osi_dnlc_remove(adp, aname, 0);
  
      if (tvc) {
--- 286,294 ----
      }
  
  
!     if (tvc)
  	osi_dnlc_purgedp(tvc);	/* get rid of any entries for this directory */
!     else
  	osi_dnlc_remove(adp, aname, 0);
  
      if (tvc) {
Index: openafs/src/afs/VNOPS/afs_vnop_remove.c
diff -c openafs/src/afs/VNOPS/afs_vnop_remove.c:1.31.2.8 openafs/src/afs/VNOPS/afs_vnop_remove.c:1.31.2.9
*** openafs/src/afs/VNOPS/afs_vnop_remove.c:1.31.2.8	Mon Apr  4 00:01:19 2005
--- openafs/src/afs/VNOPS/afs_vnop_remove.c	Mon May 30 00:05:44 2005
***************
*** 21,27 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_remove.c,v 1.31.2.8 2005/04/04 04:01:19 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.31.2.9 2005/05/30 04:05:44 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 126,133 ****
  	      SHARED_LOCK, NULL));
  
      osi_dnlc_remove(adp, aname, tvc);
-     if (tvc)
- 	afs_symhint_inval(tvc);	/* XXX: don't really need to be so extreme */
  
      if (code) {
  	if (tdc) {
--- 126,131 ----
***************
*** 362,369 ****
      }
  
      osi_dnlc_remove(adp, aname, tvc);
-     if (tvc)
- 	afs_symhint_inval(tvc);
  
      Tadp1 = adp;
      Tadpr = VREFCOUNT(adp);
--- 360,365 ----
Index: openafs/src/afs/VNOPS/afs_vnop_rename.c
diff -c openafs/src/afs/VNOPS/afs_vnop_rename.c:1.16.2.5 openafs/src/afs/VNOPS/afs_vnop_rename.c:1.16.2.6
*** openafs/src/afs/VNOPS/afs_vnop_rename.c:1.16.2.5	Sun Apr  3 14:15:40 2005
--- openafs/src/afs/VNOPS/afs_vnop_rename.c	Mon May 30 00:05:44 2005
***************
*** 18,24 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_rename.c,v 1.16.2.5 2005/04/03 18:15:40 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.16.2.6 2005/05/30 04:05:44 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 120,127 ****
  
      osi_dnlc_remove(aodp, aname1, 0);
      osi_dnlc_remove(andp, aname2, 0);
-     afs_symhint_inval(aodp);
-     afs_symhint_inval(andp);
  
      /*
       * Make sure that the data in the cache is current. We may have
--- 120,125 ----
Index: openafs/src/afsd/afsd.c
diff -c openafs/src/afsd/afsd.c:1.43.2.7 openafs/src/afsd/afsd.c:1.43.2.9
*** openafs/src/afsd/afsd.c:1.43.2.7	Sun Apr 24 10:28:40 2005
--- openafs/src/afsd/afsd.c	Mon May 23 17:26:40 2005
***************
*** 57,63 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/afsd/afsd.c,v 1.43.2.7 2005/04/24 14:28:40 shadow Exp $");
  
  #define VFS 1
  
--- 57,63 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/afsd/afsd.c,v 1.43.2.9 2005/05/23 21:26:40 shadow Exp $");
  
  #define VFS 1
  
***************
*** 230,235 ****
--- 230,237 ----
  afs_int32 afs_shutdown = 0;
  afs_int32 cacheBlocks;		/*Num blocks in the cache */
  afs_int32 cacheFiles = 1000;	/*Optimal # of files in workstation cache */
+ afs_int32 rwpct = 0;
+ afs_int32 ropct = 0;
  afs_int32 cacheStatEntries = 300;	/*Number of stat cache entries */
  char cacheBaseDir[1024];	/*Where the workstation AFS cache lives */
  char confDir[1024];		/*Where the workstation AFS configuration lives */
***************
*** 275,280 ****
--- 277,283 ----
  static int enable_fakestat = 0;	/* enable fakestat support */
  static int enable_backuptree = 0;	/* enable backup tree support */
  static int enable_nomount = 0;	/* do not mount */
+ static int enable_splitcache = 0;
  #ifdef notdef
  static int inodes = 60;		/* VERY conservative, but has to be */
  #endif
***************
*** 1535,1541 ****
  	exit(1);
  	}
      }
!     
      /*
       * Pull out all the configuration info for the workstation's AFS cache and
       * the cellular community we're willing to let our users see.
--- 1538,1558 ----
  	exit(1);
  	}
      }
!     if (as->parms[34].items) {
! 	char *c;
! 	if (!as->parms[34].items->data ||
! 	    ((c = strchr(as->parms[34].items->data, '/')) == NULL)) 
!            printf("ignoring splitcache (specify as RW/RO percentages: 60/40)\n"); 
!        else {
!            ropct = atoi((char *)c+1);
! 	   *c = '\0'; 
!            rwpct = atoi((char *)as->parms[30].items->data);
!            if ((rwpct != 0) && (ropct != 0) && (ropct+rwpct == 100)) {
!                /* -splitcache */
!                enable_splitcache = 1;
! 	   }
!        }
!     }    
      /*
       * Pull out all the configuration info for the workstation's AFS cache and
       * the cellular community we're willing to let our users see.
***************
*** 1813,1818 ****
--- 1830,1842 ----
      cparams.inodes = inodes;
  #endif
      call_syscall(AFSOP_CACHEINIT, &cparams);
+ 
+     /* do it before we init the cache inodes */
+     if (enable_splitcache) {
+ 	call_syscall(AFSOP_BUCKETPCT, 1, rwpct);
+ 	call_syscall(AFSOP_BUCKETPCT, 2, ropct);
+     }
+ 
      if (afsd_CloseSynch)
  	call_syscall(AFSOP_CLOSEWAIT);
  
***************
*** 2055,2061 ****
  	if (afsd_verbose)
  	    printf("%s: Mounting the AFS root on '%s', flags: %d.\n", rn,
  		   cacheMountDir, mountFlags);
! #ifdef AFS_FBSD_ENV
  	if ((mount("AFS", cacheMountDir, mountFlags, (caddr_t) 0)) < 0) {
  #elif defined(AFS_AIX_ENV)
  	if (aix_vmount()) {
--- 2079,2088 ----
  	if (afsd_verbose)
  	    printf("%s: Mounting the AFS root on '%s', flags: %d.\n", rn,
  		   cacheMountDir, mountFlags);
! #if defined(AFS_FBSD60_ENV)
! 	/* data must be non-NULL but is otherwise ignored */
! 	if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, rn)) < 0) {
! #elif defined(AFS_FBSD_ENV)
  	if ((mount("AFS", cacheMountDir, mountFlags, (caddr_t) 0)) < 0) {
  #elif defined(AFS_AIX_ENV)
  	if (aix_vmount()) {
***************
*** 2065,2072 ****
  	if ((mount("AFS", cacheMountDir, mountFlags, "afs", NULL, 0)) < 0) {
  #elif defined(AFS_SGI_ENV)
  	mountFlags = MS_FSS;
! 	if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, (caddr_t) MOUNT_AFS))
! 	    < 0) {
  #elif defined(AFS_LINUX20_ENV)
  	if ((mount("AFS", cacheMountDir, MOUNT_AFS, 0, NULL)) < 0) {
  #else
--- 2092,2098 ----
  	if ((mount("AFS", cacheMountDir, mountFlags, "afs", NULL, 0)) < 0) {
  #elif defined(AFS_SGI_ENV)
  	mountFlags = MS_FSS;
! 	if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, (caddr_t) MOUNT_AFS)) < 0) {
  #elif defined(AFS_LINUX20_ENV)
  	if ((mount("AFS", cacheMountDir, MOUNT_AFS, 0, NULL)) < 0) {
  #else
***************
*** 2178,2183 ****
--- 2204,2211 ----
      cmd_AddParm(ts, "-settime", CMD_FLAG, CMD_OPTIONAL,
                 "don't set the time");
      cmd_AddParm(ts, "-rxpck", CMD_SINGLE, CMD_OPTIONAL, "set rx_extraPackets to this value");
+     cmd_AddParm(ts, "-splitcache", CMD_SINGLE, CMD_OPTIONAL, "Percentage RW versus RO in cache (specify as 60/40)");
+ 
      return (cmd_Dispatch(argc, argv));
  }
  
Index: openafs/src/cf/linux-test3.m4
diff -c openafs/src/cf/linux-test3.m4:1.8.2.6 openafs/src/cf/linux-test3.m4:1.8.2.7
*** openafs/src/cf/linux-test3.m4:1.8.2.6	Sun Apr  3 15:32:40 2005
--- openafs/src/cf/linux-test3.m4	Sun May  8 02:05:27 2005
***************
*** 128,130 ****
--- 128,141 ----
    ac_cv_linux_kernel_page_follow_link=no)])
  AC_MSG_RESULT($ac_cv_linux_kernel_page_follow_link)
  CPPFLAGS="$save_CPPFLAGS"])
+ 
+ AC_DEFUN([LINUX_KERNEL_LINUX_SEQ_FILE_H],[
+   AC_MSG_CHECKING(for linux/seq_file.h in kernel)
+   if test -f "${LINUX_KERNEL_PATH}/include/linux/seq_file.h"; then
+     ac_linux_seq_file=yes
+     AC_MSG_RESULT($ac_linux_seq_file)
+   else
+     ac_linux_seq_file=no
+     AC_MSG_RESULT($ac_linux_seq_file)
+   fi
+ ])
Index: openafs/src/config/NTMakefile
diff -c openafs/src/config/NTMakefile:1.15 openafs/src/config/NTMakefile:1.15.2.1
*** openafs/src/config/NTMakefile:1.15	Wed Jun 23 03:37:58 2004
--- openafs/src/config/NTMakefile	Mon May 30 01:41:30 2005
***************
*** 389,394 ****
--- 389,397 ----
  !	IF (!EXIST($(DESTDIR)\include\afs))
  		$(MKDIR) $(DESTDIR)\include\afs
  !	ENDIF
+ !	IF (!EXIST($(DESTDIR)\include\des))
+ 		$(MKDIR) $(DESTDIR)\include\des
+ !	ENDIF
  !	IF (!EXIST($(DESTDIR)\include\rx))
  		$(MKDIR) $(DESTDIR)\include\rx
  !	ENDIF
Index: openafs/src/config/NTMakefile.amd64_w2k
diff -c openafs/src/config/NTMakefile.amd64_w2k:1.1.2.5 openafs/src/config/NTMakefile.amd64_w2k:1.1.2.8
*** openafs/src/config/NTMakefile.amd64_w2k:1.1.2.5	Thu Apr 28 14:13:30 2005
--- openafs/src/config/NTMakefile.amd64_w2k	Wed May 18 18:57:11 2005
***************
*** 80,86 ****
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=3
! AFSPRODUCT_VER_PATCH=8200
  AFSPRODUCT_VER_BUILD=0
  
  # For MSI installer, each major release should have a different GUID
--- 80,86 ----
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=3
! AFSPRODUCT_VER_PATCH=8300
  AFSPRODUCT_VER_BUILD=0
  
  # For MSI installer, each major release should have a different GUID
Index: openafs/src/config/NTMakefile.i386_nt40
diff -c openafs/src/config/NTMakefile.i386_nt40:1.46.2.20 openafs/src/config/NTMakefile.i386_nt40:1.46.2.23
*** openafs/src/config/NTMakefile.i386_nt40:1.46.2.20	Thu Apr 28 14:13:30 2005
--- openafs/src/config/NTMakefile.i386_nt40	Wed May 18 18:57:11 2005
***************
*** 80,86 ****
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=3
! AFSPRODUCT_VER_PATCH=8200
  AFSPRODUCT_VER_BUILD=0
  
  # For MSI installer, each major release should have a different GUID
--- 80,86 ----
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=3
! AFSPRODUCT_VER_PATCH=8300
  AFSPRODUCT_VER_BUILD=0
  
  # For MSI installer, each major release should have a different GUID
Index: openafs/src/config/NTMakefile.i386_w2k
diff -c openafs/src/config/NTMakefile.i386_w2k:1.1.2.5 openafs/src/config/NTMakefile.i386_w2k:1.1.2.8
*** openafs/src/config/NTMakefile.i386_w2k:1.1.2.5	Thu Apr 28 14:13:30 2005
--- openafs/src/config/NTMakefile.i386_w2k	Wed May 18 18:57:11 2005
***************
*** 80,86 ****
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=3
! AFSPRODUCT_VER_PATCH=8200
  AFSPRODUCT_VER_BUILD=0
  
  # For MSI installer, each major release should have a different GUID
--- 80,86 ----
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=3
! AFSPRODUCT_VER_PATCH=8300
  AFSPRODUCT_VER_BUILD=0
  
  # For MSI installer, each major release should have a different GUID
Index: openafs/src/config/afs_args.h
diff -c openafs/src/config/afs_args.h:1.13.2.4 openafs/src/config/afs_args.h:1.13.2.5
*** openafs/src/config/afs_args.h:1.13.2.4	Sun Mar 20 09:54:14 2005
--- openafs/src/config/afs_args.h	Sun May  8 01:04:17 2005
***************
*** 47,52 ****
--- 47,53 ----
  #define AFSOP_BASIC_INIT	 36	/* used to be part of START_AFS */
  #define AFSOP_SET_BACKUPTREE	 37	/* enable backup tree support */
  #define AFSOP_SET_RXPCK		 38	/*set rx_extraPackets*/
+ #define AFSOP_BUCKETPCT          39     /* bucket percentage */
  
  /* The range 20-30 is reserved for AFS system offsets in the afs_syscall */
  #define	AFSCALL_PIOCTL		20
Index: openafs/src/config/afs_sysnames.h
diff -c openafs/src/config/afs_sysnames.h:1.50.2.14 openafs/src/config/afs_sysnames.h:1.50.2.16
*** openafs/src/config/afs_sysnames.h:1.50.2.14	Sat Apr 23 20:58:06 2005
--- openafs/src/config/afs_sysnames.h	Mon May 23 17:17:41 2005
***************
*** 150,155 ****
--- 150,156 ----
  #define SYS_NAME_ID_sparc64_linux2	1800
  #define SYS_NAME_ID_sparc64_linux22	1801
  #define SYS_NAME_ID_sparc64_linux24	1802
+ #define SYS_NAME_ID_sparc64_linux26	1803
  
  #define SYS_NAME_ID_s390_linux2         1900
  #define SYS_NAME_ID_s390_linux22        1901
***************
*** 212,217 ****
--- 213,219 ----
  #define SYS_NAME_ID_i386_obsd34		2603
  #define SYS_NAME_ID_i386_obsd35		2604
  #define SYS_NAME_ID_i386_obsd36		2605
+ #define SYS_NAME_ID_i386_obsd37		2606
  
  #define SYS_NAME_ID_amd64_linux2        2700
  #define SYS_NAME_ID_amd64_linux22       2701
Index: openafs/src/config/param.i386_obsd37.h
diff -c /dev/null openafs/src/config/param.i386_obsd37.h:1.1.2.2
*** /dev/null	Wed Jun  1 00:59:59 2005
--- openafs/src/config/param.i386_obsd37.h	Mon May 23 17:17:41 2005
***************
*** 0 ****
--- 1,65 ----
+ /*
+  * Jim Rees, University of Michigan CITI
+  */
+ 
+ #ifndef	AFS_PARAM_H
+ #define	AFS_PARAM_H
+ 
+ #ifndef IGNORE_STDS_H
+ #include <sys/param.h>
+ #endif
+ 
+ #define SYS_NAME		"i386_obsd37"
+ #define SYS_NAME_ID		SYS_NAME_ID_i386_obsd37
+ 
+ #define AFS_XBSD_ENV		1	/* {Free,Open,Net}BSD */
+ #define AFS_X86_XBSD_ENV	1
+ 
+ #define AFS_NAMEI_ENV		1	/* User space interface to file system */
+ #define AFS_64BIT_ENV		1
+ #define AFS_64BIT_CLIENT	1
+ #define AFS_64BIT_IOPS_ENV	1	/* Needed for NAMEI */
+ #define AFS_OBSD_ENV		1
+ #define AFS_OBSD34_ENV		1
+ #define AFS_OBSD35_ENV		1
+ #define AFS_OBSD36_ENV		1
+ #define AFS_OBSD37_ENV		1
+ #define AFS_NONFSTRANS		1
+ #define AFS_VM_RDWR_ENV		1
+ #define AFS_VFS_ENV		1
+ #define AFS_VFSINCL_ENV		1
+ 
+ #define FTRUNC O_TRUNC
+ 
+ #define AFS_SYSCALL		208
+ #define AFS_MOUNT_AFS		"afs"
+ 
+ #define RXK_LISTENER_ENV	1
+ #define AFS_GCPAGS	        0	/* if nonzero, garbage collect PAGs */
+ #define AFS_USE_GETTIMEOFDAY    1	/* use gettimeofday to implement rx clock */
+ 
+ #define AFSLITTLE_ENDIAN	1
+ 
+ #ifndef IGNORE_STDS_H
+ #include <afs/afs_sysnames.h>
+ #endif
+ 
+ /* Extra kernel definitions (from kdefs file) */
+ #ifdef _KERNEL
+ #define AFS_GLOBAL_SUNLOCK	1
+ #define	AFS_SHORTGID		0	/* are group id's short? */
+ 
+ #if	!defined(ASSEMBLER) && !defined(__LANGUAGE_ASSEMBLY__)
+ enum vcexcl { NONEXCL, EXCL };
+ 
+ #ifndef MIN
+ #define MIN(A,B) ((A) < (B) ? (A) : (B))
+ #endif
+ #ifndef MAX
+ #define MAX(A,B) ((A) > (B) ? (A) : (B))
+ #endif
+ 
+ #endif /* ! ASSEMBLER & ! __LANGUAGE_ASSEMBLY__ */
+ #endif /* _KERNEL */
+ 
+ #endif /* AFS_PARAM_H */
Index: openafs/src/config/param.s390x_linux26.h
diff -c openafs/src/config/param.s390x_linux26.h:1.1.2.3 openafs/src/config/param.s390x_linux26.h:1.1.2.4
*** openafs/src/config/param.s390x_linux26.h:1.1.2.3	Sun Apr 24 20:02:18 2005
--- openafs/src/config/param.s390x_linux26.h	Mon May 30 00:23:39 2005
***************
*** 65,72 ****
  #endif
  #endif
  #define AFS_GLOBAL_SUNLOCK
- extern unsigned long __per_cpu_offset[NR_CPUS];
- extern SYSCALLTYPE sys_call_table_emu[] __attribute__((weak));
  #endif /* __KERNEL__  && !DUMP_KERNEL */
  
  #include <afs/afs_sysnames.h>
--- 65,70 ----
Index: openafs/src/config/param.sparc64_linux26.h
diff -c /dev/null openafs/src/config/param.sparc64_linux26.h:1.1.4.2
*** /dev/null	Wed Jun  1 00:59:59 2005
--- openafs/src/config/param.sparc64_linux26.h	Mon May 23 17:16:10 2005
***************
*** 0 ****
--- 1,171 ----
+ #ifndef UKERNEL
+ /* This section for kernel libafs compiles only */
+ 
+ /* 
+  * Copyright 2000, International Business Machines Corporation and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ 
+ #ifndef _PARAM_SPARC64_LINUX26_H_
+ #define _PARAM_SPARC64_LINUX26_H_
+ 
+ /* In user space the AFS_LINUX20_ENV should be sufficient. In the kernel,
+  * it's a judgment call. If something is obviously sparc64 specific, use that
+  * #define instead. Note that "20" refers to the linux 2.0 kernel. The "2"
+  * in the sysname is the current version of the client. This takes into
+  * account the perferred OS user space configuration as well as the kernel.
+  */
+ 
+ #define AFS_LINUX20_ENV	1
+ #define AFS_LINUX22_ENV	1
+ #define AFS_LINUX24_ENV	1
+ #define AFS_LINUX26_ENV	1
+ #define AFS_SPARC64_LINUX20_ENV	1
+ #define AFS_SPARC64_LINUX22_ENV	1
+ #define AFS_SPARC64_LINUX24_ENV	1
+ #define AFS_SPARC64_LINUX26_ENV	1
+ #define AFS_LINUX_64BIT_KERNEL 1
+ #define AFS_NONFSTRANS 1
+ 
+ #define AFS_MOUNT_AFS "afs"	/* The name of the filesystem type. */
+ #define AFS_SYSCALL 227
+ #define AFS_64BIT_IOPS_ENV  1
+ #define AFS_NAMEI_ENV     1	/* User space interface to file system */
+ 
+ #define AFS_64BIT_ENV		1	/* Defines afs_int32 as int, not long. */
+ #define AFS_64BIT_CLIENT	1
+ #define AFS_32BIT_USR_ENV       1
+ #define AFS_64BITPOINTER_ENV	1	/* pointers are 64 bits. */
+ 
+ #if defined(__KERNEL__) && !defined(KDUMP_KERNEL)
+ #include <linux/threads.h>
+ 
+ #include <linux/config.h>
+ #ifdef CONFIG_SMP
+ #ifndef AFS_SMP
+ #define AFS_SMP 1
+ #endif
+ #endif
+ /* Using "AFS_SMP" to map to however many #define's are required to get
+  * MP to compile for Linux
+  */
+ #ifdef AFS_SMP
+ #ifndef CONFIG_SMP
+ #define CONFIG_SMP 1
+ #endif
+ #define __SMP__
+ #define AFS_GLOBAL_SUNLOCK
+ #endif
+ 
+ #endif /* __KERNEL__  && !DUMP_KERNEL */
+ #include <afs/afs_sysnames.h>
+ 
+ #define AFS_USERSPACE_IP_ADDR 1
+ #define RXK_LISTENER_ENV 1
+ #define AFS_GCPAGS		0	/* if nonzero, garbage collect PAGs */
+ 
+ /* Machine / Operating system information */
+ #define SYS_NAME	"sparc64_linux26"
+ #define SYS_NAME_ID	SYS_NAME_ID_sparc64_linux26
+ #define AFSBIG_ENDIAN    1
+ #define AFS_HAVE_FFS        1	/* Use system's ffs. */
+ #define AFS_HAVE_STATVFS    0	/* System doesn't support statvfs */
+ #define AFS_VM_RDWR_ENV	    1	/* read/write implemented via VM */
+ 
+ 
+ #ifdef KERNEL
+ #ifndef MIN
+ #define MIN(A,B) ((A) < (B) ? (A) : (B))
+ #endif
+ #ifndef MAX
+ #define MAX(A,B) ((A) > (B) ? (A) : (B))
+ #endif
+ #endif /* KERNEL */
+ 
+ /* on sparclinux is O_LARGEFILE defined but there is not off64_t,
+    so small hack to get usd_file.c work */
+ #ifndef KERNEL
+ #define __USE_FILE_OFFSET64 1
+ #define __USE_LARGEFILE64 1
+ #if !defined off64_t
+ #define off64_t __off64_t
+ #endif
+ #endif
+ 
+ #endif /* _PARAM_SPARC64_LINUX26_H_ */
+ 
+ #else /* !defined(UKERNEL) */
+ 
+ /* This section for user space compiles only */
+ 
+ /* 
+  * Copyright 2000, International Business Machines Corporation and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ #ifndef _PARAM_USR_SPARC64_LINUX26_H_
+ #define _PARAM_USR_SPARC64_LINUX26_H_
+ 
+ /* In user space the AFS_LINUX20_ENV should be sufficient. In the kernel,
+  * it's a judgment call. If something is obviously sparc64 specific, use that
+  * #define instead. Note that "20" refers to the linux 2.0 kernel. The "2"
+  * in the sysname is the current version of the client. This takes into
+  * account the perferred OS user space configuration as well as the kernel.
+  */
+ 
+ #define UKERNEL			1	/* user space kernel */
+ #define AFS_ENV			1
+ #define AFS_USR_LINUX20_ENV	1
+ #define AFS_USR_LINUX22_ENV	1
+ #define AFS_USR_LINUX24_ENV	1
+ #define AFS_USR_LINUX26_ENV	1
+ #define AFS_NONFSTRANS 1
+ 
+ #define AFS_MOUNT_AFS "afs"	/* The name of the filesystem type. */
+ #define AFS_SYSCALL 227
+ #define AFS_64BIT_IOPS_ENV  1
+ #define AFS_NAMEI_ENV     1	/* User space interface to file system */
+ #include <afs/afs_sysnames.h>
+ 
+ #define AFS_USERSPACE_IP_ADDR 1
+ #define RXK_LISTENER_ENV 1
+ #define AFS_GCPAGS		0	/* if nonzero, garbage collect PAGs */
+ 
+ 
+ /* Machine / Operating system information */
+ #define SYS_NAME	"sparc64_linux26"
+ #define SYS_NAME_ID	SYS_NAME_ID_sparc64_linux26
+ #define AFSBIG_ENDIAN    1
+ #define AFS_HAVE_FFS        1	/* Use system's ffs. */
+ #define AFS_HAVE_STATVFS    0	/* System doesn't support statvfs */
+ #define AFS_VM_RDWR_ENV	    1	/* read/write implemented via VM */
+ 
+ #define	afsio_iov	uio_iov
+ #define	afsio_iovcnt	uio_iovcnt
+ #define	afsio_offset	uio_offset
+ #define	afsio_seg	uio_segflg
+ #define	afsio_fmode	uio_fmode
+ #define	afsio_resid	uio_resid
+ #define	AFS_UIOSYS	1
+ #define	AFS_UIOUSER	UIO_USERSPACE
+ #define	AFS_CLBYTES	MCLBYTES
+ #define	AFS_MINCHANGE	2
+ #define	VATTR_NULL	usr_vattr_null
+ 
+ #define AFS_DIRENT
+ #ifndef CMSERVERPREF
+ #define CMSERVERPREF
+ #endif
+ 
+ #endif /* _PARAM_USR_SPARC64_LINUX26_H_ */
+ 
+ #endif /* !defined(UKERNEL) */
Index: openafs/src/config/stds.h
diff -c openafs/src/config/stds.h:1.21 openafs/src/config/stds.h:1.21.2.1
*** openafs/src/config/stds.h:1.21	Sat Sep 13 16:14:32 2003
--- openafs/src/config/stds.h	Sun May  8 02:01:12 2005
***************
*** 57,63 ****
  typedef unsigned long long afs_uint64;
  #endif
  #define ZeroInt64(a)       (a) = 0
! #define AssignInt64(a, b)   *(a) = (b)
  #define AddInt64(a,b,c) *(c) = (afs_int64)(a) + (afs_int64)(b)
  #define AddUInt64(a,b,c) *(c) = (afs_uint64)(a) + (afs_uint64)(b)
  #define SubtractInt64(a,b,c) *(c) = (afs_int64)(a) - (afs_int64)(b)
--- 57,63 ----
  typedef unsigned long long afs_uint64;
  #endif
  #define ZeroInt64(a)       (a) = 0
! #define AssignInt64(a, b) *(b) = (a) 
  #define AddInt64(a,b,c) *(c) = (afs_int64)(a) + (afs_int64)(b)
  #define AddUInt64(a,b,c) *(c) = (afs_uint64)(a) + (afs_uint64)(b)
  #define SubtractInt64(a,b,c) *(c) = (afs_int64)(a) - (afs_int64)(b)
Index: openafs/src/config/venus.h
diff -c openafs/src/config/venus.h:1.10 openafs/src/config/venus.h:1.10.2.1
*** openafs/src/config/venus.h:1.10	Wed Jun  2 04:43:02 2004
--- openafs/src/config/venus.h	Sun May  8 02:18:12 2005
***************
*** 175,180 ****
--- 175,181 ----
  #define VIOC_PREFETCHTAPE       _VICEIOCTL(66)	/* MR-AFS prefetch from tape */
  #define VIOC_RESIDENCY_CMD      _VICEIOCTL(67)	/* generic MR-AFS cmds */
  #define VIOC_STATISTICS         _VICEIOCTL(68)	/* arla: fetch statistics */
+ #define VIOC_GETVCXSTATUS2      _VICEIOCTL(69)  /* vcache statistics */
  
  /* Coordinated 'C' pioctl's */
  #define VIOC_NEWALIAS		_CVICEIOCTL(1)	/* create new cell alias */
Index: openafs/src/des/NTMakefile
diff -c openafs/src/des/NTMakefile:1.7 openafs/src/des/NTMakefile:1.7.2.1
*** openafs/src/des/NTMakefile:1.7	Sat Nov 22 23:53:34 2003
--- openafs/src/des/NTMakefile	Mon May 30 01:41:35 2005
***************
*** 34,44 ****
  	$(INCFILEDIR)\des_conf.h \
  	$(INCFILEDIR)\mit-cpyright.h \
  	$(INCFILEDIR)\des_odd.h \
! 	$(INCFILEDIR)\crypt.h
  
  $(INCFILEDIR)\des_odd.h: odd.h
  	$(COPY) odd.h $@
  
  
  # Library component lists.
  
--- 34,47 ----
  	$(INCFILEDIR)\des_conf.h \
  	$(INCFILEDIR)\mit-cpyright.h \
  	$(INCFILEDIR)\des_odd.h \
! 	$(INCFILEDIR)\crypt.h \
!         $(INCFILEDIR)\des\stats.h
  
  $(INCFILEDIR)\des_odd.h: odd.h
  	$(COPY) odd.h $@
  
+ $(INCFILEDIR)\des\stats.h: stats.h
+         $(COPY) stats.h $@
  
  # Library component lists.
  
Index: openafs/src/des/des.c
diff -c openafs/src/des/des.c:1.11.2.2 openafs/src/des/des.c:1.11.2.3
*** openafs/src/des/des.c:1.11.2.2	Mon Oct 18 13:43:56 2004
--- openafs/src/des/des.c	Mon May 30 00:57:34 2005
***************
*** 37,43 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/des/des.c,v 1.11.2.2 2004/10/18 17:43:56 shadow Exp $");
  
  #ifndef KERNEL
  #include <stdio.h>
--- 37,43 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/des/des.c,v 1.11.2.3 2005/05/30 04:57:34 shadow Exp $");
  
  #ifndef KERNEL
  #include <stdio.h>
***************
*** 65,74 ****
  #define DBG_PRINT(s)
  #endif
  
- #ifdef AFS_PTHREAD_ENV
- pthread_mutex_t rxkad_stats_mutex;
- #endif /* AFS_PTHREAD_ENV */
- 
  /* encrypt == 0  ==> decrypt, else encrypt */
  
  afs_int32
--- 65,70 ----
***************
*** 105,116 ****
  #ifdef DEBUG
      afs_uint32 dbg_tmp[2];
  #endif
-     LOCK_RXKAD_STATS;
      if (encrypt)
! 	rxkad_stats.des_encrypts[DES_ENCRYPT]++;
      else
! 	rxkad_stats.des_encrypts[DES_DECRYPT]++;
!     UNLOCK_RXKAD_STATS;
      /*
       * Use L1,R1 and L2,R2 as two sets of "64-bit" registers always
       * work from L1,R1 input to L2,R2 output; initialize the cleartext
--- 101,110 ----
  #ifdef DEBUG
      afs_uint32 dbg_tmp[2];
  #endif
      if (encrypt)
! 	INC_RXKAD_STATS(des_encrypts[DES_ENCRYPT]);
      else
! 	INC_RXKAD_STATS(des_encrypts[DES_DECRYPT]);
      /*
       * Use L1,R1 and L2,R2 as two sets of "64-bit" registers always
       * work from L1,R1 input to L2,R2 output; initialize the cleartext
Index: openafs/src/des/key_sched.c
diff -c openafs/src/des/key_sched.c:1.6.2.1 openafs/src/des/key_sched.c:1.6.2.3
*** openafs/src/des/key_sched.c:1.6.2.1	Wed Aug 25 03:09:37 2004
--- openafs/src/des/key_sched.c	Mon May 30 14:30:36 2005
***************
*** 31,37 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/des/key_sched.c,v 1.6.2.1 2004/08/25 07:09:37 shadow Exp $");
  
  #include <mit-cpyright.h>
  #include "des_internal.h"
--- 31,37 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/des/key_sched.c,v 1.6.2.3 2005/05/30 18:30:36 shadow Exp $");
  
  #include <mit-cpyright.h>
  #include "des_internal.h"
***************
*** 44,49 ****
--- 44,53 ----
  
  typedef char key[64];
  
+ #ifndef AFS_PTHREAD_ENV 
+ struct rxkad_stats rxkad_stats = { { 0 } }; 
+ #endif
+ 
  /* the following are really void but cc86 doesnt allow it */
  static int make_key_sched();
  
***************
*** 66,74 ****
      n = 0;
      p_char = k_char;
  
!     LOCK_RXKAD_STATS;
!     rxkad_stats.des_key_scheds++;
!     UNLOCK_RXKAD_STATS;
  #ifdef lint
      n = n;			/* fool it in case of VAXASM */
  #endif
--- 70,76 ----
      n = 0;
      p_char = k_char;
  
!     INC_RXKAD_STATS(des_key_scheds);
  #ifdef lint
      n = n;			/* fool it in case of VAXASM */
  #endif
Index: openafs/src/des/new_rnd_key.c
diff -c openafs/src/des/new_rnd_key.c:1.13.2.1 openafs/src/des/new_rnd_key.c:1.13.2.2
*** openafs/src/des/new_rnd_key.c:1.13.2.1	Wed Aug 25 03:09:37 2004
--- openafs/src/des/new_rnd_key.c	Mon May 30 00:57:34 2005
***************
*** 19,25 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/des/new_rnd_key.c,v 1.13.2.1 2004/08/25 07:09:37 shadow Exp $");
  
  #ifndef KERNEL
  #include <stdio.h>
--- 19,25 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/des/new_rnd_key.c,v 1.13.2.2 2005/05/30 04:57:34 shadow Exp $");
  
  #ifndef KERNEL
  #include <stdio.h>
***************
*** 257,265 ****
  {
      int i;
  
!     LOCK_RXKAD_STATS;
!     rxkad_stats.des_randoms++;
!     UNLOCK_RXKAD_STATS;
      /*
       * Encrypt the sequence number to get the new random block:
       */
--- 257,263 ----
  {
      int i;
  
!     INC_RXKAD_STATS(des_randoms);
      /*
       * Encrypt the sequence number to get the new random block:
       */
Index: openafs/src/des/stats.h
diff -c openafs/src/des/stats.h:1.4.2.1 openafs/src/des/stats.h:1.4.2.5
*** openafs/src/des/stats.h:1.4.2.1	Wed Aug 25 03:09:37 2004
--- openafs/src/des/stats.h	Tue May 31 09:26:01 2005
***************
*** 10,16 ****
--- 10,30 ----
  /* Some Cheap statistics which should be shared with the rxkad definitions, but
   * aren't.  The layout should match the layout in rxkad/rxkad.p.h. */
  
+ #ifndef OPENAFS_DES_STATS_H
+ #define OPENAFS_DES_STATS_H
+ 
+ 
+ /* this is an optimization for pthreads environments.  Instead of having global
+    rxkad statistics, make them thread-specific, and only perform aggregation on
+    the stats structures when necessary.  Furthermore, don't do any locking, and
+    live with the nearly accurate aggregation (e.g. you might miss a few increments,
+    but the resulting aggregation should be almost correct). */
+ 
+ #ifdef AFS_PTHREAD_ENV
+ typedef struct rxkad_stats_t {
+ #else
  struct rxkad_stats {
+ #endif
      afs_uint32 connections[3];	/* client side only */
      afs_uint32 destroyObject;	/* client security objects */
      afs_uint32 destroyClient;	/* client connections */
***************
*** 30,45 ****
      afs_uint32 des_encrypts[2];	/* DECRYPT==0, ENCRYPT==1 */
      afs_uint32 des_key_scheds;	/* key schedule creations */
      afs_uint32 des_randoms;	/* random blocks generated */
!     long spares[10];
! } rxkad_stats;			/* put these here for convenience */
  
  #ifdef AFS_PTHREAD_ENV
  #include <pthread.h>
  #include <assert.h>
! extern pthread_mutex_t rxkad_stats_mutex;
! #define LOCK_RXKAD_STATS assert(pthread_mutex_lock(&rxkad_stats_mutex)==0)
! #define UNLOCK_RXKAD_STATS assert(pthread_mutex_unlock(&rxkad_stats_mutex)==0)
  #else
! #define LOCK_RXKAD_STATS
! #define UNLOCK_RXKAD_STATS
  #endif
--- 44,151 ----
      afs_uint32 des_encrypts[2];	/* DECRYPT==0, ENCRYPT==1 */
      afs_uint32 des_key_scheds;	/* key schedule creations */
      afs_uint32 des_randoms;	/* random blocks generated */
!     afs_uint32 clientObjects;
!     afs_uint32 serverObjects;
!     long spares[8];
! #ifdef AFS_PTHREAD_ENV
!     struct rxkad_stats_t * next;
!     struct rxkad_stats_t * prev;
! } rxkad_stats_t;			/* put these here for convenience */
! #else /* AFS_PTHREAD_ENV */
! };
! #ifdef AFS_NT40_ENV
! struct rxkad_stats rxkad_stats;         /* put this here for convenience */
! #endif 
! #endif /* AFS_PTHREAD_ENV */
! 
  
  #ifdef AFS_PTHREAD_ENV
+ struct rxkad_global_stats {
+     rxkad_stats_t * first;
+     rxkad_stats_t * last;
+ };
+ 
  #include <pthread.h>
  #include <assert.h>
! extern pthread_mutex_t rxkad_global_stats_lock;
! extern pthread_key_t rxkad_stats_key;
! 
! extern void rxkad_global_stats_init();
! extern rxkad_stats_t * rxkad_thr_stats_init();
! extern int rxkad_stats_agg(rxkad_stats_t *);
! 
! #ifndef BEGIN
! #define BEGIN do {
! #define END   } while(0)
! #endif
! #define RXKAD_GLOBAL_STATS_LOCK assert(pthread_mutex_lock(&rxkad_global_stats_lock)==0)
! #define RXKAD_GLOBAL_STATS_UNLOCK assert(pthread_mutex_unlock(&rxkad_global_stats_lock)==0)
! #define GET_RXKAD_STATS(stats) rxkad_stats_agg(stats)
! #define GET_RXKAD_THR_STATS(rxkad_stats) \
!     BEGIN \
!         (rxkad_stats) = ((rxkad_stats_t*)pthread_getspecific(rxkad_stats_key)); \
!         if ((rxkad_stats) == NULL) { \
!             assert(((rxkad_stats) = rxkad_thr_stats_init()) != NULL); \
!         } \
!     END
! #define INC_RXKAD_STATS(stats_elem) \
!     BEGIN \
!         rxkad_stats_t * rxkad_stats; \
!         rxkad_stats = ((rxkad_stats_t*)pthread_getspecific(rxkad_stats_key)); \
!         if (rxkad_stats == NULL) { \
!             assert(((rxkad_stats) = rxkad_thr_stats_init()) != NULL); \
!         } \
!         rxkad_stats->stats_elem++; \
!     END
! #define DEC_RXKAD_STATS(stats_elem) \
!     BEGIN \
!         rxkad_stats_t * rxkad_stats; \
!         rxkad_stats = ((rxkad_stats_t*)pthread_getspecific(rxkad_stats_key)); \
!         if (rxkad_stats == NULL) { \
!             assert(((rxkad_stats) = rxkad_thr_stats_init()) != NULL); \
!         } \
!         rxkad_stats->stats_elem--; \
!     END
! #define ADD_RXKAD_STATS(stats_elem, inc_value) \
!     BEGIN \
!         rxkad_stats_t * rxkad_stats; \
!         rxkad_stats = ((rxkad_stats_t*)pthread_getspecific(rxkad_stats_key)); \
!         if (rxkad_stats == NULL) { \
!             assert(((rxkad_stats) = rxkad_thr_stats_init()) != NULL); \
!         } \
!         rxkad_stats->stats_elem += inc_value; \
!     END
! #define SUB_RXKAD_STATS(stats_elem, dec_value) \
!     BEGIN \
!         rxkad_stats_t * rxkad_stats; \
!         rxkad_stats = ((rxkad_stats_t*)pthread_getspecific(rxkad_stats_key)); \
!         if (rxkad_stats == NULL) { \
!             assert(((rxkad_stats) = rxkad_thr_stats_init()) != NULL); \
!         } \
!         rxkad_stats->stats_elem -= dec_value; \
!     END
! #else /* AFS_PTHREAD_ENV */
! #define INC_RXKAD_STATS(stats_elem) rxkad_stats.stats_elem++
! #define DEC_RXKAD_STATS(stats_elem) rxkad_stats.stats_elem--
! #define ADD_RXKAD_STATS(stats_elem, inc_value) rxkad_stats.stats_elem += (inc_value)
! #define SUB_RXKAD_STATS(stats_elem, dec_value) rxkad_stats.stats_elem -= (dec_value)
! #define GET_RXKAD_STATS(stats) memcpy((stats), &rxkad_stats, sizeof(rxkad_stats))
! #endif /* AFS_PTHREAD_ENV */
! 
! 
! #if defined(AFS_NT40_ENV) && defined(AFS_PTHREAD_ENV)
! #ifndef RXKAD_STATS_DECLSPEC
! #define RXKAD_STATS_DECLSPEC __declspec(dllimport) extern
! #endif
  #else
! #define RXKAD_STATS_DECLSPEC extern
  #endif
+ 
+ #ifdef AFS_PTHREAD_ENV
+ RXKAD_STATS_DECLSPEC struct rxkad_global_stats rxkad_global_stats;
+ #else /* AFS_PTHREAD_ENV */
+ RXKAD_STATS_DECLSPEC struct rxkad_stats rxkad_stats;
+ #endif
+ 
+ 
+ #endif /* OPENAFS_DES_STATS_H */
Index: openafs/src/kauth/test/test_getticket.c
diff -c openafs/src/kauth/test/test_getticket.c:1.7 openafs/src/kauth/test/test_getticket.c:1.7.2.1
*** openafs/src/kauth/test/test_getticket.c:1.7	Tue Jul 15 19:15:18 2003
--- openafs/src/kauth/test/test_getticket.c	Mon May 30 00:57:34 2005
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/kauth/test/test_getticket.c,v 1.7 2003/07/15 23:15:18 shadow Exp $");
  
  #include <afs/stds.h>
  #include <sys/types.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/kauth/test/test_getticket.c,v 1.7.2.1 2005/05/30 04:57:34 shadow Exp $");
  
  #include <afs/stds.h>
  #include <sys/types.h>
***************
*** 64,70 ****
  PrintRxkadStats()
  {
      printf("New Objects client %d, server %d.  Destroyed objects %d.\n",
! 	   rxkad_stats_clientObjects, rxkad_stats_serverObjects,
  	   rxkad_stats.destroyObject);
      printf("client conns: %d %d %d, destroyed client %d.\n",
  	   rxkad_stats.connections[0], rxkad_stats.connections[1],
--- 64,70 ----
  PrintRxkadStats()
  {
      printf("New Objects client %d, server %d.  Destroyed objects %d.\n",
! 	   rxkad_stats.clientObjects, rxkad_stats.serverObjects,
  	   rxkad_stats.destroyObject);
      printf("client conns: %d %d %d, destroyed client %d.\n",
  	   rxkad_stats.connections[0], rxkad_stats.connections[1],
Index: openafs/src/kauth/test/test_rxkad_free.c
diff -c openafs/src/kauth/test/test_rxkad_free.c:1.7 openafs/src/kauth/test/test_rxkad_free.c:1.7.2.1
*** openafs/src/kauth/test/test_rxkad_free.c:1.7	Tue Jul 15 19:15:18 2003
--- openafs/src/kauth/test/test_rxkad_free.c	Mon May 30 00:57:34 2005
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/kauth/test/test_rxkad_free.c,v 1.7 2003/07/15 23:15:18 shadow Exp $");
  
  #include <afs/stds.h>
  #include <sys/types.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/kauth/test/test_rxkad_free.c,v 1.7.2.1 2005/05/30 04:57:34 shadow Exp $");
  
  #include <afs/stds.h>
  #include <sys/types.h>
***************
*** 38,44 ****
  PrintRxkadStats()
  {
      printf("New Objects client %d, server %d.  Destroyed objects %d.\n",
! 	   rxkad_stats_clientObjects, rxkad_stats_serverObjects,
  	   rxkad_stats.destroyObject);
      printf("client conns: %d %d %d, destroyed client %d.\n",
  	   rxkad_stats.connections[0], rxkad_stats.connections[1],
--- 38,44 ----
  PrintRxkadStats()
  {
      printf("New Objects client %d, server %d.  Destroyed objects %d.\n",
! 	   rxkad_stats.clientObjects, rxkad_stats.serverObjects,
  	   rxkad_stats.destroyObject);
      printf("client conns: %d %d %d, destroyed client %d.\n",
  	   rxkad_stats.connections[0], rxkad_stats.connections[1],
Index: openafs/src/libafs/afs.ppc_darwin_70.plist.in
diff -c openafs/src/libafs/afs.ppc_darwin_70.plist.in:1.2.2.1 openafs/src/libafs/afs.ppc_darwin_70.plist.in:1.2.2.2
*** openafs/src/libafs/afs.ppc_darwin_70.plist.in:1.2.2.1	Thu Apr 28 22:45:47 2005
--- openafs/src/libafs/afs.ppc_darwin_70.plist.in	Tue May 31 10:49:19 2005
***************
*** 15,25 ****
  	<key>CFBundlePackageType</key>
  	<string>KEXT</string>
  	<key>CFBundleShortVersionString</key>
! 	<string>1.3.82</string>
  	<key>CFBundleSignature</key>
  	<string>????</string>
  	<key>CFBundleVersion</key>
! 	<string>1.3.82</string>
  	<key>OSBundleLibraries</key>
  	<dict>
  		<key>com.apple.kernel.bsd</key>
--- 15,25 ----
  	<key>CFBundlePackageType</key>
  	<string>KEXT</string>
  	<key>CFBundleShortVersionString</key>
! 	<string>1.3.83</string>
  	<key>CFBundleSignature</key>
  	<string>????</string>
  	<key>CFBundleVersion</key>
! 	<string>1.3.83</string>
  	<key>OSBundleLibraries</key>
  	<dict>
  		<key>com.apple.kernel.bsd</key>
Index: openafs/src/libafsrpc/afsrpc.def
diff -c openafs/src/libafsrpc/afsrpc.def:1.3.2.3 openafs/src/libafsrpc/afsrpc.def:1.3.2.4
*** openafs/src/libafsrpc/afsrpc.def:1.3.2.3	Tue Apr 19 01:13:48 2005
--- openafs/src/libafsrpc/afsrpc.def	Mon May 30 00:57:35 2005
***************
*** 67,73 ****
  	xdrrec_skiprecord			@71
  	xdrrx_create				@72
  	hton_syserr_conv			@73
! 	rxkad_stats				@74 DATA
  	com_err					@75
  	error_message				@76
  	rx_socket				@77 DATA
--- 67,73 ----
  	xdrrec_skiprecord			@71
  	xdrrx_create				@72
  	hton_syserr_conv			@73
! 	rxkad_global_stats			@74 DATA
  	com_err					@75
  	error_message				@76
  	rx_socket				@77 DATA
***************
*** 213,217 ****
--- 213,219 ----
          StartRXAFS_FetchData64                  @218
          StartRXAFS_StoreData64                  @219
          rx_StartClientThread                    @220
+ 	rxkad_global_stats_lock			@221 DATA
+ 	rxkad_stats_key				@222 DATA
  
  
Index: openafs/src/libafsrpc/afsrpc.exp
diff -c openafs/src/libafsrpc/afsrpc.exp:1.2 openafs/src/libafsrpc/afsrpc.exp:1.2.18.1
*** openafs/src/libafsrpc/afsrpc.exp:1.2	Mon Feb 12 12:28:39 2001
--- openafs/src/libafsrpc/afsrpc.exp	Mon May 30 00:57:35 2005
***************
*** 79,85 ****
  xdr_afsuuid
  xdr_int64
  hton_syserr_conv
! rxkad_stats
  _et_list
  et_list_mutex
  com_err
--- 79,87 ----
  xdr_afsuuid
  xdr_int64
  hton_syserr_conv
! rxkad_global_stats
! rxkad_global_stats_lock
! rxkad_stats_key
  _et_list
  et_list_mutex
  com_err
Index: openafs/src/packaging/MacOS/OpenAFS.Info.plist
diff -c openafs/src/packaging/MacOS/OpenAFS.Info.plist:1.2.2.9 openafs/src/packaging/MacOS/OpenAFS.Info.plist:1.2.2.10
*** openafs/src/packaging/MacOS/OpenAFS.Info.plist:1.2.2.9	Thu Apr 28 22:45:48 2005
--- openafs/src/packaging/MacOS/OpenAFS.Info.plist	Tue May 31 10:51:03 2005
***************
*** 3,15 ****
  <plist version="1.0">
  <dict>
  	<key>CFBundleGetInfoString</key>
! 	<string>OpenAFS 1.3.82</string>
  	<key>CFBundleIdentifier</key>
  	<string>org.openafs.OpenAFS.pkg</string>
  	<key>CFBundleName</key>
  	<string>OpenAFS</string>
  	<key>CFBundleShortVersionString</key>
! 	<string>1.3.82</string>
  	<key>IFMajorVersion</key>
  	<integer>1</integer>
  	<key>IFMinorVersion</key>
--- 3,15 ----
  <plist version="1.0">
  <dict>
  	<key>CFBundleGetInfoString</key>
! 	<string>OpenAFS 1.3.83</string>
  	<key>CFBundleIdentifier</key>
  	<string>org.openafs.OpenAFS.pkg</string>
  	<key>CFBundleName</key>
  	<string>OpenAFS</string>
  	<key>CFBundleShortVersionString</key>
! 	<string>1.3.83</string>
  	<key>IFMajorVersion</key>
  	<integer>1</integer>
  	<key>IFMinorVersion</key>
Index: openafs/src/packaging/MacOS/OpenAFS.info
diff -c openafs/src/packaging/MacOS/OpenAFS.info:1.1.4.9 openafs/src/packaging/MacOS/OpenAFS.info:1.1.4.10
*** openafs/src/packaging/MacOS/OpenAFS.info:1.1.4.9	Thu Apr 28 22:45:48 2005
--- openafs/src/packaging/MacOS/OpenAFS.info	Tue May 31 10:51:03 2005
***************
*** 1,5 ****
  Title OpenAFS
! Version 1.3.82
  Description The OpenAFS distributed filesystem. This package installs an almost-ready-to-run client for OpenAFS. see http://www.openafs.org for more information.
  DefaultLocation /
  Diskname (null)
--- 1,5 ----
  Title OpenAFS
! Version 1.3.83
  Description The OpenAFS distributed filesystem. This package installs an almost-ready-to-run client for OpenAFS. see http://www.openafs.org for more information.
  DefaultLocation /
  Diskname (null)
Index: openafs/src/pam/Makefile.in
diff -c openafs/src/pam/Makefile.in:1.12 openafs/src/pam/Makefile.in:1.12.2.1
*** openafs/src/pam/Makefile.in:1.12	Thu Feb 27 12:27:37 2003
--- openafs/src/pam/Makefile.in	Sun May 29 23:37:48 2005
***************
*** 61,67 ****
  	*linux*) \
  		$(CC) $(LDFLAGS) -o $@ afs_setcred.o \
  			afs_auth.o afs_util.o $(SHOBJS) $(LIBS) ;;\
! 	*fbsd*) \
  		$(CC) $(LDFLAGS) -o $@ afs_setcred.o \
  			afs_auth.o afs_util.o $(SHOBJS) $(LIBS) ;;\
  	* ) \
--- 61,67 ----
  	*linux*) \
  		$(CC) $(LDFLAGS) -o $@ afs_setcred.o \
  			afs_auth.o afs_util.o $(SHOBJS) $(LIBS) ;;\
! 	*fbsd*| *nbsd*) \
  		$(CC) $(LDFLAGS) -o $@ afs_setcred.o \
  			afs_auth.o afs_util.o $(SHOBJS) $(LIBS) ;;\
  	* ) \
***************
*** 82,88 ****
  	*linux*) \
  		$(CC) $(LDFLAGS) -o $@ afs_setcred_krb.o \
  			afs_auth_krb.o afs_util_krb.o $(SHOBJS) $(KLIBS) ;;\
! 	*fbsd*) \
  		$(CC) $(LDFLAGS) -o $@ afs_setcred_krb.o \
  			afs_auth_krb.o afs_util_krb.o $(SHOBJS) $(KLIBS) ;;\
  	* ) \
--- 82,88 ----
  	*linux*) \
  		$(CC) $(LDFLAGS) -o $@ afs_setcred_krb.o \
  			afs_auth_krb.o afs_util_krb.o $(SHOBJS) $(KLIBS) ;;\
! 	*fbsd*| *nbsd*) \
  		$(CC) $(LDFLAGS) -o $@ afs_setcred_krb.o \
  			afs_auth_krb.o afs_util_krb.o $(SHOBJS) $(KLIBS) ;;\
  	* ) \
***************
*** 98,104 ****
  		$(CC) $(CFLAGS) -o $@ test_pam.o ${PAM_LIBS};; \
  	*linux*) \
  		$(CC) $(CFLAGS) -rdynamic -o $@ test_pam.o -lpam -ldl;; \
! 	*fbsd*) \
  		$(CC) $(CFLAGS) -rdynamic -o $@ test_pam.o -lpam ;; \
  	*) \
  		echo No link line for system $(SYS_NAME). ;; \
--- 98,104 ----
  		$(CC) $(CFLAGS) -o $@ test_pam.o ${PAM_LIBS};; \
  	*linux*) \
  		$(CC) $(CFLAGS) -rdynamic -o $@ test_pam.o -lpam -ldl;; \
! 	*fbsd*| *nbsd*) \
  		$(CC) $(CFLAGS) -rdynamic -o $@ test_pam.o -lpam ;; \
  	*) \
  		echo No link line for system $(SYS_NAME). ;; \
Index: openafs/src/pam/afs_auth.c
diff -c openafs/src/pam/afs_auth.c:1.12 openafs/src/pam/afs_auth.c:1.12.2.1
*** openafs/src/pam/afs_auth.c:1.12	Tue Jul 15 19:15:56 2003
--- openafs/src/pam/afs_auth.c	Sun May 29 23:37:48 2005
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/pam/afs_auth.c,v 1.12 2003/07/15 23:15:56 shadow Exp $");
  
  #include <syslog.h>
  #include <stdlib.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/pam/afs_auth.c,v 1.12.2.1 2005/05/30 03:37:48 shadow Exp $");
  
  #include <syslog.h>
  #include <stdlib.h>
***************
*** 190,196 ****
  	RET(PAM_AUTH_ERR);
      }
  #else
! #if     defined(AFS_LINUX20_ENV) || defined(AFS_FBSD_ENV)
      upwd = getpwnam(user);
  #else
      upwd = getpwnam_r(user, &unix_pwd, upwd_buf, sizeof(upwd_buf));
--- 190,196 ----
  	RET(PAM_AUTH_ERR);
      }
  #else
! #if     defined(AFS_LINUX20_ENV) || defined(AFS_FBSD_ENV) || defined(AFS_NBSD_ENV)
      upwd = getpwnam(user);
  #else
      upwd = getpwnam_r(user, &unix_pwd, upwd_buf, sizeof(upwd_buf));
Index: openafs/src/pam/afs_password.c
diff -c openafs/src/pam/afs_password.c:1.10 openafs/src/pam/afs_password.c:1.10.2.1
*** openafs/src/pam/afs_password.c:1.10	Tue Jul 15 19:15:56 2003
--- openafs/src/pam/afs_password.c	Sun May 29 23:37:48 2005
***************
*** 19,25 ****
  #include <security/pam_modules.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/pam/afs_password.c,v 1.10 2003/07/15 23:15:56 shadow Exp $");
  
  #include <sys/param.h>
  #include <afs/kautils.h>
--- 19,25 ----
  #include <security/pam_modules.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/pam/afs_password.c,v 1.10.2.1 2005/05/30 03:37:48 shadow Exp $");
  
  #include <sys/param.h>
  #include <afs/kautils.h>
***************
*** 134,140 ****
  	RET(PAM_AUTH_ERR);
      }
  #else
! #if     defined(AFS_LINUX20_ENV) || defined(AFS_FBSD_ENV)
      upwd = getpwnam(user);
  #else
      upwd = getpwnam_r(user, &unix_pwd, upwd_buf, sizeof(upwd_buf));
--- 134,140 ----
  	RET(PAM_AUTH_ERR);
      }
  #else
! #if     defined(AFS_LINUX20_ENV) || defined(AFS_FBSD_ENV) || defined(AFS_NBSD_ENV)
      upwd = getpwnam(user);
  #else
      upwd = getpwnam_r(user, &unix_pwd, upwd_buf, sizeof(upwd_buf));
Index: openafs/src/pam/afs_setcred.c
diff -c openafs/src/pam/afs_setcred.c:1.13 openafs/src/pam/afs_setcred.c:1.13.2.1
*** openafs/src/pam/afs_setcred.c:1.13	Tue Jul 15 19:15:56 2003
--- openafs/src/pam/afs_setcred.c	Sun May 29 23:37:48 2005
***************
*** 20,26 ****
  #include <security/pam_modules.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/pam/afs_setcred.c,v 1.13 2003/07/15 23:15:56 shadow Exp $");
  
  #include <sys/param.h>
  #include <afs/kautils.h>
--- 20,26 ----
  #include <security/pam_modules.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/pam/afs_setcred.c,v 1.13.2.1 2005/05/30 03:37:48 shadow Exp $");
  
  #include <sys/param.h>
  #include <afs/kautils.h>
***************
*** 170,176 ****
  	RET(PAM_AUTH_ERR);
      }
  #else
! #if     defined(AFS_LINUX20_ENV) || defined(AFS_FBSD_ENV)
      upwd = getpwnam(user);
  #else
      upwd = getpwnam_r(user, &unix_pwd, upwd_buf, sizeof(upwd_buf));
--- 170,176 ----
  	RET(PAM_AUTH_ERR);
      }
  #else
! #if     defined(AFS_LINUX20_ENV) || defined(AFS_FBSD_ENV) || defined(AFS_NBSD_ENV)
      upwd = getpwnam(user);
  #else
      upwd = getpwnam_r(user, &unix_pwd, upwd_buf, sizeof(upwd_buf));
Index: openafs/src/pam/test_pam.c
diff -c openafs/src/pam/test_pam.c:1.7 openafs/src/pam/test_pam.c:1.7.2.1
*** openafs/src/pam/test_pam.c:1.7	Tue Jul 15 19:15:57 2003
--- openafs/src/pam/test_pam.c	Sun May 29 23:37:48 2005
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/pam/test_pam.c,v 1.7 2003/07/15 23:15:57 shadow Exp $");
  
  #include <stdio.h>
  #include <security/pam_appl.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/pam/test_pam.c,v 1.7.2.1 2005/05/30 03:37:48 shadow Exp $");
  
  #include <stdio.h>
  #include <security/pam_appl.h>
***************
*** 34,40 ****
  static const char *new_envstring = "GOTHEREVIATESTPAM=1";
  static const char *new_homestring = "HOME=/tmp";
  
! #if defined(AFS_LINUX20_ENV) || defined(AFS_FBSD_ENV)
  #define getpassphrase getpass
  #endif
  
--- 34,40 ----
  static const char *new_envstring = "GOTHEREVIATESTPAM=1";
  static const char *new_homestring = "HOME=/tmp";
  
! #if defined(AFS_LINUX20_ENV) || defined(AFS_FBSD_ENV) || defined(AFS_NBSD_ENV)
  #define getpassphrase getpass
  #endif
  
Index: openafs/src/rx/rx.c
diff -c openafs/src/rx/rx.c:1.58.2.17 openafs/src/rx/rx.c:1.58.2.20
*** openafs/src/rx/rx.c:1.58.2.17	Wed Apr 20 17:23:47 2005
--- openafs/src/rx/rx.c	Mon May 30 00:57:36 2005
***************
*** 17,23 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx.c,v 1.58.2.17 2005/04/20 21:23:47 jaltman Exp $");
  
  #ifdef KERNEL
  #include "afs/sysincludes.h"
--- 17,23 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx.c,v 1.58.2.20 2005/05/30 04:57:36 shadow Exp $");
  
  #ifdef KERNEL
  #include "afs/sysincludes.h"
***************
*** 153,159 ****
   */
  
  extern pthread_mutex_t rx_stats_mutex;
- extern pthread_mutex_t rxkad_stats_mutex;
  extern pthread_mutex_t des_init_mutex;
  extern pthread_mutex_t des_random_mutex;
  extern pthread_mutex_t rx_clock_mutex;
--- 153,158 ----
***************
*** 207,214 ****
  	   (&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
- 	   (&rxkad_stats_mutex, (const pthread_mutexattr_t *)0) == 0);
      assert(pthread_mutex_init(&rx_debug_mutex, (const pthread_mutexattr_t *)0)
  	   == 0);
  
--- 206,211 ----
***************
*** 218,223 ****
--- 215,222 ----
  	   == 0);
      assert(pthread_key_create(&rx_thread_id_key, NULL) == 0);
      assert(pthread_key_create(&rx_ts_info_key, NULL) == 0);
+  
+     rxkad_global_stats_init();
  }
  
  pthread_once_t rx_once_init = PTHREAD_ONCE_INIT;
***************
*** 1073,1086 ****
       * If so, let them go first to avoid starving them.
       * This is a fairly simple scheme, and might not be
       * a complete solution for large numbers of waiters.
       */
      if (conn->makeCallWaiters) {
  #ifdef	RX_ENABLE_LOCKS
! 	CV_WAIT(&conn->conn_call_cv, &conn->conn_call_lock);
  #else
! 	osi_rxSleep(conn);
  #endif
!     }
  
      for (;;) {
  	for (i = 0; i < RX_MAXCALLS; i++) {
--- 1072,1103 ----
       * If so, let them go first to avoid starving them.
       * This is a fairly simple scheme, and might not be
       * a complete solution for large numbers of waiters.
+      * 
+      * makeCallWaiters keeps track of the number of 
+      * threads waiting to make calls and the 
+      * RX_CONN_MAKECALL_WAITING flag bit is used to 
+      * indicate that there are indeed calls waiting.
+      * The flag is set when the waiter is incremented.
+      * It is only cleared in rx_EndCall when 
+      * makeCallWaiters is 0.  This prevents us from 
+      * accidently destroying the connection while it
+      * is potentially about to be used.
       */
+     MUTEX_ENTER(&conn->conn_data_lock);
      if (conn->makeCallWaiters) {
+ 	conn->flags |= RX_CONN_MAKECALL_WAITING;
+ 	conn->makeCallWaiters++;
+         MUTEX_EXIT(&conn->conn_data_lock);
+ 
  #ifdef	RX_ENABLE_LOCKS
!         CV_WAIT(&conn->conn_call_cv, &conn->conn_call_lock);
  #else
!         osi_rxSleep(conn);
  #endif
! 	MUTEX_ENTER(&conn->conn_data_lock);
! 	conn->makeCallWaiters--;
!     } 
!     MUTEX_EXIT(&conn->conn_data_lock);
  
      for (;;) {
  	for (i = 0; i < RX_MAXCALLS; i++) {
***************
*** 1103,1117 ****
  	}
  	MUTEX_ENTER(&conn->conn_data_lock);
  	conn->flags |= RX_CONN_MAKECALL_WAITING;
  	MUTEX_EXIT(&conn->conn_data_lock);
  
- 	conn->makeCallWaiters++;
  #ifdef	RX_ENABLE_LOCKS
  	CV_WAIT(&conn->conn_call_cv, &conn->conn_call_lock);
  #else
  	osi_rxSleep(conn);
  #endif
  	conn->makeCallWaiters--;
      }
      /*
       * Wake up anyone else who might be giving us a chance to
--- 1120,1136 ----
  	}
  	MUTEX_ENTER(&conn->conn_data_lock);
  	conn->flags |= RX_CONN_MAKECALL_WAITING;
+ 	conn->makeCallWaiters++;
  	MUTEX_EXIT(&conn->conn_data_lock);
  
  #ifdef	RX_ENABLE_LOCKS
  	CV_WAIT(&conn->conn_call_cv, &conn->conn_call_lock);
  #else
  	osi_rxSleep(conn);
  #endif
+ 	MUTEX_ENTER(&conn->conn_data_lock);
  	conn->makeCallWaiters--;
+ 	MUTEX_EXIT(&conn->conn_data_lock);
      }
      /*
       * Wake up anyone else who might be giving us a chance to
***************
*** 1876,1881 ****
--- 1895,1903 ----
  	 * rx_NewCall is in a stable state. Otherwise, rx_NewCall may
  	 * have checked this call, found it active and by the time it
  	 * goes to sleep, will have missed the signal.
+          *
+          * Do not clear the RX_CONN_MAKECALL_WAITING flag as long as
+          * there are threads waiting to use the conn object.
  	 */
  	MUTEX_EXIT(&call->lock);
  	MUTEX_ENTER(&conn->conn_call_lock);
***************
*** 1883,1889 ****
  	MUTEX_ENTER(&conn->conn_data_lock);
  	conn->flags |= RX_CONN_BUSY;
  	if (conn->flags & RX_CONN_MAKECALL_WAITING) {
! 	    conn->flags &= (~RX_CONN_MAKECALL_WAITING);
  	    MUTEX_EXIT(&conn->conn_data_lock);
  #ifdef	RX_ENABLE_LOCKS
  	    CV_BROADCAST(&conn->conn_call_cv);
--- 1905,1912 ----
  	MUTEX_ENTER(&conn->conn_data_lock);
  	conn->flags |= RX_CONN_BUSY;
  	if (conn->flags & RX_CONN_MAKECALL_WAITING) {
!             if (conn->makeCallWaiters == 0)
!                 conn->flags &= (~RX_CONN_MAKECALL_WAITING);
  	    MUTEX_EXIT(&conn->conn_data_lock);
  #ifdef	RX_ENABLE_LOCKS
  	    CV_BROADCAST(&conn->conn_call_cv);
***************
*** 1905,1921 ****
       * kernel version, and may interrupt the macros rx_Read or
       * rx_Write, which run at normal priority for efficiency. */
      if (call->currentPacket) {
! 	rxi_FreePacket(call->currentPacket);
  	call->currentPacket = (struct rx_packet *)0;
! 	call->nLeft = call->nFree = call->curlen = 0;
!     } else
! 	call->nLeft = call->nFree = call->curlen = 0;
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
!     for (queue_Scan(&call->iovq, tp, nxp, rx_packet)) {
! 	queue_Remove(tp);
! 	rxi_FreePacket(tp);
!     }
  
      CALL_RELE(call, RX_CALL_REFCOUNT_BEGIN);
      MUTEX_EXIT(&call->lock);
--- 1928,1941 ----
       * kernel version, and may interrupt the macros rx_Read or
       * rx_Write, which run at normal priority for efficiency. */
      if (call->currentPacket) {
! 	queue_Prepend(&call->iovq, call->currentPacket);
  	call->currentPacket = (struct rx_packet *)0;
!     }
! 	
!     call->nLeft = call->nFree = call->curlen = 0;
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
!     rxi_FreePackets(0, &call->iovq);
  
      CALL_RELE(call, RX_CALL_REFCOUNT_BEGIN);
      MUTEX_EXIT(&call->lock);
***************
*** 2169,2175 ****
       * If someone else destroys a connection, they either have no
       * call lock held or are going through this section of code.
       */
!     if (conn->flags & RX_CONN_DESTROY_ME) {
  	MUTEX_ENTER(&conn->conn_data_lock);
  	conn->refCount++;
  	MUTEX_EXIT(&conn->conn_data_lock);
--- 2189,2195 ----
       * If someone else destroys a connection, they either have no
       * call lock held or are going through this section of code.
       */
!     if (conn->flags & RX_CONN_DESTROY_ME && !(conn->flags & RX_CONN_MAKECALL_WAITING)) {
  	MUTEX_ENTER(&conn->conn_data_lock);
  	conn->refCount++;
  	MUTEX_EXIT(&conn->conn_data_lock);
***************
*** 4087,4094 ****
      int someAcked = 0;
  
      for (queue_Scan(&call->tq, p, tp, rx_packet)) {
- 	if (!p)
- 	    break;
  	p->flags |= RX_PKTFLAG_ACKED;
  	someAcked = 1;
      }
--- 4107,4112 ----
***************
*** 4123,4130 ****
      if (!force && (call->flags & RX_CALL_TQ_BUSY)) {
  	int someAcked = 0;
  	for (queue_Scan(&call->tq, p, tp, rx_packet)) {
- 	    if (!p)
- 		break;
  	    p->flags |= RX_PKTFLAG_ACKED;
  	    someAcked = 1;
  	}
--- 4141,4146 ----
***************
*** 4134,4145 ****
  	}
      } else {
  #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
! 	for (queue_Scan(&call->tq, p, tp, rx_packet)) {
! 	    if (!p)
! 		break;
! 	    queue_Remove(p);
! 	    rxi_FreePacket(p);
! 	}
  #ifdef	AFS_GLOBAL_RXLOCK_KERNEL
  	call->flags &= ~RX_CALL_TQ_CLEARME;
      }
--- 4150,4156 ----
  	}
      } else {
  #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
! 	rxi_FreePackets(0, &call->tq);
  #ifdef	AFS_GLOBAL_RXLOCK_KERNEL
  	call->flags &= ~RX_CALL_TQ_CLEARME;
      }
***************
*** 4164,4178 ****
  void
  rxi_ClearReceiveQueue(register struct rx_call *call)
  {
-     register struct rx_packet *p, *tp;
      if (queue_IsNotEmpty(&call->rq)) {
! 	for (queue_Scan(&call->rq, p, tp, rx_packet)) {
! 	    if (!p)
! 		break;
! 	    queue_Remove(p);
! 	    rxi_FreePacket(p);
! 	    rx_packetReclaims++;
! 	}
  	call->flags &= ~(RX_CALL_RECEIVE_DONE | RX_CALL_HAVE_LAST);
      }
      if (call->state == RX_STATE_PRECALL) {
--- 4175,4182 ----
  void
  rxi_ClearReceiveQueue(register struct rx_call *call)
  {
      if (queue_IsNotEmpty(&call->rq)) {
! 	rx_packetReclaims += rxi_FreePackets(0, &call->rq);
  	call->flags &= ~(RX_CALL_RECEIVE_DONE | RX_CALL_HAVE_LAST);
      }
      if (call->state == RX_STATE_PRECALL) {
***************
*** 4500,4505 ****
--- 4504,4512 ----
      register struct rx_packet *p;
      u_char offset;
      afs_int32 templ;
+ #ifdef RX_ENABLE_TSFPQ
+     struct rx_ts_info_t * rx_ts_info;
+ #endif
  
      /*
       * Open the receive window once a thread starts reading packets
***************
*** 4517,4540 ****
      if (p) {
  	rx_computelen(p, p->length);	/* reset length, you never know */
      } /* where that's been...         */
      else if (!(p = rxi_AllocPacket(RX_PACKET_CLASS_SPECIAL))) {
  	/* We won't send the ack, but don't panic. */
  	return optionalPacket;
      }
  
      templ =
  	rx_AckDataSize(call->rwind) + 4 * sizeof(afs_int32) -
  	rx_GetDataSize(p);
      if (templ > 0) {
! 	if (rxi_AllocDataBuf(p, templ, RX_PACKET_CLASS_SPECIAL)) {
  	    if (!optionalPacket)
  		rxi_FreePacket(p);
  	    return optionalPacket;
  	}
  	templ = rx_AckDataSize(call->rwind) + 2 * sizeof(afs_int32);
  	if (rx_Contiguous(p) < templ) {
  	    if (!optionalPacket)
  		rxi_FreePacket(p);
  	    return optionalPacket;
  	}
      }
--- 4524,4564 ----
      if (p) {
  	rx_computelen(p, p->length);	/* reset length, you never know */
      } /* where that's been...         */
+ #ifdef RX_ENABLE_TSFPQ
+     else {
+         RX_TS_INFO_GET(rx_ts_info);
+         if ((p = rx_ts_info->local_special_packet)) {
+             rx_computelen(p, p->length);
+         } else if ((p = rxi_AllocPacket(RX_PACKET_CLASS_SPECIAL))) {
+             rx_ts_info->local_special_packet = p;
+         } else { /* We won't send the ack, but don't panic. */
+             return optionalPacket;
+         }
+     }
+ #else
      else if (!(p = rxi_AllocPacket(RX_PACKET_CLASS_SPECIAL))) {
  	/* We won't send the ack, but don't panic. */
  	return optionalPacket;
      }
+ #endif
  
      templ =
  	rx_AckDataSize(call->rwind) + 4 * sizeof(afs_int32) -
  	rx_GetDataSize(p);
      if (templ > 0) {
! 	if (rxi_AllocDataBuf(p, templ, RX_PACKET_CLASS_SPECIAL) > 0) {
! #ifndef RX_ENABLE_TSFPQ
  	    if (!optionalPacket)
  		rxi_FreePacket(p);
+ #endif
  	    return optionalPacket;
  	}
  	templ = rx_AckDataSize(call->rwind) + 2 * sizeof(afs_int32);
  	if (rx_Contiguous(p) < templ) {
+ #ifndef RX_ENABLE_TSFPQ
  	    if (!optionalPacket)
  		rxi_FreePacket(p);
+ #endif
  	    return optionalPacket;
  	}
      }
***************
*** 4562,4569 ****
--- 4586,4595 ----
      for (offset = 0, queue_Scan(&call->rq, rqp, nxp, rx_packet)) {
  	if (!rqp || !call->rq.next
  	    || (rqp->header.seq > (call->rnext + call->rwind))) {
+ #ifndef RX_ENABLE_TSFPQ
  	    if (!optionalPacket)
  		rxi_FreePacket(p);
+ #endif
  	    rxi_CallError(call, RX_CALL_DEAD);
  	    return optionalPacket;
  	}
***************
*** 4573,4580 ****
--- 4599,4608 ----
  	ap->acks[offset++] = RX_ACK_TYPE_ACK;
  
  	if ((offset > (u_char) rx_maxReceiveWindow) || (offset > call->rwind)) {
+ #ifndef RX_ENABLE_TSFPQ
  	    if (!optionalPacket)
  		rxi_FreePacket(p);
+ #endif
  	    rxi_CallError(call, RX_CALL_DEAD);
  	    return optionalPacket;
  	}
***************
*** 4654,4661 ****
--- 4682,4691 ----
      MUTEX_ENTER(&rx_stats_mutex);
      rx_stats.ackPacketsSent++;
      MUTEX_EXIT(&rx_stats_mutex);
+ #ifndef RX_ENABLE_TSFPQ
      if (!optionalPacket)
  	rxi_FreePacket(p);
+ #endif
      return optionalPacket;	/* Return packet for re-use by caller */
  }
  
Index: openafs/src/rx/rx_globals.h
diff -c openafs/src/rx/rx_globals.h:1.9.2.8 openafs/src/rx/rx_globals.h:1.9.2.9
*** openafs/src/rx/rx_globals.h:1.9.2.8	Mon Apr 25 16:56:03 2005
--- openafs/src/rx/rx_globals.h	Sun May 29 23:41:45 2005
***************
*** 162,168 ****
--- 162,170 ----
          
          /* FPQ stats */
          int checkin_ops;
+         int checkin_xfer;
          int checkout_ops;
+         int checkout_xfer;
          int gtol_ops;
          int gtol_xfer;
          int ltog_ops;
***************
*** 170,175 ****
--- 172,178 ----
          int alloc_ops;
          int alloc_xfer;
      } _FPQ;
+     struct rx_packet * local_special_packet;
  } rx_ts_info_t;
  EXT struct rx_ts_info_t * rx_ts_info_init();   /* init function for thread-specific data struct */
  #define RX_TS_INFO_GET(ts_info_p) \
***************
*** 216,221 ****
--- 219,225 ----
  	(p)->niovecs = 2; \
  	(p)->length = RX_FIRSTBUFFERSIZE; \
      } while(0)
+ 
  #ifdef RX_ENABLE_LOCKS
  EXT afs_kmutex_t rx_freePktQ_lock;
  #endif /* RX_ENABLE_LOCKS */
***************
*** 329,334 ****
--- 333,354 ----
          RX_FPQ_MARK_USED(p); \
          (rx_ts_info_p)->_FPQ.len--; \
          (rx_ts_info_p)->_FPQ.checkout_ops++; \
+         (rx_ts_info_p)->_FPQ.checkout_xfer++; \
+     } while(0)
+ /* checkout multiple packets from the thread-specific free packet queue */
+ #define RX_TS_FPQ_CHECKOUT2(rx_ts_info_p,num_transfer,q) \
+     do { \
+         register int i; \
+         register struct rx_packet *p; \
+         for (i=0, p=queue_First(&((rx_ts_info_p)->_FPQ), rx_packet); \
+              i < (num_transfer); \
+              i++, p=queue_Next(p, rx_packet)) { \
+             RX_FPQ_MARK_USED(p); \
+         } \
+         queue_SplitBeforeAppend(&((rx_ts_info_p)->_FPQ),(q),p); \
+         (rx_ts_info_p)->_FPQ.len -= (num_transfer); \
+         (rx_ts_info_p)->_FPQ.checkout_ops++; \
+         (rx_ts_info_p)->_FPQ.checkout_xfer += (num_transfer); \
      } while(0)
  /* check a packet into the thread-specific free packet queue */
  #define RX_TS_FPQ_CHECKIN(rx_ts_info_p,p) \
***************
*** 337,342 ****
--- 357,378 ----
          RX_FPQ_MARK_FREE(p); \
          (rx_ts_info_p)->_FPQ.len++; \
          (rx_ts_info_p)->_FPQ.checkin_ops++; \
+         (rx_ts_info_p)->_FPQ.checkin_xfer++; \
+     } while(0)
+ /* check multiple packets into the thread-specific free packet queue */
+ /* num_transfer must equal length of (q); it is not a means of checking 
+  * in part of (q).  passing num_transfer just saves us instructions 
+  * since caller already knows length of (q) for other reasons */
+ #define RX_TS_FPQ_CHECKIN2(rx_ts_info_p,num_transfer,q) \
+     do { \
+         register struct rx_packet *p, *np; \
+         for (queue_Scan((q), p, np, rx_packet)) { \
+             RX_FPQ_MARK_FREE(p); \
+         } \
+         queue_SplicePrepend(&((rx_ts_info_p)->_FPQ),(q)); \
+         (rx_ts_info_p)->_FPQ.len += (num_transfer); \
+         (rx_ts_info_p)->_FPQ.checkin_ops++; \
+         (rx_ts_info_p)->_FPQ.checkin_xfer += (num_transfer); \
      } while(0)
  #endif /* AFS_PTHREAD_ENV */
  
Index: openafs/src/rx/rx_packet.c
diff -c openafs/src/rx/rx_packet.c:1.35.2.14 openafs/src/rx/rx_packet.c:1.35.2.15
*** openafs/src/rx/rx_packet.c:1.35.2.14	Wed Apr 20 17:23:47 2005
--- openafs/src/rx/rx_packet.c	Sun May 29 23:41:45 2005
***************
*** 15,21 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_packet.c,v 1.35.2.14 2005/04/20 21:23:47 jaltman Exp $");
  
  #ifdef KERNEL
  #if defined(UKERNEL)
--- 15,21 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_packet.c,v 1.35.2.15 2005/05/30 03:41:45 jaltman Exp $");
  
  #ifdef KERNEL
  #if defined(UKERNEL)
***************
*** 108,113 ****
--- 108,115 ----
  extern char cml_version_number[];
  extern int (*rx_almostSent) ();
  
+ static int AllocPacketBufs(int class, int num_pkts, struct rx_queue *q);
+ 
  static void rxi_SendDebugPacket(struct rx_packet *apacket, osi_socket asocket,
  				afs_int32 ahost, short aport,
  				afs_int32 istack);
***************
*** 244,282 ****
      return (resid ? (r - resid) : r);
  }
  
  #ifdef RX_ENABLE_TSFPQ
! static struct rx_packet *
! allocCBuf(int class)
  {
!     struct rx_packet *c;
      register struct rx_ts_info_t * rx_ts_info;
      SPLVAR;
  
      RX_TS_INFO_GET(rx_ts_info);
  
!     if (queue_IsEmpty(&rx_ts_info->_FPQ)) {
          NETPRI;
          MUTEX_ENTER(&rx_freePktQ_lock);
! 
! 	if (queue_IsEmpty(&rx_freePacketQueue)) {
! 	    rxi_MorePacketsNoLock(rx_initSendWindow);
  	}
  
! 	RX_TS_FPQ_GTOL(rx_ts_info);
  
  	MUTEX_EXIT(&rx_freePktQ_lock);
  	USERPRI;
      }
  
!     RX_TS_FPQ_CHECKOUT(rx_ts_info, c);
  
!     return c;
  }
  #else /* RX_ENABLE_TSFPQ */
! static struct rx_packet *
! allocCBuf(int class)
  {
      struct rx_packet *c;
      SPLVAR;
  
      NETPRI;
--- 246,308 ----
      return (resid ? (r - resid) : r);
  }
  
+ int
+ rxi_AllocPackets(int class, int num_pkts, struct rx_queue * q)
+ {
+     register struct rx_packet *p, *np;
+ 
+     num_pkts = AllocPacketBufs(class, num_pkts, q);
+ 
+     for (queue_Scan(q, p, np, rx_packet)) {
+         RX_PACKET_IOV_FULLINIT(p);
+     }
+ 
+     return num_pkts;
+ }
+ 
  #ifdef RX_ENABLE_TSFPQ
! static int
! AllocPacketBufs(int class, int num_pkts, struct rx_queue * q)
  {
!     register struct rx_packet *c;
      register struct rx_ts_info_t * rx_ts_info;
+     int transfer, alloc;
      SPLVAR;
  
      RX_TS_INFO_GET(rx_ts_info);
  
!     transfer = num_pkts - rx_ts_info->_FPQ.len;
!     if (transfer > 0) {
          NETPRI;
          MUTEX_ENTER(&rx_freePktQ_lock);
! 	
! 	if ((transfer + rx_TSFPQGlobSize) <= rx_nFreePackets) {
! 	    transfer += rx_TSFPQGlobSize;
! 	} else if (transfer <= rx_nFreePackets) {
! 	    transfer = rx_nFreePackets;
! 	} else {
! 	    /* alloc enough for us, plus a few globs for other threads */
! 	    alloc = transfer + (3 * rx_TSFPQGlobSize) - rx_nFreePackets;
! 	    rxi_MorePacketsNoLock(MAX(alloc, rx_initSendWindow));
! 	    transfer += rx_TSFPQGlobSize;
  	}
  
! 	RX_TS_FPQ_GTOL2(rx_ts_info, transfer);
  
  	MUTEX_EXIT(&rx_freePktQ_lock);
  	USERPRI;
      }
  
!     RX_TS_FPQ_CHECKOUT2(rx_ts_info, num_pkts, q);
  
!     return num_pkts;
  }
  #else /* RX_ENABLE_TSFPQ */
! static int
! AllocPacketBufs(int class, int num_pkts, struct rx_queue * q)
  {
      struct rx_packet *c;
+     int i, overq = 0;
      SPLVAR;
  
      NETPRI;
***************
*** 284,291 ****
      MUTEX_ENTER(&rx_freePktQ_lock);
  
  #ifdef KERNEL
!     if (rxi_OverQuota(class)) {
! 	c = NULL;
  	rxi_NeedMorePackets = TRUE;
  	MUTEX_ENTER(&rx_stats_mutex);
  	switch (class) {
--- 310,319 ----
      MUTEX_ENTER(&rx_freePktQ_lock);
  
  #ifdef KERNEL
!     for (; (num_pkts > 0) && (rxi_OverQuota2(class,num_pkts)); 
! 	 num_pkts--, overq++);
! 
!     if (overq) {
  	rxi_NeedMorePackets = TRUE;
  	MUTEX_ENTER(&rx_stats_mutex);
  	switch (class) {
***************
*** 306,332 ****
  	    break;
  	}
  	MUTEX_EXIT(&rx_stats_mutex);
- 	goto done;
      }
  
!     if (queue_IsEmpty(&rx_freePacketQueue)) {
! 	c = NULL;
  	rxi_NeedMorePackets = TRUE;
  	goto done;
      }
  #else /* KERNEL */
!     if (queue_IsEmpty(&rx_freePacketQueue)) {
! 	rxi_MorePacketsNoLock(rx_initSendWindow);
      }
  #endif /* KERNEL */
  
!     rx_nFreePackets--;
!     c = queue_First(&rx_freePacketQueue, rx_packet);
!     queue_Remove(c);
!     if (!(c->flags & RX_PKTFLAG_FREE))
! 	osi_Panic("rxi_AllocPacket: packet not free\n");
!     c->flags = 0;		/* clear RX_PKTFLAG_FREE, initialize the rest */
!     c->header.flags = 0;
  
  #ifdef KERNEL
    done:
--- 334,363 ----
  	    break;
  	}
  	MUTEX_EXIT(&rx_stats_mutex);
      }
  
!     if (rx_nFreePackets < num_pkts)
!         num_pkts = rx_nFreePackets;
! 
!     if (!num_pkts) {
  	rxi_NeedMorePackets = TRUE;
  	goto done;
      }
  #else /* KERNEL */
!     if (rx_nFreePackets < num_pkts) {
!         rxi_MorePacketsNoLock(MAX((num_pkts-rx_nFreePackets), rx_initSendWindow));
      }
  #endif /* KERNEL */
  
!     for (i=0, c=queue_First(&rx_freePacketQueue, rx_packet);
! 	 i < num_pkts; 
! 	 i++, c=queue_Next(c, rx_packet)) {
!         RX_FPQ_MARK_USED(c);
!     }
! 
!     queue_SplitBeforeAppend(&rx_freePacketQueue,q,c);
! 
!     rx_nFreePackets -= num_pkts;
  
  #ifdef KERNEL
    done:
***************
*** 334,340 ****
      MUTEX_EXIT(&rx_freePktQ_lock);
  
      USERPRI;
!     return c;
  }
  #endif /* RX_ENABLE_TSFPQ */
  
--- 365,371 ----
      MUTEX_EXIT(&rx_freePktQ_lock);
  
      USERPRI;
!     return num_pkts;
  }
  #endif /* RX_ENABLE_TSFPQ */
  
***************
*** 342,356 ****
   * Free a packet currently used as a continuation buffer
   */
  #ifdef RX_ENABLE_TSFPQ
! void
! rxi_freeCBuf(struct rx_packet *c)
  {
      register struct rx_ts_info_t * rx_ts_info;
!     register int i;
      SPLVAR;
  
      RX_TS_INFO_GET(rx_ts_info);
!     RX_TS_FPQ_CHECKIN(rx_ts_info,c);
  
      if (rx_ts_info->_FPQ.len > rx_TSFPQLocalMax) {
          NETPRI;
--- 373,394 ----
   * Free a packet currently used as a continuation buffer
   */
  #ifdef RX_ENABLE_TSFPQ
! /* num_pkts=0 means queue length is unknown */
! int
! rxi_FreePackets(int num_pkts, struct rx_queue * q)
  {
      register struct rx_ts_info_t * rx_ts_info;
!     register struct rx_packet *c, *nc;
      SPLVAR;
  
+     if (!num_pkts) {
+ 	queue_Count(q, c, nc, rx_packet, num_pkts);
+ 	if (!num_pkts)
+ 	    return 0;
+     }
+ 
      RX_TS_INFO_GET(rx_ts_info);
!     RX_TS_FPQ_CHECKIN2(rx_ts_info, num_pkts, q);
  
      if (rx_ts_info->_FPQ.len > rx_TSFPQLocalMax) {
          NETPRI;
***************
*** 364,385 ****
  	MUTEX_EXIT(&rx_freePktQ_lock);
  	USERPRI;
      }
  }
  #else /* RX_ENABLE_TSFPQ */
! void
! rxi_freeCBuf(struct rx_packet *c)
  {
      SPLVAR;
  
      NETPRI;
      MUTEX_ENTER(&rx_freePktQ_lock);
  
!     rxi_FreePacketNoLock(c);
      /* Wakeup anyone waiting for packets */
      rxi_PacketsUnWait();
  
      MUTEX_EXIT(&rx_freePktQ_lock);
      USERPRI;
  }
  #endif /* RX_ENABLE_TSFPQ */
  
--- 402,443 ----
  	MUTEX_EXIT(&rx_freePktQ_lock);
  	USERPRI;
      }
+ 
+     return num_pkts;
  }
  #else /* RX_ENABLE_TSFPQ */
! /* num_pkts=0 means queue length is unknown */
! int
! rxi_FreePackets(int num_pkts, struct rx_queue *q)
  {
+     register struct rx_packet *p, *np;
      SPLVAR;
  
+     if (!num_pkts) {
+         for (queue_Scan(q, p, np, rx_packet), num_pkts++) {
+             RX_FPQ_MARK_FREE(p);
+ 	}
+ 	if (!num_pkts)
+ 	    return 0;
+     } else {
+         for (queue_Scan(q, p, np, rx_packet)) {
+             RX_FPQ_MARK_FREE(p);
+ 	}
+     }
+ 
      NETPRI;
      MUTEX_ENTER(&rx_freePktQ_lock);
  
!     queue_SpliceAppend(&rx_freePacketQueue, q);
!     rx_nFreePackets += num_pkts;
! 
      /* Wakeup anyone waiting for packets */
      rxi_PacketsUnWait();
  
      MUTEX_EXIT(&rx_freePktQ_lock);
      USERPRI;
+ 
+     return num_pkts;
  }
  #endif /* RX_ENABLE_TSFPQ */
  
***************
*** 414,437 ****
   * returns the number of bytes >0 which it failed to come up with.
   * Don't need to worry about locking on packet, since only
   * one thread can manipulate one at a time. Locking on continution
!  * packets is handled by allocCBuf */
  /* MTUXXX don't need to go throught the for loop if we can trust niovecs */
  int
  rxi_AllocDataBuf(struct rx_packet *p, int nb, int class)
  {
!     int i;
! 
!     for (i = p->niovecs; nb > 0 && i < RX_MAXWVECS; i++) {
! 	register struct rx_packet *cb;
! 	if ((cb = allocCBuf(class))) {
! 	    p->wirevec[i].iov_base = (caddr_t) cb->localdata;
! 	    p->wirevec[i].iov_len = RX_CBUFFERSIZE;
! 	    nb -= RX_CBUFFERSIZE;
! 	    p->length += RX_CBUFFERSIZE;
! 	    p->niovecs++;
! 	} else
! 	    break;
!     }
  
      return nb;
  }
--- 472,509 ----
   * returns the number of bytes >0 which it failed to come up with.
   * Don't need to worry about locking on packet, since only
   * one thread can manipulate one at a time. Locking on continution
!  * packets is handled by AllocPacketBufs */
  /* MTUXXX don't need to go throught the for loop if we can trust niovecs */
  int
  rxi_AllocDataBuf(struct rx_packet *p, int nb, int class)
  {
!     int i, nv;
!     struct rx_queue q;
!     register struct rx_packet *cb, *ncb;
! 
!     /* compute the number of cbuf's we need */
!     nv = nb / RX_CBUFFERSIZE;
!     if ((nv * RX_CBUFFERSIZE) < nb)
!         nv++;
!     if ((nv + p->niovecs) > RX_MAXWVECS)
!         nv = RX_MAXWVECS - p->niovecs;
!     if (nv < 1)
!         return nb;
! 
!     /* allocate buffers */
!     queue_Init(&q);
!     nv = AllocPacketBufs(class, nv, &q);
! 
!     /* setup packet iovs */
!     for (i = p->niovecs, queue_Scan(&q, cb, ncb, rx_packet), i++) {
!         queue_Remove(cb);
!         p->wirevec[i].iov_base = (caddr_t) cb->localdata;
!         p->wirevec[i].iov_len = RX_CBUFFERSIZE;
!     }
! 
!     nb -= (nv * RX_CBUFFERSIZE);
!     p->length += (nv * RX_CBUFFERSIZE);
!     p->niovecs += nv;
  
      return nb;
  }
***************
*** 2455,2464 ****
      if (len > 0) {
  	osi_Panic("PrepareSendPacket 1\n");	/* MTUXXX */
      } else {
  	/* Free any extra elements in the wirevec */
! 	for (j = MAX(2, i); j < p->niovecs; j++) {
! 	    rxi_freeCBuf(RX_CBUF_TO_PACKET(p->wirevec[j].iov_base, p));
  	}
  	p->niovecs = i;
  	p->wirevec[i - 1].iov_len += len;
      }
--- 2527,2544 ----
      if (len > 0) {
  	osi_Panic("PrepareSendPacket 1\n");	/* MTUXXX */
      } else {
+         struct rx_queue q;
+        int nb;
+ 
+ 	queue_Init(&q);
+ 
  	/* Free any extra elements in the wirevec */
! 	for (j = MAX(2, i), nb = j - p->niovecs; j < p->niovecs; j++) {
! 	    queue_Append(&q,RX_CBUF_TO_PACKET(p->wirevec[j].iov_base, p));
  	}
+ 	if (nb)
+ 	    rxi_FreePackets(nb, &q);
+ 
  	p->niovecs = i;
  	p->wirevec[i - 1].iov_len += len;
      }
Index: openafs/src/rx/rx_packet.h
diff -c openafs/src/rx/rx_packet.h:1.13 openafs/src/rx/rx_packet.h:1.13.2.1
*** openafs/src/rx/rx_packet.h:1.13	Tue Feb  3 01:23:39 2004
--- openafs/src/rx/rx_packet.h	Sun May 29 23:41:45 2005
***************
*** 293,298 ****
--- 293,299 ----
  
  #ifdef KERNEL
  #define rxi_OverQuota(packetclass) (rx_nFreePackets - 1 < rx_packetQuota[packetclass])
+ #define rxi_OverQuota2(packetclass,num_alloc) (rx_nFreePackets - (num_alloc) < rx_packetQuota[packetclass])
  #endif /* KERNEL */
  
  /* this returns an afs_int32 from byte offset o in packet p.  offset must
Index: openafs/src/rx/rx_prototypes.h
diff -c openafs/src/rx/rx_prototypes.h:1.14.2.8 openafs/src/rx/rx_prototypes.h:1.14.2.10
*** openafs/src/rx/rx_prototypes.h:1.14.2.8	Mon Apr 25 13:19:59 2005
--- openafs/src/rx/rx_prototypes.h	Sun May 29 23:41:45 2005
***************
*** 439,445 ****
  				   unsigned int offset, int resid, char *out);
  extern afs_int32 rx_SlowWritePacket(struct rx_packet *packet, int offset,
  				    int resid, char *in);
- extern void rxi_freeCBuf(struct rx_packet *c);
  extern int rxi_RoundUpPacket(struct rx_packet *p, unsigned int nb);
  extern int rxi_AllocDataBuf(struct rx_packet *p, int nb, int cla_ss);
  extern void rxi_MorePackets(int apackets);
--- 439,444 ----
***************
*** 453,458 ****
--- 452,459 ----
  extern void rxi_FreePacket(struct rx_packet *p);
  extern struct rx_packet *rxi_AllocPacketNoLock(int cla_ss);
  extern struct rx_packet *rxi_AllocPacket(int cla_ss);
+ extern int rxi_AllocPackets(int cla_ss, int num_pkts, struct rx_queue *q);
+ extern int rxi_FreePackets(int num_pkts, struct rx_queue *q);
  extern struct rx_packet *rxi_AllocSendPacket(register struct rx_call *call,
  					     int want);
  extern int rxi_ReadPacket(int socket, register struct rx_packet *p,
***************
*** 535,543 ****
  extern void rxi_FlushWrite(register struct rx_call *call);
  extern void rx_FlushWrite(struct rx_call *call);
  
- /* rx_stream.c */
- 
- 
  /* rx_trace.c */
  
  
--- 536,541 ----
Index: openafs/src/rx/rx_queue.h
diff -c openafs/src/rx/rx_queue.h:1.3.2.1 openafs/src/rx/rx_queue.h:1.3.2.2
*** openafs/src/rx/rx_queue.h:1.3.2.1	Mon Apr 25 16:56:03 2005
--- openafs/src/rx/rx_queue.h	Mon May 30 22:12:25 2005
***************
*** 58,71 ****
  /* INTERNAL macros */
  
  /* This one coerces the user's structure to a queue element (or queue head) */
! #define	_Q(x) ((struct rx_queue *)(x))
  
  /* This one adds a queue element (i) before or after another queue element (or queue head) (q), doubly linking everything together.  It's called by the user usable macros, below.  If (a,b) is (next,prev) then the element i is linked after q; if it is (prev,next) then it is linked before q */
  /* N.B.  I don't think it is possible to write this expression, correctly, with less than one comma (you can easily write an alternative expression with no commas that works with most or all compilers, but it's not clear that it really is un-ambiguous, legal C-code). */
! #define _QA(q,i,a,b) (((i->a=q->a)->b=i)->b=q, q->a=i)
  
  /* These ones splice two queues together.  If (a,b) is (next,prev) then (*q2) is prepended to (*q1), otherwise (*q2) is appended to (*q1). */
! #define _QS(q1,q2,a,b) if (queue_IsEmpty(q2)); else \
      ((((q2->a->b=q1)->a->b=q2->b)->a=q1->a, q1->a=q2->a), queue_Init(q2))
  
  /* This one removes part of queue (*q1) and attaches it to queue (*q2).
--- 58,71 ----
  /* INTERNAL macros */
  
  /* This one coerces the user's structure to a queue element (or queue head) */
! #define	_RXQ(x) ((struct rx_queue *)(x))
  
  /* This one adds a queue element (i) before or after another queue element (or queue head) (q), doubly linking everything together.  It's called by the user usable macros, below.  If (a,b) is (next,prev) then the element i is linked after q; if it is (prev,next) then it is linked before q */
  /* N.B.  I don't think it is possible to write this expression, correctly, with less than one comma (you can easily write an alternative expression with no commas that works with most or all compilers, but it's not clear that it really is un-ambiguous, legal C-code). */
! #define _RXQA(q,i,a,b) (((i->a=q->a)->b=i)->b=q, q->a=i)
  
  /* These ones splice two queues together.  If (a,b) is (next,prev) then (*q2) is prepended to (*q1), otherwise (*q2) is appended to (*q1). */
! #define _RXQS(q1,q2,a,b) if (queue_IsEmpty(q2)); else \
      ((((q2->a->b=q1)->a->b=q2->b)->a=q1->a, q1->a=q2->a), queue_Init(q2))
  
  /* This one removes part of queue (*q1) and attaches it to queue (*q2).
***************
*** 75,168 ****
   * otherwise the subchain is the elements in (*q1) after (i).
   * If (x,y) is (q1,i) then operation is either BeforePrepend of AfterAppend.
   * If (x,y) is (i,q1) then operation is either BeforeAppend or AfterPrepend. */
! #define _QSP(q1,q2,i,a,b,c,d,x,y) if (!queue_IsEnd(q1,i->c)) \
      (((y->b->a=q2->a)->b=y->b), ((x->a->b=q2)->a=x->a), ((i->c=q1)->d=i))
  
  /* Basic remove operation.  Doesn't update the queue item to indicate it's been removed */
! #define _QR(i) ((_Q(i)->prev->next=_Q(i)->next)->prev=_Q(i)->prev)
  
  /* EXPORTED macros */
  
  /* Initialize a queue head (*q).  A queue head is just a queue element */
! #define queue_Init(q) (_Q(q))->prev = (_Q(q))->next = (_Q(q))
  
  /* Prepend a queue element (*i) to the head of the queue, after the queue head (*q).  The new queue element should not currently be on any list. */
! #define queue_Prepend(q,i) _QA(_Q(q),_Q(i),next,prev)
  
  /* Append a queue element (*i) to the end of the queue, before the queue head (*q).  The new queue element should not currently be on any list. */
! #define queue_Append(q,i) _QA(_Q(q),_Q(i),prev,next)
  
  /* Insert a queue element (*i2) before another element (*i1) in the queue.  The new queue element should not currently be on any list. */
! #define queue_InsertBefore(i1,i2) _QA(_Q(i1),_Q(i2),prev,next)
  
  /* Insert a queue element (*i2) after another element (*i1) in the queue.  The new queue element should not currently be on any list. */
! #define queue_InsertAfter(i1,i2) _QA(_Q(i1),_Q(i2),next,prev)
  
  /* Spice the members of (*q2) to the beginning of (*q1), re-initialize (*q2) */
! #define queue_SplicePrepend(q1,q2) _QS(_Q(q1),_Q(q2),next,prev)
  
  /* Splice the members of queue (*q2) to the end of (*q1), re-initialize (*q2) */
! #define queue_SpliceAppend(q1,q2) _QS(_Q(q1),_Q(q2),prev,next)
  
  /* split the members after i off of queue (*q1), and append them onto queue (*q2) */
! #define queue_SplitAfterAppend(q1,q2,i) _QSP(_Q(q1),_Q(q2),_Q(i),prev,next,next,prev,_Q(q1),_Q(i))
  
  /* split the members after i off of queue (*q1), and prepend them onto queue (*q2) */
! #define queue_SplitAfterPrepend(q1,q2,i) _QSP(_Q(q1),_Q(q2),_Q(i),next,prev,next,prev,_Q(i),_Q(q1))
  
  /* split the members before i off of queue (*q1), and append them onto queue (*q2) */
! #define queue_SplitBeforeAppend(q1,q2,i) _QSP(_Q(q1),_Q(q2),_Q(i),prev,next,prev,next,_Q(i),_Q(q1))
  
  /* split the members before i off of queue (*q1), and prepend them onto queue (*q2) */
! #define queue_SplitBeforePrepend(q1,q2,i) _QSP(_Q(q1),_Q(q2),_Q(i),next,prev,prev,next,_Q(q1),_Q(i))
  
  /* Replace the queue (*q1) with the contents of the queue (*q2), re-initialize (*q2) */
  #define queue_Replace(q1,q2) if (queue_IsEmpty(q2)) queue_Init(q1); else \
!     (*_Q(q1) = *_Q(q2), _Q(q1)->next->prev = _Q(q1)->prev->next = _Q(q1), queue_Init(q2))
  
  /* Remove a queue element (*i) from it's queue.  The next field is 0'd, so that any further use of this q entry will hopefully cause a core dump.  Multiple removes of the same queue item are not supported */
! #define queue_Remove(i) (_QR(i), _Q(i)->next = 0)
  
  /* Move the queue element (*i) from it's queue to the end of the queue (*q) */
! #define queue_MoveAppend(q,i) (_QR(i), queue_Append(q,i))
  
  /* Move the queue element (*i) from it's queue to the head of the queue (*q) */
! #define queue_MovePrepend(q,i) (_QR(i), queue_Prepend(q,i))
  
  /* Return the first element of a queue, coerced too the specified structure s */
  /* Warning:  this returns the queue head, if the queue is empty */
! #define queue_First(q,s) ((struct s *)_Q(q)->next)
  
  /* Return the last element of a queue, coerced to the specified structure s */
  /* Warning:  this returns the queue head, if the queue is empty */
! #define queue_Last(q,s) ((struct s *)_Q(q)->prev)
  
  /* Return the next element in a queue, beyond the specified item, coerced to the specified structure s */
  /* Warning:  this returns the queue head, if the item specified is the last in the queue */
! #define queue_Next(i,s) ((struct s *)_Q(i)->next)
  
  /* Return the previous element to a specified element of a queue, coerced to the specified structure s */
  /* Warning:  this returns the queue head, if the item specified is the first in the queue */
! #define queue_Prev(i,s) ((struct s *)_Q(i)->prev)
  
  /* Return true if the queue is empty, i.e. just consists of a queue head.  The queue head must have been initialized some time prior to this call */
! #define queue_IsEmpty(q) (_Q(q)->next == _Q(q))
  
  /* Return true if the queue is non-empty, i.e. consists of a queue head plus at least one queue item */
! #define queue_IsNotEmpty(q) (_Q(q)->next != _Q(q))
  
  /* Return true if the queue item is currently in a queue */
  /* Returns false if the item was removed from a queue OR is uninitialized (zero) */
! #define queue_IsOnQueue(i) (_Q(i)->next != 0)
  
  /* Returns true if the queue item (i) is the first element of the queue (q) */
! #define queue_IsFirst(q,i) (_Q(q)->first == _Q(i))
  
  /* Returns true if the queue item (i) is the last element of the queue (q) */
! #define queue_IsLast(q,i) (_Q(q)->prev == _Q(i))
  
  /* Returns true if the queue item (i) is the end of the queue (q), that is, i is the head of the queue */
! #define queue_IsEnd(q,i) (_Q(q) == _Q(i))
  
  /* Prototypical loop to scan an entire queue forwards.  q is the queue
   * head, qe is the loop variable, next is a variable used to store the
--- 75,168 ----
   * otherwise the subchain is the elements in (*q1) after (i).
   * If (x,y) is (q1,i) then operation is either BeforePrepend of AfterAppend.
   * If (x,y) is (i,q1) then operation is either BeforeAppend or AfterPrepend. */
! #define _RXQSP(q1,q2,i,a,b,c,d,x,y) if (!queue_IsEnd(q1,i->c)) \
      (((y->b->a=q2->a)->b=y->b), ((x->a->b=q2)->a=x->a), ((i->c=q1)->d=i))
  
  /* Basic remove operation.  Doesn't update the queue item to indicate it's been removed */
! #define _RXQR(i) ((_RXQ(i)->prev->next=_RXQ(i)->next)->prev=_RXQ(i)->prev)
  
  /* EXPORTED macros */
  
  /* Initialize a queue head (*q).  A queue head is just a queue element */
! #define queue_Init(q) (_RXQ(q))->prev = (_RXQ(q))->next = (_RXQ(q))
  
  /* Prepend a queue element (*i) to the head of the queue, after the queue head (*q).  The new queue element should not currently be on any list. */
! #define queue_Prepend(q,i) _RXQA(_RXQ(q),_RXQ(i),next,prev)
  
  /* Append a queue element (*i) to the end of the queue, before the queue head (*q).  The new queue element should not currently be on any list. */
! #define queue_Append(q,i) _RXQA(_RXQ(q),_RXQ(i),prev,next)
  
  /* Insert a queue element (*i2) before another element (*i1) in the queue.  The new queue element should not currently be on any list. */
! #define queue_InsertBefore(i1,i2) _RXQA(_RXQ(i1),_RXQ(i2),prev,next)
  
  /* Insert a queue element (*i2) after another element (*i1) in the queue.  The new queue element should not currently be on any list. */
! #define queue_InsertAfter(i1,i2) _RXQA(_RXQ(i1),_RXQ(i2),next,prev)
  
  /* Spice the members of (*q2) to the beginning of (*q1), re-initialize (*q2) */
! #define queue_SplicePrepend(q1,q2) _RXQS(_RXQ(q1),_RXQ(q2),next,prev)
  
  /* Splice the members of queue (*q2) to the end of (*q1), re-initialize (*q2) */
! #define queue_SpliceAppend(q1,q2) _RXQS(_RXQ(q1),_RXQ(q2),prev,next)
  
  /* split the members after i off of queue (*q1), and append them onto queue (*q2) */
! #define queue_SplitAfterAppend(q1,q2,i) _RXQSP(_RXQ(q1),_RXQ(q2),_RXQ(i),prev,next,next,prev,_RXQ(q1),_RXQ(i))
  
  /* split the members after i off of queue (*q1), and prepend them onto queue (*q2) */
! #define queue_SplitAfterPrepend(q1,q2,i) _RXQSP(_RXQ(q1),_RXQ(q2),_RXQ(i),next,prev,next,prev,_RXQ(i),_RXQ(q1))
  
  /* split the members before i off of queue (*q1), and append them onto queue (*q2) */
! #define queue_SplitBeforeAppend(q1,q2,i) _RXQSP(_RXQ(q1),_RXQ(q2),_RXQ(i),prev,next,prev,next,_RXQ(i),_RXQ(q1))
  
  /* split the members before i off of queue (*q1), and prepend them onto queue (*q2) */
! #define queue_SplitBeforePrepend(q1,q2,i) _RXQSP(_RXQ(q1),_RXQ(q2),_RXQ(i),next,prev,prev,next,_RXQ(q1),_RXQ(i))
  
  /* Replace the queue (*q1) with the contents of the queue (*q2), re-initialize (*q2) */
  #define queue_Replace(q1,q2) if (queue_IsEmpty(q2)) queue_Init(q1); else \
!     (*_RXQ(q1) = *_RXQ(q2), _RXQ(q1)->next->prev = _RXQ(q1)->prev->next = _RXQ(q1), queue_Init(q2))
  
  /* Remove a queue element (*i) from it's queue.  The next field is 0'd, so that any further use of this q entry will hopefully cause a core dump.  Multiple removes of the same queue item are not supported */
! #define queue_Remove(i) (_RXQR(i), _RXQ(i)->next = 0)
  
  /* Move the queue element (*i) from it's queue to the end of the queue (*q) */
! #define queue_MoveAppend(q,i) (_RXQR(i), queue_Append(q,i))
  
  /* Move the queue element (*i) from it's queue to the head of the queue (*q) */
! #define queue_MovePrepend(q,i) (_RXQR(i), queue_Prepend(q,i))
  
  /* Return the first element of a queue, coerced too the specified structure s */
  /* Warning:  this returns the queue head, if the queue is empty */
! #define queue_First(q,s) ((struct s *)_RXQ(q)->next)
  
  /* Return the last element of a queue, coerced to the specified structure s */
  /* Warning:  this returns the queue head, if the queue is empty */
! #define queue_Last(q,s) ((struct s *)_RXQ(q)->prev)
  
  /* Return the next element in a queue, beyond the specified item, coerced to the specified structure s */
  /* Warning:  this returns the queue head, if the item specified is the last in the queue */
! #define queue_Next(i,s) ((struct s *)_RXQ(i)->next)
  
  /* Return the previous element to a specified element of a queue, coerced to the specified structure s */
  /* Warning:  this returns the queue head, if the item specified is the first in the queue */
! #define queue_Prev(i,s) ((struct s *)_RXQ(i)->prev)
  
  /* Return true if the queue is empty, i.e. just consists of a queue head.  The queue head must have been initialized some time prior to this call */
! #define queue_IsEmpty(q) (_RXQ(q)->next == _RXQ(q))
  
  /* Return true if the queue is non-empty, i.e. consists of a queue head plus at least one queue item */
! #define queue_IsNotEmpty(q) (_RXQ(q)->next != _RXQ(q))
  
  /* Return true if the queue item is currently in a queue */
  /* Returns false if the item was removed from a queue OR is uninitialized (zero) */
! #define queue_IsOnQueue(i) (_RXQ(i)->next != 0)
  
  /* Returns true if the queue item (i) is the first element of the queue (q) */
! #define queue_IsFirst(q,i) (_RXQ(q)->first == _RXQ(i))
  
  /* Returns true if the queue item (i) is the last element of the queue (q) */
! #define queue_IsLast(q,i) (_RXQ(q)->prev == _RXQ(i))
  
  /* Returns true if the queue item (i) is the end of the queue (q), that is, i is the head of the queue */
! #define queue_IsEnd(q,i) (_RXQ(q) == _RXQ(i))
  
  /* Prototypical loop to scan an entire queue forwards.  q is the queue
   * head, qe is the loop variable, next is a variable used to store the
Index: openafs/src/rx/rx_rdwr.c
diff -c openafs/src/rx/rx_rdwr.c:1.21.2.4 openafs/src/rx/rx_rdwr.c:1.21.2.5
*** openafs/src/rx/rx_rdwr.c:1.21.2.4	Wed Apr 13 22:31:44 2005
--- openafs/src/rx/rx_rdwr.c	Sun May 29 23:41:45 2005
***************
*** 15,21 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_rdwr.c,v 1.21.2.4 2005/04/14 02:31:44 shadow Exp $");
  
  #ifdef KERNEL
  #ifndef UKERNEL
--- 15,21 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_rdwr.c,v 1.21.2.5 2005/05/30 03:41:45 jaltman Exp $");
  
  #ifdef KERNEL
  #ifndef UKERNEL
***************
*** 107,124 ****
  {
      register struct rx_packet *cp = call->currentPacket;
      register struct rx_packet *rp;
-     register struct rx_packet *nxp;	/* Next packet pointer, for queue_Scan */
      register int requestCount;
      register unsigned int t;
  /* XXXX took out clock_NewTime from here.  Was it needed? */
      requestCount = nbytes;
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
!     if (!queue_IsEmpty(&call->iovq)) {
! 	for (queue_Scan(&call->iovq, rp, nxp, rx_packet)) {
! 	    queue_Remove(rp);
! 	    rxi_FreePacket(rp);
! 	}
      }
  
      do {
--- 107,121 ----
  {
      register struct rx_packet *cp = call->currentPacket;
      register struct rx_packet *rp;
      register int requestCount;
      register unsigned int t;
+ 
  /* XXXX took out clock_NewTime from here.  Was it needed? */
      requestCount = nbytes;
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
!     if (queue_IsNotEmpty(&call->iovq)) {
!         rxi_FreePackets(0, &call->iovq);
      }
  
      do {
***************
*** 310,321 ****
       * ReadvProc/WritevProc.
       */
      if (!queue_IsEmpty(&call->iovq)) {
! 	register struct rx_packet *rp;
! 	register struct rx_packet *nxp;
! 	for (queue_Scan(&call->iovq, rp, nxp, rx_packet)) {
! 	    queue_Remove(rp);
! 	    rxi_FreePacket(rp);
! 	}
      }
  
      /*
--- 307,313 ----
       * ReadvProc/WritevProc.
       */
      if (!queue_IsEmpty(&call->iovq)) {
!         rxi_FreePackets(0, &call->iovq);
      }
  
      /*
***************
*** 362,373 ****
       * ReadvProc/WritevProc.
       */
      if (!queue_IsEmpty(&call->iovq)) {
! 	register struct rx_packet *rp;
! 	register struct rx_packet *nxp;
! 	for (queue_Scan(&call->iovq, rp, nxp, rx_packet)) {
! 	    queue_Remove(rp);
! 	    rxi_FreePacket(rp);
! 	}
      }
  
      /*
--- 354,360 ----
       * ReadvProc/WritevProc.
       */
      if (!queue_IsEmpty(&call->iovq)) {
! 	rxi_FreePackets(0, &call->iovq);
      }
  
      /*
***************
*** 570,576 ****
  	      int nbytes)
  {
      struct rx_packet *rp;
-     struct rx_packet *nxp;	/* Next packet pointer, for queue_Scan */
      int requestCount;
      int nextio;
  
--- 557,562 ----
***************
*** 578,586 ****
      nextio = 0;
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
!     for (queue_Scan(&call->iovq, rp, nxp, rx_packet)) {
! 	queue_Remove(rp);
! 	rxi_FreePacket(rp);
      }
  
      if (call->mode == RX_MODE_SENDING) {
--- 564,571 ----
      nextio = 0;
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
!     if (queue_IsNotEmpty(&call->iovq)) {
!         rxi_FreePackets(0, &call->iovq);
      }
  
      if (call->mode == RX_MODE_SENDING) {
***************
*** 657,673 ****
  {
      struct rx_connection *conn = call->conn;
      register struct rx_packet *cp = call->currentPacket;
-     register struct rx_packet *tp;	/* Temporary packet pointer */
-     register struct rx_packet *nxp;	/* Next packet pointer, for queue_Scan */
      register unsigned int t;
      int requestCount = nbytes;
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
!     if (!queue_IsEmpty(&call->iovq)) {
! 	for (queue_Scan(&call->iovq, tp, nxp, rx_packet)) {
! 	    queue_Remove(tp);
! 	    rxi_FreePacket(tp);
! 	}
      }
  
      if (call->mode != RX_MODE_SENDING) {
--- 642,653 ----
  {
      struct rx_connection *conn = call->conn;
      register struct rx_packet *cp = call->currentPacket;
      register unsigned int t;
      int requestCount = nbytes;
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
!     if (queue_IsNotEmpty(&call->iovq)) {
! 	rxi_FreePackets(0, &call->iovq);
      }
  
      if (call->mode != RX_MODE_SENDING) {
***************
*** 833,845 ****
       * RX_CALL_IOVEC_WAIT is always cleared before returning from
       * ReadvProc/WritevProc.
       */
!     if (!queue_IsEmpty(&call->iovq)) {
! 	register struct rx_packet *rp;
! 	register struct rx_packet *nxp;
! 	for (queue_Scan(&call->iovq, rp, nxp, rx_packet)) {
! 	    queue_Remove(rp);
! 	    rxi_FreePacket(rp);
! 	}
      }
  
      /*
--- 813,820 ----
       * RX_CALL_IOVEC_WAIT is always cleared before returning from
       * ReadvProc/WritevProc.
       */
!     if (queue_IsNotEmpty(&call->iovq)) {
! 	rxi_FreePackets(0, &call->iovq);
      }
  
      /*
***************
*** 885,897 ****
       * RX_CALL_IOVEC_WAIT is always cleared before returning from
       * ReadvProc/WritevProc.
       */
!     if (!queue_IsEmpty(&call->iovq)) {
! 	register struct rx_packet *rp;
! 	register struct rx_packet *nxp;
! 	for (queue_Scan(&call->iovq, rp, nxp, rx_packet)) {
! 	    queue_Remove(rp);
! 	    rxi_FreePacket(rp);
! 	}
      }
  
      /*
--- 860,867 ----
       * RX_CALL_IOVEC_WAIT is always cleared before returning from
       * ReadvProc/WritevProc.
       */
!     if (queue_IsNotEmpty(&call->iovq)) {
! 	rxi_FreePackets(0, &call->iovq);
      }
  
      /*
***************
*** 938,945 ****
  {
      struct rx_connection *conn = call->conn;
      struct rx_packet *cp = call->currentPacket;
-     struct rx_packet *tp;	/* temporary packet pointer */
-     struct rx_packet *nxp;	/* Next packet pointer, for queue_Scan */
      int requestCount;
      int nextio;
      /* Temporary values, real work is done in rxi_WritevProc */
--- 908,913 ----
***************
*** 952,960 ****
      nextio = 0;
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
!     for (queue_Scan(&call->iovq, tp, nxp, rx_packet)) {
! 	queue_Remove(tp);
! 	rxi_FreePacket(tp);
      }
  
      if (call->mode != RX_MODE_SENDING) {
--- 920,927 ----
      nextio = 0;
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
!     if (queue_IsNotEmpty(&call->iovq)) {
!         rxi_FreePackets(0, &call->iovq);
      }
  
      if (call->mode != RX_MODE_SENDING) {
***************
*** 1066,1073 ****
  rxi_WritevProc(struct rx_call *call, struct iovec *iov, int nio, int nbytes)
  {
      struct rx_packet *cp = call->currentPacket;
-     register struct rx_packet *tp;	/* Temporary packet pointer */
-     register struct rx_packet *nxp;	/* Next packet pointer, for queue_Scan */
      int nextio;
      int requestCount;
      struct rx_queue tmpq;
--- 1033,1038 ----
***************
*** 1092,1105 ****
  #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
  
      if (call->error) {
- 	for (queue_Scan(&call->iovq, tp, nxp, rx_packet)) {
- 	    queue_Remove(tp);
- 	    rxi_FreePacket(tp);
- 	}
  	if (cp) {
! 	    rxi_FreePacket(cp);
  	    cp = call->currentPacket = NULL;
  	}
  	return 0;
      }
  
--- 1057,1067 ----
  #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
  
      if (call->error) {
  	if (cp) {
! 	    queue_Prepend(&call->iovq, cp);
  	    cp = call->currentPacket = NULL;
  	}
+ 	rxi_FreePackets(0, &call->iovq);
  	return 0;
      }
  
***************
*** 1126,1135 ****
  		if (queue_IsEmpty(&call->iovq)) {
  		    call->error = RX_PROTOCOL_ERROR;
  		    cp = call->currentPacket = NULL;
! 		    for (queue_Scan(&tmpq, tp, nxp, rx_packet)) {
! 			queue_Remove(tp);
! 			rxi_FreePacket(tp);
! 		    }
  		    return 0;
  		}
  		cp = queue_First(&call->iovq, rx_packet);
--- 1088,1094 ----
  		if (queue_IsEmpty(&call->iovq)) {
  		    call->error = RX_PROTOCOL_ERROR;
  		    cp = call->currentPacket = NULL;
! 		    rxi_FreePackets(0, &tmpq);
  		    return 0;
  		}
  		cp = queue_First(&call->iovq, rx_packet);
***************
*** 1150,1163 ****
  	    if (iov[nextio].iov_base != call->curpos
  		|| iov[nextio].iov_len > (int)call->curlen) {
  		call->error = RX_PROTOCOL_ERROR;
- 		for (queue_Scan(&tmpq, tp, nxp, rx_packet)) {
- 		    queue_Remove(tp);
- 		    rxi_FreePacket(tp);
- 		}
  		if (cp) {
! 		    rxi_FreePacket(cp);
  		    call->currentPacket = NULL;
  		}
  		return 0;
  	    }
  	    nbytes -= iov[nextio].iov_len;
--- 1109,1119 ----
  	    if (iov[nextio].iov_base != call->curpos
  		|| iov[nextio].iov_len > (int)call->curlen) {
  		call->error = RX_PROTOCOL_ERROR;
  		if (cp) {
! 		    queue_Prepend(&tmpq, cp);
  		    call->currentPacket = NULL;
  		}
+ 		rxi_FreePackets(0, &tmpq);
  		return 0;
  	    }
  	    nbytes -= iov[nextio].iov_len;
***************
*** 1178,1187 ****
  
      /* Move the packets from the temporary queue onto the transmit queue.
       * We may end up with more than call->twind packets on the queue. */
!     for (queue_Scan(&tmpq, tp, nxp, rx_packet)) {
! 	queue_Remove(tp);
! 	queue_Append(&call->tq, tp);
!     }
  
      if (!(call->flags & (RX_CALL_FAST_RECOVER | RX_CALL_FAST_RECOVER_WAIT))) {
  	rxi_Start(0, call, 0, 0);
--- 1134,1140 ----
  
      /* Move the packets from the temporary queue onto the transmit queue.
       * We may end up with more than call->twind packets on the queue. */
!     queue_SpliceAppend(&call->tq, &tmpq);
  
      if (!(call->flags & (RX_CALL_FAST_RECOVER | RX_CALL_FAST_RECOVER_WAIT))) {
  	rxi_Start(0, call, 0, 0);
***************
*** 1231,1243 ****
  rxi_FlushWrite(register struct rx_call *call)
  {
      register struct rx_packet *cp = call->currentPacket;
-     register struct rx_packet *tp;	/* Temporary packet pointer */
-     register struct rx_packet *nxp;	/* Next packet pointer, for queue_Scan */
  
      /* Free any packets from the last call to ReadvProc/WritevProc */
!     for (queue_Scan(&call->iovq, tp, nxp, rx_packet)) {
! 	queue_Remove(tp);
! 	rxi_FreePacket(tp);
      }
  
      if (call->mode == RX_MODE_SENDING) {
--- 1184,1193 ----
  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)) {
! 	rxi_FreePackets(0, &call->iovq);
      }
  
      if (call->mode == RX_MODE_SENDING) {
Index: openafs/src/rx/rx_stream.c
diff -c openafs/src/rx/rx_stream.c:1.8 openafs/src/rx/rx_stream.c:removed
*** openafs/src/rx/rx_stream.c:1.8	Fri Aug  8 17:54:47 2003
--- openafs/src/rx/rx_stream.c	Wed Jun  1 01:00:00 2005
***************
*** 1,284 ****
- /*
-  * Copyright 2000, International Business Machines Corporation and others.
-  * All Rights Reserved.
-  * 
-  * This software has been released under the terms of the IBM Public
-  * License.  For details, see the LICENSE file in the top-level source
-  * directory or online at http://www.openafs.org/dl/license10.html
-  */
- 
- /* RX stream:  the stream I/O layer for RX */
- 
- This file is now obsolete.
- #include <afsconfig.h>
- #ifdef KERNEL
- #include "afs/param.h"
- #else
- #include <afs/param.h>
- #endif
-  
-     RCSID
-     ("$Header: /cvs/openafs/src/rx/Attic/rx_stream.c,v 1.8 2003/08/08 21:54:47 shadow Exp $");
- 
- #ifdef	KERNEL
- #include "h/types.h"
- #include "h/uio.h"
- #include "rx/rx_stream.h"
- #else /* KERNEL */
- #include "rx_stream.h"
- #endif /* KERNEL */
- 
- void
- rx_stream_InitRead(sd, call)
-      struct rx_stream *sd;
-      struct rx_call *call;
- {
-     queue_Init(&sd->sd.rd.rq);
-     queue_Init(&sd->sd.rd.freeTheseQ);
-     sd->sd.rd.nLeft = 0;
-     sd->sd.rd.call = call;
- }
- 
- /* Normally called from the macro, rx_stream_Read */
- int
- rx_stream_ReadProc(sd, buf, nbytes)
-      struct rx_stream *sd;
-      char *buf;
-      int nbytes;
- {
-     int totalBytes = nbytes;
- 
-     if (queue_IsNotEmpty(&sd->sd.rd.freeTheseQ))
- 	rx_FreePackets(&sd->sd.rd.freeTheseQ);
- 
-     while (nbytes) {
- 	struct rx_packet *tp;
- 	if (queue_IsEmpty(&sd->sd.rd.rq)) {
- 	    if (rx_ReadData(sd->sd.rd.call, &sd->sd.rd.rq))
- 		return totalBytes - nbytes;
- 	    tp = queue_First(&sd->sd.rd.rq, rx_packet);
- 	    sd->sd.rd.nextByte = rx_DataOf(tp);
- 	    sd->sd.rd.nLeft = rx_GetDataSize(tp);
- 	}
- 	if (nbytes < sd->sd.rd.nLeft) {
- 	    sd->sd.rd.nLeft -= nbytes;
- 	    memcpy(buf, sd->sd.rd.nextByte, nbytes);
- 	    sd->sd.rd.nextByte += nbytes;
- 	    return totalBytes;
- 	}
- 	memcpy(buf, sd->sd.rd.nextByte, sd->sd.rd.nLeft);
- 	buf += sd->sd.rd.nLeft;
- 	nbytes -= sd->sd.rd.nLeft;
- 	tp = queue_First(&sd->sd.rd.rq, rx_packet);
- 	queue_Remove(tp);
- 	rx_FreePacket(tp);
- 	if (queue_IsNotEmpty(&sd->sd.rd.rq)) {
- 	    tp = queue_First(&sd->sd.rd.rq, rx_packet);
- 	    sd->sd.rd.nextByte = rx_DataOf(tp);
- 	    sd->sd.rd.nLeft = rx_GetDataSize(tp);
- 	}
-     }
-     return totalBytes;
- }
- 
- int
- rx_stream_ReadIov(sd, iovlenp, iov, nbytes)
-      struct rx_stream *sd;
-      int *iovlenp;
-      struct iovec *iov;
-      int nbytes;
- {
-     int totalBytes = nbytes;
-     int iovIndex = 0;
-     int maxiovlen = *iovlenp;
- 
-     if (queue_IsNotEmpty(&sd->sd.rd.freeTheseQ))
- 	rx_FreePackets(&sd->sd.rd.freeTheseQ);
- 
-     while (nbytes && iovIndex < maxiovlen) {
- 	struct rx_packet *tp;
- 	if (queue_IsEmpty(&sd->sd.rd.rq)) {
- 	    if (rx_ReadData(sd->sd.rd.call, &sd->sd.rd.rq))
- 		break;
- 	    tp = queue_First(&sd->sd.rd.rq, rx_packet);
- 	    sd->sd.rd.nextByte = rx_DataOf(tp);
- 	    sd->sd.rd.nLeft = rx_GetDataSize(tp);
- 	}
- 	if (nbytes < sd->sd.rd.nLeft) {
- 	    sd->sd.rd.nLeft -= nbytes;
- 	    iov[iovIndex].iov_base = sd->sd.rd.nextByte;
- 	    iov[iovIndex++].iov_len = nbytes;
- 	    sd->sd.rd.nextByte += nbytes;
- 	    nbytes = 0;
- 	    break;
- 	}
- 	iov[iovIndex].iov_base = sd->sd.rd.nextByte;
- 	iov[iovIndex++].iov_len = sd->sd.rd.nLeft;
- 	nbytes -= sd->sd.rd.nLeft;
- 	tp = queue_First(&sd->sd.rd.rq, rx_packet);
- 	queue_MovePrepend(&sd->sd.rd.freeTheseQ, tp);
- 	if (queue_IsNotEmpty(&sd->sd.rd.rq)) {
- 	    tp = queue_First(&sd->sd.rd.rq, rx_packet);
- 	    sd->sd.rd.nextByte = rx_DataOf(tp);
- 	    sd->sd.rd.nLeft = rx_GetDataSize(tp);
- 	}
-     }
-     *iovlenp = iovIndex;
-     return totalBytes - nbytes;
- }
- 
- void
- rx_stream_FinishRead(sd)
-      struct rx_stream *sd;
- {
-     if (queue_IsNotEmpty(&sd->sd.rd.rq))
- 	rx_FreePackets(&sd->sd.rd.rq);
-     if (queue_IsNotEmpty(&sd->sd.rd.freeTheseQ))
- 	rx_FreePackets(&sd->sd.rd.freeTheseQ);
- }
- 
- void
- rx_stream_InitWrite(sd, call)
-      struct rx_stream *sd;
-      struct rx_call *call;
- {
-     sd->sd.wd.freePtr = 0;
-     sd->sd.wd.nFree = 0;
-     sd->sd.wd.call = call;
-     queue_Init(&sd->sd.wd.wq);
-     sd->sd.wd.packetSize = rx_MaxDataSize(rx_ConnectionOf(call));
- }
- 
- /* The real write procedure (rx_stream_Write is a macro) */
- int
- rx_stream_WriteProc(sd, buf, nbytes)
-      struct rx_stream *sd;
-      char *buf;
-      int nbytes;
- {
-     int totalBytes = nbytes;
-     while (nbytes) {
- 	if (queue_IsEmpty(&sd->sd.wd.wq)) {
- 	    if (rx_AllocPackets(sd->sd.wd.call, &sd->sd.wd.wq, 1, RX_WAIT))
- 		break;
- 	    sd->sd.wd.nFree = sd->sd.wd.packetSize;
- 	    sd->sd.wd.freePtr =
- 		rx_DataOf(queue_First(&sd->sd.wd.wq, rx_packet));
- 	}
- 	if (nbytes < sd->sd.wd.nFree) {
- 	    if (buf)
- 		memcpy(sd->sd.wd.freePtr, buf, nbytes), buf += nbytes;
- 	    sd->sd.wd.nFree -= nbytes;
- 	    sd->sd.wd.freePtr += nbytes;
- 	    nbytes = 0;
- 	    break;
- 	}
- 	if (buf)
- 	    memcpy(sd->sd.wd.freePtr, buf, sd->sd.wd.nFree), buf +=
- 		sd->sd.wd.nFree;
- 	nbytes -= sd->sd.wd.nFree;
- 	sd->sd.wd.nFree = 0;
- 	if (rx_stream_FlushWrite(sd))
- 	    break;
-     }
-     return totalBytes - nbytes;
- }
- 
- /* Returns nbytes allocated */
- int
- rx_stream_AllocIov(sd, iovlenp, iovp, nbytes)
-      struct rx_stream *sd;
-      int *iovlenp;
-      struct iovec *iovp;
-      int nbytes;
- {
-     struct rx_packet *p, *nxp;
-     int maxiovlen = *iovlenp;
-     int iovIndex;
-     int totalBytes;
-     int nFree;
-     int niovs;
- 
-     for (nFree = 0, queue_Scan(&sd->sd.wd.wq, p, nxp, rx_packet)) {
- 	nFree += sd->sd.wd.packetSize;
-     }
-     if (sd->sd.wd.nFree)
- 	nFree = nFree - sd->sd.wd.packetSize + sd->sd.wd.nFree;
- 
-     /* Allocate the number of bytes requested, or an even portion */
-     for (totalBytes = nbytes;; totalBytes >>= 1) {
- 	/* Compute number of additional buffers, beyond current partial buffer, required */
- 	int nPackets;
- 	nbytes = totalBytes - nFree;
- 	if (nbytes < 0) {
- 	    niovs = 1;
- 	    break;
- 	}
- 	niovs = nPackets =
- 	    (nbytes + sd->sd.wd.packetSize - 1) / sd->sd.wd.packetSize;
- 	if (nFree)
- 	    niovs++;
- 	if (niovs <= maxiovlen) {
- 	    if (rx_AllocPackets(sd->sd.wd.call, &sd->sd.wd.wq, nPackets, 1))
- 		break;
- 	    if (nFree == 0) {
- 		/* Since there weren't any packets allocated previously, setup new description for first packet */
- 		sd->sd.wd.nFree = sd->sd.wd.packetSize;
- 		sd->sd.wd.freePtr =
- 		    rx_DataOf(queue_First(&sd->sd.wd.wq, rx_packet));
- 	    }
- 	    break;
- 	}
-     }
- 
-     /* Create an iovec to describe the set of allocated buffers */
-     for (nFree = sd->sd.wd.nFree, nbytes = totalBytes, iovIndex =
- 	 0, queue_Scan(&sd->sd.wd.wq, p, nxp, rx_packet), iovIndex++, nFree =
- 	 sd->sd.wd.packetSize) {
- 	if (iovIndex >= niovs)
- 	    break;
- 	iovp[iovIndex].iov_base = rx_DataOf(p) + sd->sd.wd.packetSize - nFree;
- 	if (nbytes <= nFree) {
- 	    iovp[iovIndex].iov_len = nbytes;
- 	    nbytes = 0;
- 	    break;
- 	}
- 	nbytes -= nFree;
- 	iovp[iovIndex].iov_len = nFree;
-     }
-     *iovlenp = niovs;
-     return totalBytes - nbytes;
- }
- 
- /* Wrong, wrong, wrong */
- rx_stream_FlushWrite(sd)
-      struct rx_stream *sd;
- {
-     struct rx_queue q;
-     queue_Init(&q);
-     if (queue_IsNotEmpty(&sd->sd.wd.wq)
- 	&& sd->sd.wd.nFree < sd->sd.wd.packetSize) {
- 	struct rx_packet *tp = queue_First(&sd->sd.wd.wq, rx_packet);
- 	queue_MoveAppend(&q, tp);
- 	rx_SetDataSize(queue_First(&q, rx_packet),
- 		       sd->sd.wd.packetSize - sd->sd.wd.nFree);
- 	if (queue_IsNotEmpty(&sd->sd.wd.wq)) {
- 	    sd->sd.wd.nFree = sd->sd.wd.packetSize;
- 	    sd->sd.wd.freePtr =
- 		rx_DataOf(queue_First(&sd->sd.wd.wq, rx_packet));
- 	} else
- 	    sd->sd.wd.nFree = 0;
- 	return (rx_SendData(sd->sd.wd.call, &q));
-     }
-     return 0;
- }
- 
- void
- rx_stream_FinishWrite(sd)
-      struct rx_stream *sd;
- {
-     rx_stream_FlushWrite(sd);
-     if (queue_IsNotEmpty(&sd->sd.wd.wq))
- 	rx_FreePackets(&sd->sd.wd.wq);
-     sd->sd.wd.nFree = 0;
- }
--- 0 ----
Index: openafs/src/rx/rx_stream.h
diff -c openafs/src/rx/rx_stream.h:1.5 openafs/src/rx/rx_stream.h:removed
*** openafs/src/rx/rx_stream.h:1.5	Tue Jul 15 19:16:10 2003
--- openafs/src/rx/rx_stream.h	Wed Jun  1 01:00:00 2005
***************
*** 1,76 ****
- /*
-  * Copyright 2000, International Business Machines Corporation and others.
-  * All Rights Reserved.
-  * 
-  * This software has been released under the terms of the IBM Public
-  * License.  For details, see the LICENSE file in the top-level source
-  * directory or online at http://www.openafs.org/dl/license10.html
-  */
- 
- /* rx_stream.h:  the stream I/O layer for RX */
- 
- This file is now obsolete.
- #ifndef _RX_STREAM_
- #define _RX_STREAM_
- #ifdef	KERNEL
- #include "rx/rx.h"
- #else				/* KERNEL */
- #include <sys/types.h>
- #include <sys/uio.h>
- #include "rx.h"
- #endif				/* KERNEL */
- /* Write descriptor */
-     struct rx_stream_wd {
-     char *freePtr;		/* Pointer to bytes in first packet */
-     int nFree;			/* Number of bytes free in first packet */
-     struct rx_call *call;	/* The call this stream is attached to */
-     struct rx_queue wq;		/* Currently allocated packets for this stream */
-     int packetSize;		/* Data size used in each packet */
- };
- 
- /* Read descriptor */
- struct rx_stream_rd {
-     struct rx_packet *packet;	/* The current packet */
-     char *nextByte;		/* Pointer to bytes in current packet */
-     int nLeft;			/* Number of bytes free in current packet */
-     struct rx_call *call;	/* The call this stream is attached to */
-     struct rx_queue rq;		/* Currently allocated packets for this stream */
-     struct rx_queue freeTheseQ;	/* These packets should be freed on the next operation */
- };
- 
- /* Composite stream descriptor */
- struct rx_stream {
-     union {
- 	struct rx_stream_rd rd;
- 	struct rx_stream_wd wd;
-     } sd;
- };
- 
- /* Externals */
- void rx_stream_InitWrite();
- void rx_stream_InitRead();
- void rx_stream_FinishWrite();
- void rx_stream_FinishRead();
- int rx_stream_Read();
- int rx_stream_Write();
- int rx_stream_AllocIov();
- 
- /* Write nbytes of data to the write stream.  Returns the number of bytes written */
- /* If it returns 0, the call status should be checked with rx_Error. */
- #define	rx_stream_Write(iod, buf, nbytes)				\
-     (iod)->sd.wd.nFree > (nbytes) ?					\
- 	(buf) && memcpy((iod)->sd.wd.freePtr, (buf), (nbytes)),		\
- 	(iod)->sd.wd.nFree -= (nbytes),					\
- 	(iod)->sd.wd.freePtr += (nbytes), (nbytes)			\
-       : rx_stream_WriteProc((iod), (buf), (nbytes))
- 
- 
- /* Read nbytes of data from the read stream.  Returns the number of bytes read */
- /* If it returns less than requested, the call status should be checked with rx_Error */
- #define	rx_stream_Read(iod, buf, nbytes)					\
-     (iod)->sd.rd.nLeft > (nbytes) ?						\
-     memcpy((buf), (iod)->sd.rd.nextByte, (nbytes)),				\
-     (iod)->sd.rd.nLeft -= (nbytes), (iod)->sd.rd.nextByte += (nbytes), (nbytes)	\
-    : rx_stream_ReadProc((iod), (buf), (nbytes))
- 
- #endif /* _RX_STREAM_    End of rx_stream.h */
--- 0 ----
Index: openafs/src/rx/xdr_rx.c
diff -c openafs/src/rx/xdr_rx.c:1.10.2.2 openafs/src/rx/xdr_rx.c:1.10.2.3
*** openafs/src/rx/xdr_rx.c:1.10.2.2	Sun Apr  3 14:15:51 2005
--- openafs/src/rx/xdr_rx.c	Tue May 24 19:14:44 2005
***************
*** 19,25 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/xdr_rx.c,v 1.10.2.2 2005/04/03 18:15:51 shadow Exp $");
  
  #ifdef KERNEL
  #ifndef UKERNEL
--- 19,25 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/xdr_rx.c,v 1.10.2.3 2005/05/24 23:14:44 shadow Exp $");
  
  #ifdef KERNEL
  #ifndef UKERNEL
***************
*** 141,147 ****
  
  /*
   * Initialize an rx xdr handle, for a given rx call.  op must be XDR_ENCODE or XDR_DECODE.
!  * Call must have been returned by rx_MakeCall or rx_GetCall.  Stream should be a pointer to a local rx_stream structure.
   */
  void
  xdrrx_create(register XDR * xdrs, register struct rx_call *call,
--- 141,147 ----
  
  /*
   * Initialize an rx xdr handle, for a given rx call.  op must be XDR_ENCODE or XDR_DECODE.
!  * Call must have been returned by rx_MakeCall or rx_GetCall.
   */
  void
  xdrrx_create(register XDR * xdrs, register struct rx_call *call,
Index: openafs/src/rxkad/Makefile.in
diff -c openafs/src/rxkad/Makefile.in:1.19.2.2 openafs/src/rxkad/Makefile.in:1.19.2.3
*** openafs/src/rxkad/Makefile.in:1.19.2.2	Tue Dec  7 00:49:39 2004
--- openafs/src/rxkad/Makefile.in	Mon May 30 14:30:36 2005
***************
*** 23,28 ****
--- 23,29 ----
  
  fc_test_LIBS=\
  	${TOP_LIBDIR}/librxkad.a \
+ 	${TOP_LIBDIR}/libdes.a \
  	${TOP_LIBDIR}/librx.a \
  	${TOP_LIBDIR}/liblwp.a \
  	${TOP_LIBDIR}/libsys.a \
Index: openafs/src/rxkad/bg-fcrypt.c
diff -c openafs/src/rxkad/bg-fcrypt.c:1.5.2.1 openafs/src/rxkad/bg-fcrypt.c:1.5.2.2
*** openafs/src/rxkad/bg-fcrypt.c:1.5.2.1	Wed Aug 25 03:09:42 2004
--- openafs/src/rxkad/bg-fcrypt.c	Mon May 30 00:57:37 2005
***************
*** 38,44 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/bg-fcrypt.c,v 1.5.2.1 2004/08/25 07:09:42 shadow Exp $");
  
  #define DEBUG 0
  #ifdef KERNEL
--- 38,44 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/bg-fcrypt.c,v 1.5.2.2 2005/05/30 04:57:37 shadow Exp $");
  
  #define DEBUG 0
  #ifdef KERNEL
***************
*** 74,79 ****
--- 74,80 ----
  #include "rxkad.h"
  #include "fcrypt.h"
  #include "private_data.h"
+ #include <des/stats.h>
  
  #undef WORDS_BIGENDIAN
  #ifdef AFSBIG_ENDIAN
***************
*** 507,515 ****
  fc_ecb_encrypt(afs_uint32 * in, afs_uint32 * out, fc_KeySchedule sched,
  	       int encrypt)
  {
!     LOCK_RXKAD_STATS;
!     rxkad_stats.fc_encrypts[encrypt]++;
!     UNLOCK_RXKAD_STATS;
      if (encrypt)
  	fc_ecb_enc(in[0], in[1], out, sched);
      else
--- 508,514 ----
  fc_ecb_encrypt(afs_uint32 * in, afs_uint32 * out, fc_KeySchedule sched,
  	       int encrypt)
  {
!     INC_RXKAD_STATS(fc_encrypts[encrypt]);
      if (encrypt)
  	fc_ecb_enc(in[0], in[1], out, sched);
      else
***************
*** 669,677 ****
      ROT56R(hi, lo, 11);
      *sched++ = EFF_NTOHL(lo);
  #endif
!     LOCK_RXKAD_STATS;
!     rxkad_stats.fc_key_scheds++;
!     UNLOCK_RXKAD_STATS;
      return 0;
  }
  
--- 668,674 ----
      ROT56R(hi, lo, 11);
      *sched++ = EFF_NTOHL(lo);
  #endif
!     INC_RXKAD_STATS(fc_key_scheds);
      return 0;
  }
  
***************
*** 692,700 ****
  
      obj = rx_SecurityObjectOf(rx_connection_not_used);
      tp = (struct rxkad_cprivate *)obj->privateData;
!     LOCK_RXKAD_STATS;
!     rxkad_stats.bytesEncrypted[rxkad_TypeIndex(tp->type)] += len;
!     UNLOCK_RXKAD_STATS;
      {
  	/* What is this good for?
  	 * It turns out that the security header for auth_enc is of
--- 689,695 ----
  
      obj = rx_SecurityObjectOf(rx_connection_not_used);
      tp = (struct rxkad_cprivate *)obj->privateData;
!     ADD_RXKAD_STATS(bytesEncrypted[rxkad_TypeIndex(tp->type)],len);
      {
  	/* What is this good for?
  	 * It turns out that the security header for auth_enc is of
***************
*** 730,738 ****
  
      obj = rx_SecurityObjectOf(rx_connection_not_used);
      tp = (struct rxkad_cprivate *)obj->privateData;
!     LOCK_RXKAD_STATS;
!     rxkad_stats.bytesDecrypted[rxkad_TypeIndex(tp->type)] += len;
!     UNLOCK_RXKAD_STATS;
      memcpy(ivec, iv, sizeof(ivec));	/* Must use copy of iv */
      for (frag = &packet->wirevec[1]; len > 0; frag++) {
  	int iov_len = frag->iov_len;
--- 725,731 ----
  
      obj = rx_SecurityObjectOf(rx_connection_not_used);
      tp = (struct rxkad_cprivate *)obj->privateData;
!     ADD_RXKAD_STATS(bytesDecrypted[rxkad_TypeIndex(tp->type)],len);
      memcpy(ivec, iv, sizeof(ivec));	/* Must use copy of iv */
      for (frag = &packet->wirevec[1]; len > 0; frag++) {
  	int iov_len = frag->iov_len;
Index: openafs/src/rxkad/rxkad.p.h
diff -c openafs/src/rxkad/rxkad.p.h:1.11.2.5 openafs/src/rxkad/rxkad.p.h:1.11.2.6
*** openafs/src/rxkad/rxkad.p.h:1.11.2.5	Sun Apr  3 14:18:56 2005
--- openafs/src/rxkad/rxkad.p.h	Mon May 30 00:57:37 2005
***************
*** 90,141 ****
  #define rxkad_TypeIndex(type) \
      ((((type) == 1) || ((type) == 2)) ? (type) : 0)
  
- struct rxkad_stats {
-     afs_uint32 connections[3];	/* client side only */
-     afs_uint32 destroyObject;	/* client security objects */
-     afs_uint32 destroyClient;	/* client connections */
-     afs_uint32 destroyUnused;	/* unused server conn */
-     afs_uint32 destroyUnauth;	/* unauthenticated server conn */
-     afs_uint32 destroyConn[3];	/* server conn per level */
-     afs_uint32 expired;		/* server packets rejected */
-     afs_uint32 challengesSent;	/* server challenges sent */
-     afs_uint32 challenges[3];	/* challenges seen by client */
-     afs_uint32 responses[3];	/* responses seen by server */
-     afs_uint32 preparePackets[6];
-     afs_uint32 checkPackets[6];
-     afs_uint32 bytesEncrypted[2];	/* index just by type */
-     afs_uint32 bytesDecrypted[2];
-     afs_uint32 fc_encrypts[2];	/* DECRYPT==0, ENCRYPT==1 */
-     afs_uint32 fc_key_scheds;	/* key schedule creations */
-     afs_uint32 des_encrypts[2];	/* DECRYPT==0, ENCRYPT==1 */
-     afs_uint32 des_key_scheds;	/* key schedule creations */
-     afs_uint32 des_randoms;	/* random blocks generated */
-     long spares[10];
- };
- 
- #if defined(AFS_NT40_ENV) && defined(AFS_PTHREAD_ENV)
- #ifndef RXKAD_STATS_DECLSPEC
- #define RXKAD_STATS_DECLSPEC __declspec(dllimport) extern
- #endif
- #else
- #define RXKAD_STATS_DECLSPEC extern
- #endif
- RXKAD_STATS_DECLSPEC struct rxkad_stats rxkad_stats;
- #ifdef AFS_PTHREAD_ENV
- #include <pthread.h>
- #include <assert.h>
- extern pthread_mutex_t rxkad_stats_mutex;
- #define LOCK_RXKAD_STATS assert(pthread_mutex_lock(&rxkad_stats_mutex)==0)
- #define UNLOCK_RXKAD_STATS assert(pthread_mutex_unlock(&rxkad_stats_mutex)==0)
- #else
- #define LOCK_RXKAD_STATS
- #define UNLOCK_RXKAD_STATS
- #endif
- 
- 
- /* gak! using up spares already! */
- #define rxkad_stats_clientObjects (rxkad_stats.spares[0])
- #define rxkad_stats_serverObjects (rxkad_stats.spares[1])
  
  extern int rxkad_EpochWasSet;	/* TRUE => we called rx_SetEpoch */
  
--- 90,95 ----
Index: openafs/src/rxkad/rxkad_client.c
diff -c openafs/src/rxkad/rxkad_client.c:1.18.2.1 openafs/src/rxkad/rxkad_client.c:1.18.2.2
*** openafs/src/rxkad/rxkad_client.c:1.18.2.1	Wed Aug 25 03:09:42 2004
--- openafs/src/rxkad/rxkad_client.c	Mon May 30 00:57:37 2005
***************
*** 19,25 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/rxkad_client.c,v 1.18.2.1 2004/08/25 07:09:42 shadow Exp $");
  
  #ifdef KERNEL
  #include "afs/stds.h"
--- 19,25 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/rxkad_client.c,v 1.18.2.2 2005/05/30 04:57:37 shadow Exp $");
  
  #ifdef KERNEL
  #include "afs/stds.h"
***************
*** 63,68 ****
--- 63,69 ----
  #endif /* AFS_PTHREAD_ENV */
  #endif /* KERNEL */
  
+ #include <des/stats.h>
  #include "private_data.h"
  #define XPRT_RXKAD_CLIENT
  
***************
*** 207,215 ****
      }
      memcpy(tcp->ticket, ticket, ticketLen);
  
!     LOCK_RXKAD_STATS;
!     rxkad_stats_clientObjects++;
!     UNLOCK_RXKAD_STATS;
      return tsc;
  }
  
--- 208,214 ----
      }
      memcpy(tcp->ticket, ticket, ticketLen);
  
!     INC_RXKAD_STATS(clientObjects);
      return tsc;
  }
  
***************
*** 255,263 ****
  
      if (level > tcp->level)
  	return RXKADLEVELFAIL;
!     LOCK_RXKAD_STATS;
!     rxkad_stats.challenges[rxkad_LevelIndex(tcp->level)]++;
!     UNLOCK_RXKAD_STATS;
      if (v2) {
  	int i;
  	afs_uint32 xor[2];
--- 254,260 ----
  
      if (level > tcp->level)
  	return RXKADLEVELFAIL;
!     INC_RXKAD_STATS(challenges[rxkad_LevelIndex(tcp->level)]);
      if (v2) {
  	int i;
  	afs_uint32 xor[2];
Index: openafs/src/rxkad/rxkad_common.c
diff -c openafs/src/rxkad/rxkad_common.c:1.20.2.3 openafs/src/rxkad/rxkad_common.c:1.20.2.6
*** openafs/src/rxkad/rxkad_common.c:1.20.2.3	Fri Mar 11 02:03:35 2005
--- openafs/src/rxkad/rxkad_common.c	Mon May 30 14:30:36 2005
***************
*** 23,29 ****
  #define INCLUDE_RXKAD_PRIVATE_DECLS
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/rxkad_common.c,v 1.20.2.3 2005/03/11 07:03:35 shadow Exp $");
  
  #ifdef KERNEL
  #ifndef UKERNEL
--- 23,29 ----
  #define INCLUDE_RXKAD_PRIVATE_DECLS
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/rxkad_common.c,v 1.20.2.6 2005/05/30 18:30:36 shadow Exp $");
  
  #ifdef KERNEL
  #ifndef UKERNEL
***************
*** 32,38 ****
  #ifdef	AFS_AIX_ENV
  #include "h/systm.h"
  #endif
! #ifdef AFS_DARWIN60_ENV
  #include "h/kernel.h"
  #endif
  #include "h/types.h"
--- 32,38 ----
  #ifdef	AFS_AIX_ENV
  #include "h/systm.h"
  #endif
! #if defined(AFS_DARWIN60_ENV) || defined(AFS_OBSD_ENV)
  #include "h/kernel.h"
  #endif
  #include "h/types.h"
***************
*** 71,76 ****
--- 71,77 ----
  
  #endif /* KERNEL */
  
+ #include <des/stats.h>
  #include "private_data.h"
  #define XPRT_RXKAD_COMMON
  
***************
*** 83,89 ****
  #endif
  /* variable initialization for the benefit of darwin compiler; if it causes
     problems elsewhere, conditionalize for darwin or fc_test compile breaks */
! struct rxkad_stats rxkad_stats = { { 0 } };
  
  /* static prototypes */
  static afs_int32 ComputeSum(struct rx_packet *apacket,
--- 84,196 ----
  #endif
  /* variable initialization for the benefit of darwin compiler; if it causes
     problems elsewhere, conditionalize for darwin or fc_test compile breaks */
! #ifdef AFS_PTHREAD_ENV
! struct rxkad_global_stats rxkad_global_stats = { 0 };
! pthread_mutex_t rxkad_global_stats_lock;
! pthread_key_t rxkad_stats_key;
! #else /* AFS_PTHREAD_ENV */
! /* Move delaration of this to des/key_sched.c */
! /* struct rxkad_stats rxkad_stats = { { 0 } }; */
! #endif /* AFS_PTHREAD_ENV */
! 
! #ifdef AFS_PTHREAD_ENV
! /* rxkad_stats related stuff */
! 
! /*
!  * Macro to insert an element at the tail of a doubly linked list
!  */
! #define DLL_INSERT_TAIL(ptr,head,tail,next,prev) \
!     do {					 \
! 	(ptr)->next = NULL;			 \
!         (ptr)->prev = (tail);			 \
! 	(tail) = (ptr);				 \
! 	if ((ptr)->prev) 			 \
! 	    (ptr)->prev->next = (ptr);		 \
! 	else					 \
! 	    (head) = (ptr);			 \
! 	assert((head) && ((head)->prev == NULL)); \
!     } while(0)
! 
! void rxkad_global_stats_init() {
!     assert(pthread_mutex_init(&rxkad_global_stats_lock, (const pthread_mutexattr_t *)0) == 0);
!     assert(pthread_key_create(&rxkad_stats_key, NULL) == 0);
!     memset(&rxkad_global_stats, 0, sizeof(rxkad_global_stats));
! }
! 
! rxkad_stats_t * 
! rxkad_thr_stats_init() {
!     rxkad_stats_t * rxkad_stats;
!     rxkad_stats = (rxkad_stats_t *)malloc(sizeof(rxkad_stats_t));
!     assert(rxkad_stats != NULL && pthread_setspecific(rxkad_stats_key,rxkad_stats) == 0);
!     memset(rxkad_stats,0,sizeof(rxkad_stats_t));
!     RXKAD_GLOBAL_STATS_LOCK;
!     DLL_INSERT_TAIL(rxkad_stats, rxkad_global_stats.first, rxkad_global_stats.last, next, prev);
!     RXKAD_GLOBAL_STATS_UNLOCK;
!     return rxkad_stats;
! }
! 
! int rxkad_stats_agg(rxkad_stats_t * rxkad_stats) {
!     rxkad_stats_t * thr_stats;
!     assert(rxkad_stats != NULL);
!     memset(rxkad_stats, 0, sizeof(rxkad_stats_t));
!     RXKAD_GLOBAL_STATS_LOCK;
!     for (thr_stats = rxkad_global_stats.first; thr_stats != NULL; thr_stats = thr_stats->next) {
!         rxkad_stats->connections[0] += thr_stats->connections[0];
! 	rxkad_stats->connections[1] += thr_stats->connections[1];
! 	rxkad_stats->connections[2] += thr_stats->connections[2];
! 	rxkad_stats->destroyObject += thr_stats->destroyObject;
! 	rxkad_stats->destroyClient += thr_stats->destroyClient;
! 	rxkad_stats->destroyUnused += thr_stats->destroyUnused;
! 	rxkad_stats->destroyUnauth += thr_stats->destroyUnauth;
! 	rxkad_stats->destroyConn[0] += thr_stats->destroyConn[0];
! 	rxkad_stats->destroyConn[1] += thr_stats->destroyConn[1];
! 	rxkad_stats->destroyConn[2] += thr_stats->destroyConn[2];
! 	rxkad_stats->expired += thr_stats->expired;
! 	rxkad_stats->challengesSent += thr_stats->challengesSent;
! 	rxkad_stats->challenges[0] += thr_stats->challenges[0];
! 	rxkad_stats->challenges[1] += thr_stats->challenges[1];
! 	rxkad_stats->challenges[2] += thr_stats->challenges[2];
! 	rxkad_stats->responses[0] += thr_stats->responses[0];
! 	rxkad_stats->responses[1] += thr_stats->responses[1];
! 	rxkad_stats->responses[2] += thr_stats->responses[2];
! 	rxkad_stats->preparePackets[0] += thr_stats->preparePackets[0];
! 	rxkad_stats->preparePackets[1] += thr_stats->preparePackets[1];
! 	rxkad_stats->preparePackets[2] += thr_stats->preparePackets[2];
! 	rxkad_stats->preparePackets[3] += thr_stats->preparePackets[3];
! 	rxkad_stats->preparePackets[4] += thr_stats->preparePackets[4];
! 	rxkad_stats->preparePackets[5] += thr_stats->preparePackets[5];
! 	rxkad_stats->checkPackets[0] += thr_stats->checkPackets[0];
! 	rxkad_stats->checkPackets[1] += thr_stats->checkPackets[1];
! 	rxkad_stats->checkPackets[2] += thr_stats->checkPackets[2];
! 	rxkad_stats->checkPackets[3] += thr_stats->checkPackets[3];
! 	rxkad_stats->checkPackets[4] += thr_stats->checkPackets[4];
! 	rxkad_stats->checkPackets[5] += thr_stats->checkPackets[5];
! 	rxkad_stats->bytesEncrypted[0] += thr_stats->bytesEncrypted[0];
! 	rxkad_stats->bytesEncrypted[1] += thr_stats->bytesEncrypted[1];
! 	rxkad_stats->bytesDecrypted[0] += thr_stats->bytesDecrypted[0];
! 	rxkad_stats->bytesDecrypted[1] += thr_stats->bytesDecrypted[1];
! 	rxkad_stats->fc_encrypts[0] += thr_stats->fc_encrypts[0];
! 	rxkad_stats->fc_encrypts[1] += thr_stats->fc_encrypts[1];
! 	rxkad_stats->fc_key_scheds += thr_stats->fc_key_scheds;
! 	rxkad_stats->des_encrypts[0] += thr_stats->des_encrypts[0];
! 	rxkad_stats->des_encrypts[1] += thr_stats->des_encrypts[1];
! 	rxkad_stats->des_key_scheds += thr_stats->des_key_scheds;
! 	rxkad_stats->des_randoms += thr_stats->des_randoms;
! 	rxkad_stats->spares[0] += thr_stats->spares[0];
! 	rxkad_stats->spares[1] += thr_stats->spares[1];
! 	rxkad_stats->spares[2] += thr_stats->spares[2];
! 	rxkad_stats->spares[3] += thr_stats->spares[3];
! 	rxkad_stats->spares[4] += thr_stats->spares[4];
! 	rxkad_stats->spares[5] += thr_stats->spares[5];
! 	rxkad_stats->spares[6] += thr_stats->spares[6];
! 	rxkad_stats->spares[7] += thr_stats->spares[7];
! 	rxkad_stats->spares[8] += thr_stats->spares[8];
! 	rxkad_stats->spares[9] += thr_stats->spares[9];
!     }
!     RXKAD_GLOBAL_STATS_UNLOCK;
!     return 0;
! }
! #endif /* AFS_PTHREAD_ENV */
  
  /* static prototypes */
  static afs_int32 ComputeSum(struct rx_packet *apacket,
***************
*** 207,215 ****
      } else {
  	return RXKADINCONSISTENCY;
      }				/* unknown type */
!     LOCK_RXKAD_STATS;
!     rxkad_stats.destroyObject++;
!     UNLOCK_RXKAD_STATS;
      return 0;
  }
  
--- 314,320 ----
      } else {
  	return RXKADINCONSISTENCY;
      }				/* unknown type */
!     INC_RXKAD_STATS(destroyObject);
      return 0;
  }
  
***************
*** 251,259 ****
  	rxkad_SetLevel(aconn, tcp->level);	/* set header and trailer sizes */
  	rxkad_AllocCID(aobj, aconn);	/* CHANGES cid AND epoch!!!! */
  	rxkad_DeriveXORInfo(aconn, tcp->keysched, tcp->ivec, tccp->preSeq);
! 	LOCK_RXKAD_STATS;
! 	rxkad_stats.connections[rxkad_LevelIndex(tcp->level)]++;
! 	UNLOCK_RXKAD_STATS;
      }
  
      aobj->refCount++;		/* attached connection */
--- 356,362 ----
  	rxkad_SetLevel(aconn, tcp->level);	/* set header and trailer sizes */
  	rxkad_AllocCID(aobj, aconn);	/* CHANGES cid AND epoch!!!! */
  	rxkad_DeriveXORInfo(aconn, tcp->keysched, tcp->ivec, tccp->preSeq);
! 	INC_RXKAD_STATS(connections[rxkad_LevelIndex(tcp->level)]);
      }
  
      aobj->refCount++;		/* attached connection */
***************
*** 272,291 ****
  	sconn = (struct rxkad_sconn *)aconn->securityData;
  	if (sconn) {
  	    aconn->securityData = 0;
- 	    LOCK_RXKAD_STATS;
  	    if (sconn->authenticated)
! 		rxkad_stats.destroyConn[rxkad_LevelIndex(sconn->level)]++;
  	    else
! 		rxkad_stats.destroyUnauth++;
! 	    UNLOCK_RXKAD_STATS;
  	    rock = sconn->rock;
  	    if (rock)
  		rxi_Free(rock, sizeof(struct rxkad_serverinfo));
  	    rxi_Free(sconn, sizeof(struct rxkad_sconn));
  	} else {
! 	    LOCK_RXKAD_STATS;
! 	    rxkad_stats.destroyUnused++;
! 	    UNLOCK_RXKAD_STATS;
  	}
      } else {			/* client */
  	struct rxkad_cconn *cconn;
--- 375,390 ----
  	sconn = (struct rxkad_sconn *)aconn->securityData;
  	if (sconn) {
  	    aconn->securityData = 0;
  	    if (sconn->authenticated)
! 		INC_RXKAD_STATS(destroyConn[rxkad_LevelIndex(sconn->level)]);
  	    else
! 		INC_RXKAD_STATS(destroyUnauth);
  	    rock = sconn->rock;
  	    if (rock)
  		rxi_Free(rock, sizeof(struct rxkad_serverinfo));
  	    rxi_Free(sconn, sizeof(struct rxkad_sconn));
  	} else {
! 	    INC_RXKAD_STATS(destroyUnused);
  	}
      } else {			/* client */
  	struct rxkad_cconn *cconn;
***************
*** 298,306 ****
  	    aconn->securityData = 0;
  	    rxi_Free(cconn, sizeof(struct rxkad_cconn));
  	}
! 	LOCK_RXKAD_STATS;
! 	rxkad_stats.destroyClient++;
! 	UNLOCK_RXKAD_STATS;
      }
      aobj->refCount--;		/* decrement connection counter */
      if (aobj->refCount <= 0) {
--- 397,403 ----
  	    aconn->securityData = 0;
  	    rxi_Free(cconn, sizeof(struct rxkad_cconn));
  	}
! 	INC_RXKAD_STATS(destroyClient);
      }
      aobj->refCount--;		/* decrement connection counter */
      if (aobj->refCount <= 0) {
***************
*** 341,357 ****
  	if (sconn && sconn->authenticated
  	    && (osi_Time() < sconn->expirationTime)) {
  	    level = sconn->level;
! 	    LOCK_RXKAD_STATS;
! 	    rxkad_stats.checkPackets[rxkad_StatIndex(rxkad_server, level)]++;
! 	    UNLOCK_RXKAD_STATS;
  	    sconn->stats.packetsReceived++;
  	    sconn->stats.bytesReceived += len;
  	    schedule = (fc_KeySchedule *) sconn->keysched;
  	    ivec = (fc_InitializationVector *) sconn->ivec;
  	} else {
! 	    LOCK_RXKAD_STATS;
! 	    rxkad_stats.expired++;
! 	    UNLOCK_RXKAD_STATS;
  	    return RXKADEXPIRED;
  	}
  	preSeq = sconn->preSeq;
--- 438,450 ----
  	if (sconn && sconn->authenticated
  	    && (osi_Time() < sconn->expirationTime)) {
  	    level = sconn->level;
! 	    INC_RXKAD_STATS(checkPackets[rxkad_StatIndex(rxkad_server, level)]);
  	    sconn->stats.packetsReceived++;
  	    sconn->stats.bytesReceived += len;
  	    schedule = (fc_KeySchedule *) sconn->keysched;
  	    ivec = (fc_InitializationVector *) sconn->ivec;
  	} else {
! 	    INC_RXKAD_STATS(expired);
  	    return RXKADEXPIRED;
  	}
  	preSeq = sconn->preSeq;
***************
*** 366,374 ****
  	if (!(tcp->type & rxkad_client))
  	    return RXKADINCONSISTENCY;
  	level = tcp->level;
! 	LOCK_RXKAD_STATS;
! 	rxkad_stats.checkPackets[rxkad_StatIndex(rxkad_client, level)]++;
! 	UNLOCK_RXKAD_STATS;
  	cconn->stats.packetsReceived++;
  	cconn->stats.bytesReceived += len;
  	preSeq = cconn->preSeq;
--- 459,465 ----
  	if (!(tcp->type & rxkad_client))
  	    return RXKADINCONSISTENCY;
  	level = tcp->level;
! 	INC_RXKAD_STATS(checkPackets[rxkad_StatIndex(rxkad_client, level)]);
  	cconn->stats.packetsReceived++;
  	cconn->stats.bytesReceived += len;
  	preSeq = cconn->preSeq;
***************
*** 434,451 ****
  	if (sconn && sconn->authenticated
  	    && (osi_Time() < sconn->expirationTime)) {
  	    level = sconn->level;
! 	    LOCK_RXKAD_STATS;
! 	    rxkad_stats.
! 		preparePackets[rxkad_StatIndex(rxkad_server, level)]++;
! 	    UNLOCK_RXKAD_STATS;
  	    sconn->stats.packetsSent++;
  	    sconn->stats.bytesSent += len;
  	    schedule = (fc_KeySchedule *) sconn->keysched;
  	    ivec = (fc_InitializationVector *) sconn->ivec;
  	} else {
! 	    LOCK_RXKAD_STATS;
! 	    rxkad_stats.expired++;	/* this is a pretty unlikely path... */
! 	    UNLOCK_RXKAD_STATS;
  	    return RXKADEXPIRED;
  	}
  	preSeq = sconn->preSeq;
--- 525,537 ----
  	if (sconn && sconn->authenticated
  	    && (osi_Time() < sconn->expirationTime)) {
  	    level = sconn->level;
! 	    INC_RXKAD_STATS(preparePackets[rxkad_StatIndex(rxkad_server, level)]);
  	    sconn->stats.packetsSent++;
  	    sconn->stats.bytesSent += len;
  	    schedule = (fc_KeySchedule *) sconn->keysched;
  	    ivec = (fc_InitializationVector *) sconn->ivec;
  	} else {
! 	    INC_RXKAD_STATS(expired);	/* this is a pretty unlikely path... */
  	    return RXKADEXPIRED;
  	}
  	preSeq = sconn->preSeq;
***************
*** 457,465 ****
  	if (!(tcp->type & rxkad_client))
  	    return RXKADINCONSISTENCY;
  	level = tcp->level;
! 	LOCK_RXKAD_STATS;
! 	rxkad_stats.preparePackets[rxkad_StatIndex(rxkad_client, level)]++;
! 	UNLOCK_RXKAD_STATS;
  	cconn->stats.packetsSent++;
  	cconn->stats.bytesSent += len;
  	preSeq = cconn->preSeq;
--- 543,549 ----
  	if (!(tcp->type & rxkad_client))
  	    return RXKADINCONSISTENCY;
  	level = tcp->level;
! 	INC_RXKAD_STATS(preparePackets[rxkad_StatIndex(rxkad_client, level)]);
  	cconn->stats.packetsSent++;
  	cconn->stats.bytesSent += len;
  	preSeq = cconn->preSeq;
Index: openafs/src/rxkad/rxkad_server.c
diff -c openafs/src/rxkad/rxkad_server.c:1.14.2.1 openafs/src/rxkad/rxkad_server.c:1.14.2.2
*** openafs/src/rxkad/rxkad_server.c:1.14.2.1	Wed Aug 25 03:09:42 2004
--- openafs/src/rxkad/rxkad_server.c	Mon May 30 00:57:38 2005
***************
*** 15,21 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/rxkad_server.c,v 1.14.2.1 2004/08/25 07:09:42 shadow Exp $");
  
  #include <afs/stds.h>
  #include <sys/types.h>
--- 15,21 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/rxkad_server.c,v 1.14.2.2 2005/05/30 04:57:38 shadow Exp $");
  
  #include <afs/stds.h>
  #include <sys/types.h>
***************
*** 36,41 ****
--- 36,42 ----
  #include <rx/xdr.h>
  #include <des.h>
  #include <afs/afsutil.h>
+ #include <des/stats.h>
  #include "private_data.h"
  #define XPRT_RXKAD_SERVER
  
***************
*** 160,168 ****
      tsp->user_ok = user_ok;	/* to inform server of client id. */
      init_random_int32();
  
!     LOCK_RXKAD_STATS;
!     rxkad_stats_serverObjects++;
!     UNLOCK_RXKAD_STATS;
      return tsc;
  }
  
--- 161,167 ----
      tsp->user_ok = user_ok;	/* to inform server of client id. */
      init_random_int32();
  
!     INC_RXKAD_STATS(serverObjects);
      return tsc;
  }
  
***************
*** 238,246 ****
      rx_packetwrite(apacket, 0, challengeSize, challenge);
      rx_SetDataSize(apacket, challengeSize);
      sconn->tried = 1;
!     LOCK_RXKAD_STATS;
!     rxkad_stats.challengesSent++;
!     UNLOCK_RXKAD_STATS;
      return 0;
  }
  
--- 237,243 ----
      rx_packetwrite(apacket, 0, challengeSize, challenge);
      rx_SetDataSize(apacket, challengeSize);
      sconn->tried = 1;
!     INC_RXKAD_STATS(challengesSent);
      return 0;
  }
  
***************
*** 405,413 ****
  	return RXKADLEVELFAIL;
      sconn->level = level;
      rxkad_SetLevel(aconn, sconn->level);
!     LOCK_RXKAD_STATS;
!     rxkad_stats.responses[rxkad_LevelIndex(sconn->level)]++;
!     UNLOCK_RXKAD_STATS;
      /* now compute endpoint-specific info used for computing 16 bit checksum */
      rxkad_DeriveXORInfo(aconn, sconn->keysched, sconn->ivec, sconn->preSeq);
  
--- 402,408 ----
  	return RXKADLEVELFAIL;
      sconn->level = level;
      rxkad_SetLevel(aconn, sconn->level);
!     INC_RXKAD_STATS(responses[rxkad_LevelIndex(sconn->level)]);
      /* now compute endpoint-specific info used for computing 16 bit checksum */
      rxkad_DeriveXORInfo(aconn, sconn->keysched, sconn->ivec, sconn->preSeq);
  
Index: openafs/src/rxkad/domestic/crypt_conn.c
diff -c openafs/src/rxkad/domestic/crypt_conn.c:1.11.2.1 openafs/src/rxkad/domestic/crypt_conn.c:1.11.2.2
*** openafs/src/rxkad/domestic/crypt_conn.c:1.11.2.1	Wed Aug 25 03:17:01 2004
--- openafs/src/rxkad/domestic/crypt_conn.c	Mon May 30 00:57:38 2005
***************
*** 19,25 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/domestic/crypt_conn.c,v 1.11.2.1 2004/08/25 07:17:01 shadow Exp $");
  
  #ifdef KERNEL
  #include "afs/stds.h"
--- 19,25 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/domestic/crypt_conn.c,v 1.11.2.2 2005/05/30 04:57:38 shadow Exp $");
  
  #ifdef KERNEL
  #include "afs/stds.h"
***************
*** 42,47 ****
--- 42,48 ----
  #endif
  #endif /* KERNEL */
  
+ #include <des/stats.h>
  #include "private_data.h"
  #define XPRT_RXKAD_CRYPT
  
***************
*** 61,69 ****
  
      obj = rx_SecurityObjectOf(conn);
      tp = (struct rxkad_cprivate *)obj->privateData;
!     LOCK_RXKAD_STATS;
!     rxkad_stats.bytesDecrypted[rxkad_TypeIndex(tp->type)] += len;
!     UNLOCK_RXKAD_STATS;
      memcpy((void *)xor, (void *)ivec, sizeof(xor));
      for (i = 0; len; i++) {
  	data = rx_data(packet, i, tlen);
--- 62,68 ----
  
      obj = rx_SecurityObjectOf(conn);
      tp = (struct rxkad_cprivate *)obj->privateData;
!     ADD_RXKAD_STATS(bytesDecrypted[rxkad_TypeIndex(tp->type)],len);
      memcpy((void *)xor, (void *)ivec, sizeof(xor));
      for (i = 0; len; i++) {
  	data = rx_data(packet, i, tlen);
***************
*** 97,105 ****
  
      obj = rx_SecurityObjectOf(conn);
      tp = (struct rxkad_cprivate *)obj->privateData;
!     LOCK_RXKAD_STATS;
!     rxkad_stats.bytesEncrypted[rxkad_TypeIndex(tp->type)] += len;
!     UNLOCK_RXKAD_STATS;
      /*
       * afs_int32 cksum;
       * cksum = htonl(0);                
--- 96,102 ----
  
      obj = rx_SecurityObjectOf(conn);
      tp = (struct rxkad_cprivate *)obj->privateData;
!     ADD_RXKAD_STATS(bytesEncrypted[rxkad_TypeIndex(tp->type)],len);
      /*
       * afs_int32 cksum;
       * cksum = htonl(0);                
Index: openafs/src/rxkad/domestic/fcrypt.c
diff -c openafs/src/rxkad/domestic/fcrypt.c:1.11.2.2 openafs/src/rxkad/domestic/fcrypt.c:1.11.2.3
*** openafs/src/rxkad/domestic/fcrypt.c:1.11.2.2	Mon Oct 18 13:44:01 2004
--- openafs/src/rxkad/domestic/fcrypt.c	Mon May 30 00:57:38 2005
***************
*** 20,26 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/domestic/fcrypt.c,v 1.11.2.2 2004/10/18 17:44:01 shadow Exp $");
  
  #define DEBUG 0
  #ifdef KERNEL
--- 20,26 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/domestic/fcrypt.c,v 1.11.2.3 2005/05/30 04:57:38 shadow Exp $");
  
  #define DEBUG 0
  #ifdef KERNEL
***************
*** 55,61 ****
  #include "sboxes.h"
  #include "fcrypt.h"
  #include "rxkad.h"
! 
  
  #ifdef TCRYPT
  int ROUNDS = 16;
--- 55,61 ----
  #include "sboxes.h"
  #include "fcrypt.h"
  #include "rxkad.h"
! #include <des/stats.h>
  
  #ifdef TCRYPT
  int ROUNDS = 16;
***************
*** 102,110 ****
  	kword[1] = (kword[1] >> 11) | (temp << (56 - 32 - 11));
  	schedule[i] = kword[0];
      }
!     LOCK_RXKAD_STATS;
!     rxkad_stats.fc_key_scheds++;
!     UNLOCK_RXKAD_STATS;
      return 0;
  }
  
--- 102,108 ----
  	kword[1] = (kword[1] >> 11) | (temp << (56 - 32 - 11));
  	schedule[i] = kword[0];
      }
!     INC_RXKAD_STATS(fc_key_scheds);
      return 0;
  }
  
***************
*** 140,148 ****
  #endif
  
      if (encrypt) {
! 	LOCK_RXKAD_STATS;
! 	rxkad_stats.fc_encrypts[ENCRYPT]++;
! 	UNLOCK_RXKAD_STATS;
  	for (i = 0; i < (ROUNDS / 2); i++) {
  	    S = *schedule++ ^ R;	/* xor R with key bits from schedule */
  	    Pchar[Byte2] = sbox0[Schar[Byte0]];	/* do 8-bit S Box subst. */
--- 138,144 ----
  #endif
  
      if (encrypt) {
! 	INC_RXKAD_STATS(fc_encrypts[ENCRYPT]);
  	for (i = 0; i < (ROUNDS / 2); i++) {
  	    S = *schedule++ ^ R;	/* xor R with key bits from schedule */
  	    Pchar[Byte2] = sbox0[Schar[Byte0]];	/* do 8-bit S Box subst. */
***************
*** 160,168 ****
  	    R ^= P;
  	}
      } else {
! 	LOCK_RXKAD_STATS;
! 	rxkad_stats.fc_encrypts[DECRYPT]++;
! 	UNLOCK_RXKAD_STATS;
  	schedule = &schedule[ROUNDS - 1];	/* start at end of key schedule */
  	for (i = 0; i < (ROUNDS / 2); i++) {
  	    S = *schedule-- ^ L;	/* xor R with key bits from schedule */
--- 156,162 ----
  	    R ^= P;
  	}
      } else {
! 	INC_RXKAD_STATS(fc_encrypts[DECRYPT]);
  	schedule = &schedule[ROUNDS - 1];	/* start at end of key schedule */
  	for (i = 0; i < (ROUNDS / 2); i++) {
  	    S = *schedule-- ^ L;	/* xor R with key bits from schedule */
Index: openafs/src/shlibafsrpc/afsrpc.exp
diff -c openafs/src/shlibafsrpc/afsrpc.exp:1.1 openafs/src/shlibafsrpc/afsrpc.exp:1.1.4.1
*** openafs/src/shlibafsrpc/afsrpc.exp:1.1	Wed Aug 28 02:05:51 2002
--- openafs/src/shlibafsrpc/afsrpc.exp	Mon May 30 00:57:39 2005
***************
*** 79,85 ****
  xdr_afsuuid
  xdr_int64
  hton_syserr_conv
! rxkad_stats
  _et_list
  et_list_mutex
  com_err
--- 79,87 ----
  xdr_afsuuid
  xdr_int64
  hton_syserr_conv
! rxkad_global_stats
! rxkad_global_stats_lock
! rxkad_stats_key
  _et_list
  et_list_mutex
  com_err
Index: openafs/src/shlibafsrpc/mapfile
diff -c openafs/src/shlibafsrpc/mapfile:1.3 openafs/src/shlibafsrpc/mapfile:1.3.2.1
*** openafs/src/shlibafsrpc/mapfile:1.3	Wed Mar 26 12:23:16 2003
--- openafs/src/shlibafsrpc/mapfile	Mon May 30 00:57:39 2005
***************
*** 54,60 ****
  	tkt_MakeTicket;
  	xdrrx_create;
  	hton_syserr_conv;
! 	rxkad_stats;
  	com_err;
  	error_message;
  	rx_socket;
--- 54,62 ----
  	tkt_MakeTicket;
  	xdrrx_create;
  	hton_syserr_conv;
! 	rxkad_global_stats;
! 	rxkad_global_stats_lock;
! 	rxkad_stats_key;
  	com_err;
  	error_message;
  	rx_socket;
Index: openafs/src/sys/pioctl_nt.c
diff -c openafs/src/sys/pioctl_nt.c:1.18.2.9 openafs/src/sys/pioctl_nt.c:1.18.2.10
*** openafs/src/sys/pioctl_nt.c:1.18.2.9	Thu Apr 28 08:11:38 2005
--- openafs/src/sys/pioctl_nt.c	Fri Apr 29 15:57:19 2005
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/sys/pioctl_nt.c,v 1.18.2.9 2005/04/28 12:11:38 jaltman Exp $");
  
  #include <afs/stds.h>
  #include <windows.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/sys/pioctl_nt.c,v 1.18.2.10 2005/04/29 19:57:19 jaltman Exp $");
  
  #include <afs/stds.h>
  #include <windows.h>
***************
*** 246,253 ****
              hKrb5DLL = 0;
              return FALSE;
          }
      }
!     return TRUE;
  }
  
  static BOOL
--- 246,254 ----
              hKrb5DLL = 0;
              return FALSE;
          }
+         return TRUE;
      }
!     return FALSE;
  }
  
  static BOOL
Index: openafs/src/tsm41/aix41_auth.c
diff -c openafs/src/tsm41/aix41_auth.c:1.10 openafs/src/tsm41/aix41_auth.c:1.10.2.1
*** openafs/src/tsm41/aix41_auth.c:1.10	Sat May  8 00:45:36 2004
--- openafs/src/tsm41/aix41_auth.c	Sun May  8 01:51:24 2005
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/tsm41/aix41_auth.c,v 1.10 2004/05/08 04:45:36 shadow Exp $");
  
  #if defined(AFS_AIX41_ENV)
  #include <sys/types.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/tsm41/aix41_auth.c,v 1.10.2.1 2005/05/08 05:51:24 shadow Exp $");
  
  #if defined(AFS_AIX41_ENV)
  #include <sys/types.h>
***************
*** 144,150 ****
  struct passwd *
  afs_getpwnam(char *user)
  {
!     return (struct passwd *) afs_getpwnam_int(user, 0);
  }
  
  struct passwd *
--- 144,150 ----
  struct passwd *
  afs_getpwnam(char *user)
  {
!   return (NULL);
  }
  
  struct passwd *
***************
*** 164,187 ****
      if (!user)
         return &pwd;
  
!     while ((p = getpwent()) != NULL) {
! 	if (!strcmp(p->pw_name, user)) {
! 	    strncpy(&name, p->pw_name, sizeof(name));
! 	    strncpy(&passwd, p->pw_passwd, sizeof(passwd));
! 	    strncpy(&gecos, p->pw_gecos, sizeof(gecos));
! 	    strncpy(&dir, p->pw_dir, sizeof(dir));
! 	    strncpy(&shell, p->pw_shell, sizeof(shell));
! 	    pwd.pw_name = &name;
! 	    pwd.pw_passwd = &passwd;
! 	    pwd.pw_uid = p->pw_uid;
! 	    pwd.pw_gid = p->pw_gid;
! 	    pwd.pw_gecos = &gecos;
! 	    pwd.pw_dir = &dir;
! 	    pwd.pw_shell = &shell;
! 	    break;
! 	}
      }
!     endpwent();
      if (ignore && (p == NULL))
         return NULL;
      return &pwd;
--- 164,186 ----
      if (!user)
         return &pwd;
  
!     p = getpwnam (user);
!     
!     if (p) {
!       strncpy(&name, p->pw_name, sizeof(name));
!       strncpy(&passwd, p->pw_passwd, sizeof(passwd));
!       strncpy(&gecos, p->pw_gecos, sizeof(gecos));
!       strncpy(&dir, p->pw_dir, sizeof(dir));
!       strncpy(&shell, p->pw_shell, sizeof(shell));
      }
!     pwd.pw_name = &name;
!     pwd.pw_passwd = &passwd;
!     pwd.pw_uid = p->pw_uid;
!     pwd.pw_gid = p->pw_gid;
!     pwd.pw_gecos = &gecos;
!     pwd.pw_dir = &dir;
!     pwd.pw_shell = &shell;
! 
      if (ignore && (p == NULL))
         return NULL;
      return &pwd;
Index: openafs/src/util/afsutil_prototypes.h
diff -c openafs/src/util/afsutil_prototypes.h:1.7.2.1 openafs/src/util/afsutil_prototypes.h:1.7.2.2
*** openafs/src/util/afsutil_prototypes.h:1.7.2.1	Sun Apr 24 10:27:58 2005
--- openafs/src/util/afsutil_prototypes.h	Sun May  8 02:10:26 2005
***************
*** 62,69 ****
   * early in name.
   */
  #ifdef AFS_64BIT_ENV
! #define int32_to_flipbase64(S, A) int64_to_flipbase64(S, (afs_int64)(A))
! extern char *int64_to_flipbase64(lb64_string_t s, afs_int64 a);
  extern afs_int64 flipbase64_to_int64(char *s);
  #else
  #define int32_to_flipbase64(S, A) int64_to_flipbase64(S, (u_int64_t)(A))
--- 62,69 ----
   * early in name.
   */
  #ifdef AFS_64BIT_ENV
! #define int32_to_flipbase64(S, A) int64_to_flipbase64(S, (afs_uint64)(A))
! extern char *int64_to_flipbase64(lb64_string_t s, afs_uint64 a);
  extern afs_int64 flipbase64_to_int64(char *s);
  #else
  #define int32_to_flipbase64(S, A) int64_to_flipbase64(S, (u_int64_t)(A))
Index: openafs/src/util/flipbase64.c
diff -c openafs/src/util/flipbase64.c:1.10 openafs/src/util/flipbase64.c:1.10.2.1
*** openafs/src/util/flipbase64.c:1.10	Fri Oct 24 02:26:17 2003
--- openafs/src/util/flipbase64.c	Sun May  8 02:10:26 2005
***************
*** 13,19 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/util/flipbase64.c,v 1.10 2003/10/24 06:26:17 shadow Exp $");
  
  
  #if defined(AFS_NAMEI_ENV)
--- 13,19 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/util/flipbase64.c,v 1.10.2.1 2005/05/08 06:10:26 shadow Exp $");
  
  
  #if defined(AFS_NAMEI_ENV)
***************
*** 80,86 ****
   */
  #ifdef AFS_64BIT_ENV
  char *
! int64_to_flipbase64(lb64_string_t s, afs_int64 a)
  #else
  char *
  int64_to_flipbase64(lb64_string_t s, u_int64_t a)
--- 80,86 ----
   */
  #ifdef AFS_64BIT_ENV
  char *
! int64_to_flipbase64(lb64_string_t s, afs_uint64 a)
  #else
  char *
  int64_to_flipbase64(lb64_string_t s, u_int64_t a)
***************
*** 88,94 ****
  {
      int i;
  #ifdef AFS_64BIT_ENV
!     afs_int64 n;
  #else
      u_int64_t n;
  #endif
--- 88,94 ----
  {
      int i;
  #ifdef AFS_64BIT_ENV
!     afs_uint64 n;
  #else
      u_int64_t n;
  #endif
Index: openafs/src/venus/fs.c
diff -c openafs/src/venus/fs.c:1.24.2.1 openafs/src/venus/fs.c:1.24.2.2
*** openafs/src/venus/fs.c:1.24.2.1	Mon Oct 18 03:12:20 2004
--- openafs/src/venus/fs.c	Sun May  8 02:18:14 2005
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/venus/fs.c,v 1.24.2.1 2004/10/18 07:12:20 shadow Exp $");
  
  #include <afs/afs_args.h>
  #include <rx/xdr.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/venus/fs.c,v 1.24.2.2 2005/05/08 06:18:14 shadow Exp $");
  
  #include <afs/afs_args.h>
  #include <rx/xdr.h>
***************
*** 112,117 ****
--- 112,124 ----
      afs_int32 rights;
  };
  
+ struct vcxstat2 {
+     afs_int32 callerAccess;
+     afs_int32 cbExpires;
+     afs_int32 anyAccess;
+     char mvstat;
+ };
+ 
  static void
  ZapAcl(acl)
       struct Acl *acl;
***************
*** 1189,1194 ****
--- 1196,1228 ----
  }
  
  static int
+ GetCallerAccess(struct cmd_syndesc *as, char *arock)
+ {
+     struct cmd_item *ti;
+     int error = 0;
+ 
+     SetDotDefault(&as->parms[0].items);
+     for (ti = as->parms[0].items; ti; ti = ti->next) {
+         afs_int32 code;
+         struct ViceIoctl blob;
+         struct vcxstat2 stat;
+         blob.out_size = sizeof(struct vcxstat2);
+         blob.in_size = 0;
+         blob.out = &stat;
+         code = pioctl(ti->data, VIOC_GETVCXSTATUS2, &blob, 1);
+         if (code) {
+             Die(errno, ti->data);
+             error = 1;
+             continue;
+         }
+         printf("Callers access to %s is ", ti->data);
+         PRights(stat.callerAccess, 0);
+         printf("\n");
+     }
+     return error;
+ }
+ 
+ static int
  FlushVolumeCmd(struct cmd_syndesc *as, char *arock)
  {
      afs_int32 code;
***************
*** 3172,3177 ****
--- 3206,3216 ----
      cmd_AddParm(ts, "-if", CMD_FLAG, CMD_OPTIONAL, "initial file acl");
      cmd_CreateAlias(ts, "la");
  
+     ts = cmd_CreateSyntax("getcalleraccess", GetCallerAccess, 0,
+             "list callers access");
+     cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
+     cmd_CreateAlias(ts, "gca");
+ 
      ts = cmd_CreateSyntax("cleanacl", CleanACLCmd, 0,
  			  "clean up access control list");
      cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
Index: openafs/src/viced/viced.c
diff -c openafs/src/viced/viced.c:1.58.2.4 openafs/src/viced/viced.c:1.58.2.5
*** openafs/src/viced/viced.c:1.58.2.4	Fri Apr 15 14:25:01 2005
--- openafs/src/viced/viced.c	Mon May 30 00:41:28 2005
***************
*** 20,26 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/viced.c,v 1.58.2.4 2005/04/15 18:25:01 shadow Exp $");
  
  #include <stdio.h>
  #include <stdlib.h>
--- 20,26 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/viced.c,v 1.58.2.5 2005/05/30 04:41:28 shadow Exp $");
  
  #include <stdio.h>
  #include <stdlib.h>
***************
*** 739,744 ****
--- 739,747 ----
      strcat(buffer, "[-rxpck <number of rx extra packets>] ");
      strcat(buffer, "[-rxdbg (enable rx debugging)] ");
      strcat(buffer, "[-rxdbge (enable rxevent debugging)] ");
+ #if AFS_PTHREAD_ENV
+     strcat(buffer, "[-vattachpar <number of volume attach threads>] ");
+ #endif
  #ifdef	AFS_AIX32_ENV
      strcat(buffer, "[-m <min percentage spare in partition>] ");
  #endif
***************
*** 934,939 ****
--- 937,950 ----
  		return -1; 
  	    }
  	    rxpackets = atoi(argv[++i]);
+ #ifdef AFS_PTHREAD_ENV
+ 	} else if (!strcmp(argv[i], "-vattachpar")) {
+             if ((i + 1) >= argc) {
+ 		fprintf(stderr, "missing argument for -vattachpar\n"); 
+ 		return -1; 
+ 	    }
+ 	    vol_attach_threads = atoi(argv[++i]);
+ #endif /* AFS_PTHREAD_ENV */
  	} else if (!strcmp(argv[i], "-s")) {
  	    Sawsmall = 1;
              if ((i + 1) >= argc) {
Index: openafs/src/vol/vol-info.c
diff -c openafs/src/vol/vol-info.c:1.18.2.2 openafs/src/vol/vol-info.c:1.18.2.3
*** openafs/src/vol/vol-info.c:1.18.2.2	Thu Mar 10 21:55:49 2005
--- openafs/src/vol/vol-info.c	Sun May  8 02:10:27 2005
***************
*** 18,24 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/vol-info.c,v 1.18.2.2 2005/03/11 02:55:49 shadow Exp $");
  
  #include <ctype.h>
  #include <errno.h>
--- 18,24 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/vol-info.c,v 1.18.2.3 2005/05/08 06:10:27 shadow Exp $");
  
  #include <ctype.h>
  #include <errno.h>
***************
*** 256,262 ****
      if ((ti = as->parms[5].items))
  	partName = ti->data;
      if ((ti = as->parms[6].items))
! 	volumeId = atoi(ti->data);
      if (as->parms[7].items)
  	dheader = 1;
      else
--- 256,262 ----
      if ((ti = as->parms[5].items))
  	partName = ti->data;
      if ((ti = as->parms[6].items))
! 	volumeId = strtoul(ti->data, NULL, 10);
      if (as->parms[7].items)
  	dheader = 1;
      else
***************
*** 499,505 ****
  		printf("\tVolId\t= %u\n", header.id);
  	    }
  
! 	    IH_INIT(ih, dp->device, header.id, header.volumeInfo);
  	    fdP = IH_OPEN(ih);
  	    if (fdP == NULL) {
  		perror("opening volume info");
--- 499,505 ----
  		printf("\tVolId\t= %u\n", header.id);
  	    }
  
! 	    IH_INIT(ih, dp->device, header.parent, header.volumeInfo);
  	    fdP = IH_OPEN(ih);
  	    if (fdP == NULL) {
  		perror("opening volume info");
***************
*** 519,525 ****
  		       PrintInode(NULL, header.volumeInfo), code);
  	    }
  
! 	    IH_INIT(ih, dp->device, header.id, header.smallVnodeIndex);
  	    fdP = IH_OPEN(ih);
  	    if (fdP == NULL) {
  		perror("opening small vnode index");
--- 519,525 ----
  		       PrintInode(NULL, header.volumeInfo), code);
  	    }
  
! 	    IH_INIT(ih, dp->device, header.parent, header.smallVnodeIndex);
  	    fdP = IH_OPEN(ih);
  	    if (fdP == NULL) {
  		perror("opening small vnode index");
***************
*** 538,544 ****
  		       PrintInode(NULL, header.smallVnodeIndex), code);
  	    }
  
! 	    IH_INIT(ih, dp->device, header.id, header.largeVnodeIndex);
  	    fdP = IH_OPEN(ih);
  	    if (fdP == NULL) {
  		perror("opening large vnode index");
--- 538,544 ----
  		       PrintInode(NULL, header.smallVnodeIndex), code);
  	    }
  
! 	    IH_INIT(ih, dp->device, header.parent, header.largeVnodeIndex);
  	    fdP = IH_OPEN(ih);
  	    if (fdP == NULL) {
  		perror("opening large vnode index");
***************
*** 560,566 ****
  #endif
  	    }
  #ifdef AFS_NAMEI_ENV
! 	    IH_INIT(ih, dp->device, header.id, header.linkTable);
  	    fdP = IH_OPEN(ih);
  	    if (fdP == NULL) {
  		perror("opening link table index");
--- 560,566 ----
  #endif
  	    }
  #ifdef AFS_NAMEI_ENV
! 	    IH_INIT(ih, dp->device, header.parent, header.linkTable);
  	    fdP = IH_OPEN(ih);
  	    if (fdP == NULL) {
  		perror("opening link table index");
***************
*** 612,617 ****
--- 612,619 ----
  	       Vauxsize_k, Vvnodesize_k, totvolsize, totvolsize - Vdiskused,
  	       V_name(vp));
      }
+     free(vp->header);
+     free(vp);
  }
  
  int
Index: openafs/src/vol/volume.c
diff -c openafs/src/vol/volume.c:1.35.2.3 openafs/src/vol/volume.c:1.35.2.6
*** openafs/src/vol/volume.c:1.35.2.3	Wed Apr 13 22:00:36 2005
--- openafs/src/vol/volume.c	Mon May 30 06:50:04 2005
***************
*** 20,26 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/volume.c,v 1.35.2.3 2005/04/14 02:00:36 shadow Exp $");
  
  #include <rx/xdr.h>
  #include <afs/afsint.h>
--- 20,26 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/volume.c,v 1.35.2.6 2005/05/30 10:50:04 jaltman Exp $");
  
  #include <rx/xdr.h>
  #include <afs/afsint.h>
***************
*** 152,157 ****
--- 152,158 ----
  pthread_mutex_t vol_trans_mutex;
  pthread_cond_t vol_put_volume_cond;
  pthread_cond_t vol_sleep_cond;
+ int vol_attach_threads = 1;
  #endif /* AFS_PTHREAD_ENV */
  
  #ifdef	AFS_OSF_ENV
***************
*** 209,214 ****
--- 210,229 ----
  }
  #endif /* !AFS_HAVE_FFS */
  
+ #ifdef AFS_PTHREAD_ENV
+ #include "rx/rx_queue.h"
+ typedef struct diskpartition_queue_t {
+     struct rx_queue queue;
+     struct DiskPartition * diskP;
+ } diskpartition_queue_t;
+ typedef struct vinitvolumepackage_thread_t {
+     struct rx_queue queue;
+     pthread_cond_t thread_done_cv;
+     int n_threads_complete;
+ } vinitvolumepackage_thread_t;
+ static void * VInitVolumePackageThread(void * args);
+ #endif /* AFS_PTHREAD_ENV */
+ 
  struct Lock vol_listLock;	/* Lock obtained when listing volumes:  prevents a volume from being missed if the volume is attached during a list volumes */
  
  extern struct Lock FSYNC_handler_lock;
***************
*** 229,235 ****
  bit32 VolumeCacheCheck;		/* Incremented everytime a volume goes on line--
  				 * used to stamp volume headers and in-core
  				 * vnodes.  When the volume goes on-line the
! 				 * vnode will be invalidated */
  
  int VolumeCacheSize = 200, VolumeGets = 0, VolumeReplacements = 0, Vlooks = 0;
  
--- 244,251 ----
  bit32 VolumeCacheCheck;		/* Incremented everytime a volume goes on line--
  				 * used to stamp volume headers and in-core
  				 * vnodes.  When the volume goes on-line the
! 				 * vnode will be invalidated
! 				 * access only with VOL_LOCK held */
  
  int VolumeCacheSize = 200, VolumeGets = 0, VolumeReplacements = 0, Vlooks = 0;
  
***************
*** 284,293 ****
  	return -1;
  
      if (programType == fileServer) {
- 	DIR *dirp;
- 	struct dirent *dp;
  	struct DiskPartition *diskP;
  
  
  	/* Attach all the volumes in this partition */
  	for (diskP = DiskPartitionList; diskP; diskP = diskP->next) {
--- 300,347 ----
  	return -1;
  
      if (programType == fileServer) {
  	struct DiskPartition *diskP;
+ #ifdef AFS_PTHREAD_ENV
+ 	struct vinitvolumepackage_thread_t params;
+ 	struct diskpartition_queue_t * dpq;
+ 	int i, len;
+ 	pthread_t tid;
+ 	pthread_attr_t attrs;
+ 
+ 	assert(pthread_cond_init(&params.thread_done_cv,NULL) == 0);
+ 	queue_Init(&params);
+ 	params.n_threads_complete = 0;
+ 
+ 	/* create partition work queue */
+ 	for (len=0, diskP = DiskPartitionList; diskP; diskP = diskP->next, len++) {
+ 	    dpq = (diskpartition_queue_t *) malloc(sizeof(struct diskpartition_queue_t));
+ 	    assert(dpq != NULL);
+ 	    dpq->diskP = diskP;
+ 	    queue_Prepend(&params,dpq);
+ 	}
+ 
+ 	assert(pthread_attr_init(&attrs) == 0);
+ 	assert(pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED) == 0);
+ 
+ 	len = MIN(len, vol_attach_threads);
+ 	
+ 	VOL_LOCK;
+ 	for (i=0; i < len; i++) {
+ 	    assert(pthread_create
+ 		   (&tid, &attrs, &VInitVolumePackageThread,
+ 		    &params) == 0);
+ 	}
+ 
+ 	while(params.n_threads_complete < len) {
+   	    pthread_cond_wait(&params.thread_done_cv,&vol_glock_mutex);
+ 	}
+ 	VOL_UNLOCK;
  
+ 	assert(pthread_cond_destroy(&params.thread_done_cv) == 0);
+ 
+ #else /* AFS_PTHREAD_ENV */
+ 	DIR *dirp;
+ 	struct dirent *dp;
  
  	/* Attach all the volumes in this partition */
  	for (diskP = DiskPartitionList; diskP; diskP = diskP->next) {
***************
*** 319,324 ****
--- 373,379 ----
  	    Log("Partition %s: attached %d volumes; %d volumes not attached\n", diskP->name, nAttached, nUnattached);
  	    closedir(dirp);
  	}
+ #endif /* AFS_PTHREAD_ENV */
      }
  
      VInit = 2;			/* Initialized, and all volumes have been attached */
***************
*** 332,337 ****
--- 387,453 ----
      return 0;
  }
  
+ #ifdef AFS_PTHREAD_ENV
+ static void *
+ VInitVolumePackageThread(void * args) {
+     int errors = 0;		/* Number of errors while finding vice partitions. */
+ 
+     DIR *dirp;
+     struct dirent *dp;
+     struct DiskPartition *diskP;
+     struct vinitvolumepackage_thread_t * params;
+     struct diskpartition_queue_t * dpq;
+ 
+     params = (vinitvolumepackage_thread_t *) args;
+ 
+ 
+     VOL_LOCK;
+     /* Attach all the volumes in this partition */
+     while (queue_IsNotEmpty(params)) {
+         int nAttached = 0, nUnattached = 0;
+ 
+         dpq = queue_First(params,diskpartition_queue_t);
+ 	queue_Remove(dpq);
+ 	VOL_UNLOCK;
+ 	diskP = dpq->diskP;
+ 	free(dpq);
+ 
+ 	Log("Partition %s: attaching volumes\n", diskP->name);
+ 	dirp = opendir(VPartitionPath(diskP));
+ 	assert(dirp);
+ 	while ((dp = readdir(dirp))) {
+ 	    char *p;
+ 	    p = strrchr(dp->d_name, '.');
+ 	    if (p != NULL && strcmp(p, VHDREXT) == 0) {
+ 	        Error error;
+ 		Volume *vp;
+ 		vp = VAttachVolumeByName(&error, diskP->name, dp->d_name,
+ 					 V_VOLUPD);
+ 		(*(vp ? &nAttached : &nUnattached))++;
+ 		if (error == VOFFLINE)
+ 		    Log("Volume %d stays offline (/vice/offline/%s exists)\n", VolumeNumber(dp->d_name), dp->d_name);
+ 		else if (LogLevel >= 5) {
+ 		    Log("Partition %s: attached volume %d (%s)\n",
+ 			diskP->name, VolumeNumber(dp->d_name),
+ 			dp->d_name);
+ 		}
+ 		if (vp) {
+ 		    VPutVolume(vp);
+ 		}
+ 	    }
+ 	}
+ 	Log("Partition %s: attached %d volumes; %d volumes not attached\n", diskP->name, nAttached, nUnattached);
+ 	closedir(dirp);
+ 	VOL_LOCK;
+     }
+ 
+     params->n_threads_complete++;
+     pthread_cond_signal(&params->thread_done_cv);
+     VOL_UNLOCK;
+     return NULL;
+ }
+ #endif /* AFS_PTHREAD_ENV */
+ 
  /* This must be called by any volume utility which needs to run while the
     file server is also running.  This is separated from VInitVolumePackage so
     that a utility can fork--and each of the children can independently
***************
*** 725,730 ****
--- 841,847 ----
      register Volume *vp;
  
      VOL_UNLOCK;
+ 
      vp = (Volume *) calloc(1, sizeof(Volume));
      assert(vp != NULL);
      vp->specialStatus = (byte) (isbusy ? VBUSY : 0);
***************
*** 737,754 ****
      IH_INIT(vp->diskDataHandle, partp->device, header->parent,
  	    header->volumeInfo);
      IH_INIT(vp->linkHandle, partp->device, header->parent, header->linkTable);
-     vp->cacheCheck = ++VolumeCacheCheck;
-     /* just in case this ever rolls over */
-     if (!vp->cacheCheck)
- 	vp->cacheCheck = ++VolumeCacheCheck;
      vp->shuttingDown = 0;
      vp->goingOffline = 0;
      vp->nUsers = 1;
      VOL_LOCK;
      GetVolumeHeader(vp);
      VOL_UNLOCK;
      (void)ReadHeader(ec, V_diskDataHandle(vp), (char *)&V_disk(vp),
  		     sizeof(V_disk(vp)), VOLUMEINFOMAGIC, VOLUMEINFOVERSION);
      VOL_LOCK;
      if (*ec) {
  	Log("VAttachVolume: Error reading diskDataHandle vol header %s; error=%u\n", path, *ec);
--- 854,874 ----
      IH_INIT(vp->diskDataHandle, partp->device, header->parent,
  	    header->volumeInfo);
      IH_INIT(vp->linkHandle, partp->device, header->parent, header->linkTable);
      vp->shuttingDown = 0;
      vp->goingOffline = 0;
      vp->nUsers = 1;
+ 
      VOL_LOCK;
+     vp->cacheCheck = ++VolumeCacheCheck;
+     /* just in case this ever rolls over */
+     if (!vp->cacheCheck)
+ 	vp->cacheCheck = ++VolumeCacheCheck;
      GetVolumeHeader(vp);
      VOL_UNLOCK;
+ 
      (void)ReadHeader(ec, V_diskDataHandle(vp), (char *)&V_disk(vp),
  		     sizeof(V_disk(vp)), VOLUMEINFOMAGIC, VOLUMEINFOVERSION);
+ 
      VOL_LOCK;
      if (*ec) {
  	Log("VAttachVolume: Error reading diskDataHandle vol header %s; error=%u\n", path, *ec);
***************
*** 1060,1066 ****
  		    Log("Volume %u: couldn't reread volume header\n",
  			vp->hashid);
  		FreeVolume(vp);
! 		vp = 0;
  		break;
  	    }
  	}
--- 1180,1186 ----
  		    Log("Volume %u: couldn't reread volume header\n",
  			vp->hashid);
  		FreeVolume(vp);
! 		vp = NULL;
  		break;
  	    }
  	}
***************
*** 1068,1074 ****
  	if (vp->shuttingDown) {
  	    V8++;
  	    *ec = VNOVOL;
! 	    vp = 0;
  	    break;
  	}
  	if (programType == fileServer) {
--- 1188,1194 ----
  	if (vp->shuttingDown) {
  	    V8++;
  	    *ec = VNOVOL;
! 	    vp = NULL;
  	    break;
  	}
  	if (programType == fileServer) {
***************
*** 1811,1821 ****
      int old;
      static int everLogged = 0;
  
!     old = (vp->header != 0);	/* old == volume already has a header */
      if (programType != fileServer) {
  	if (!vp->header) {
  	    hd = (struct volHeader *)calloc(1, sizeof(*vp->header));
! 	    assert(hd != 0);
  	    vp->header = hd;
  	    hd->back = vp;
  	}
--- 1931,1941 ----
      int old;
      static int everLogged = 0;
  
!     old = (vp->header != NULL);	/* old == volume already has a header */
      if (programType != fileServer) {
  	if (!vp->header) {
  	    hd = (struct volHeader *)calloc(1, sizeof(*vp->header));
! 	    assert(hd != NULL);
  	    vp->header = hd;
  	    hd->back = vp;
  	}
***************
*** 1946,1948 ****
--- 2066,2069 ----
      VPrintCacheStats_r();
      VOL_UNLOCK;
  }
+ 
Index: openafs/src/vol/volume.h
diff -c openafs/src/vol/volume.h:1.14.2.2 openafs/src/vol/volume.h:1.14.2.3
*** openafs/src/vol/volume.h:1.14.2.2	Mon Dec 13 14:41:11 2004
--- openafs/src/vol/volume.h	Mon May 30 00:41:29 2005
***************
*** 34,43 ****
  extern pthread_mutex_t vol_trans_mutex;
  extern pthread_cond_t vol_put_volume_cond;
  extern pthread_cond_t vol_sleep_cond;
! #define VATTACH_LOCK \
!     assert(pthread_mutex_lock(&vol_attach_mutex) == 0)
! #define VATTACH_UNLOCK \
!     assert(pthread_mutex_unlock(&vol_attach_mutex) == 0)
  #define VOL_LOCK \
      assert(pthread_mutex_lock(&vol_glock_mutex) == 0)
  #define VOL_UNLOCK \
--- 34,43 ----
  extern pthread_mutex_t vol_trans_mutex;
  extern pthread_cond_t vol_put_volume_cond;
  extern pthread_cond_t vol_sleep_cond;
! extern int vol_attach_threads;
! /* this lock has been deprecated */
! #define VATTACH_LOCK
! #define VATTACH_UNLOCK
  #define VOL_LOCK \
      assert(pthread_mutex_lock(&vol_glock_mutex) == 0)
  #define VOL_UNLOCK \
Index: openafs/src/xstat/xstat_cm_test.c
diff -c openafs/src/xstat/xstat_cm_test.c:1.8 openafs/src/xstat/xstat_cm_test.c:1.8.2.1
*** openafs/src/xstat/xstat_cm_test.c:1.8	Tue Jul 15 19:17:52 2003
--- openafs/src/xstat/xstat_cm_test.c	Sun May  8 01:04:18 2005
***************
*** 17,23 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/xstat/xstat_cm_test.c,v 1.8 2003/07/15 23:17:52 shadow Exp $");
  
  #include "xstat_cm.h"		/*Interface for xstat_cm module */
  #include <cmd.h>		/*Command line interpreter */
--- 17,23 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/xstat/xstat_cm_test.c,v 1.8.2.1 2005/05/08 05:04:18 shadow Exp $");
  
  #include "xstat_cm.h"		/*Interface for xstat_cm module */
  #include <cmd.h>		/*Command line interpreter */
***************
*** 755,760 ****
--- 755,764 ----
      printf("\t%10d srvMaxChainLengthHWM\n", a_ovP->srvMaxChainLengthHWM);
      printf("\t%10d srvRecordsHWM\n", a_ovP->srvRecordsHWM);
  
+     printf("\t%10d cacheBucket0_Discarded\n",  a_ovP->cacheBucket0_Discarded);
+     printf("\t%10d cacheBucket1_Discarded\n",  a_ovP->cacheBucket1_Discarded);
+     printf("\t%10d cacheBucket2_Discarded\n",  a_ovP->cacheBucket2_Discarded);
+ 
      printf("\t%10d sysName_ID\n", a_ovP->sysName_ID);
  
      printf("\tFile Server up/downtimes, same cell:\n");
