Index: openafs/src/NTMakefile
diff -c openafs/src/NTMakefile:1.27.2.7 openafs/src/NTMakefile:1.27.2.8
*** openafs/src/NTMakefile:1.27.2.7 Fri Feb 1 21:48:12 2008
--- openafs/src/NTMakefile Tue Mar 11 13:02:04 2008
***************
*** 60,66 ****
$(NTMAKE_HEADERS)
$(CD) ..\..\..
! util: procmgmt_headers afsreg_headers
echo ***** $@
$(DOCD) $(SRC)\$@
$(CD) $(SRC)\$@
--- 60,73 ----
$(NTMAKE_HEADERS)
$(CD) ..\..\..
! lwp_headers:
! echo ***** $@
! $(DOCD) $(SRC)\lwp
! $(CD) $(SRC)\lwp
! $(NTMAKE_HEADERS)
! $(CD) ..\..\..
!
! util: procmgmt_headers afsreg_headers lwp_headers
echo ***** $@
$(DOCD) $(SRC)\$@
$(CD) $(SRC)\$@
Index: openafs/src/WINNT/afsd/NTMakefile
diff -c openafs/src/WINNT/afsd/NTMakefile:1.46.2.9 openafs/src/WINNT/afsd/NTMakefile:1.46.2.11
*** openafs/src/WINNT/afsd/NTMakefile:1.46.2.9 Fri Feb 8 21:32:19 2008
--- openafs/src/WINNT/afsd/NTMakefile Wed Mar 19 09:59:29 2008
***************
*** 64,69 ****
--- 64,70 ----
$(INCFILEDIR)\cm_buf.h \
$(INCFILEDIR)\cm_freelance.h \
$(INCFILEDIR)\cm_memmap.h \
+ $(INCFILEDIR)\cm_performance.h \
$(INCFILEDIR)\afsd_eventlog.h \
$(INCFILEDIR)\afsd_eventmessages.h \
$(INCFILEDIR)\afskfw.h \
***************
*** 89,103 ****
$(IDLFILES):afsrpc.idl
midl $(MIDL_FLAGS) $(AFSDEV_AUXMIDLFLAGS) /app_config $?
- RPCOBJS = $(OUT)\ifs_rpc.obj
-
- $(RPCOBJS):..\afsrdr\ifs_rpc.c
- $(C2OBJ) ..\afsrdr\ifs_rpc.c
-
AFSDOBJS=\
- $(OUT)\ifs_rpc.obj \
$(OUT)\rawops.obj \
- $(OUT)\afsdifs.obj \
$(OUT)\afsd_init.obj \
$(OUT)\cm_btree.obj \
$(OUT)\cm_cell.obj \
--- 90,97 ----
***************
*** 125,130 ****
--- 119,125 ----
$(OUT)\cm_dnlc.obj \
$(OUT)\cm_rpc.obj \
$(OUT)\cm_memmap.obj \
+ $(OUT)\cm_performance.obj \
$(OUT)\afsrpc_s.obj \
!IFDEF OSICRASH
$(OUT)\afsdcrash.obj \
Index: openafs/src/WINNT/afsd/afsd.c
diff -c openafs/src/WINNT/afsd/afsd.c:1.13 openafs/src/WINNT/afsd/afsd.c:1.13.4.2
*** openafs/src/WINNT/afsd/afsd.c:1.13 Thu Aug 4 12:32:32 2005
--- openafs/src/WINNT/afsd/afsd.c Wed Mar 19 11:36:25 2008
***************
*** 6,35 ****
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
*/
- /* AFSIFS Portions copyright (c) 2005
- * the regents of the university of michigan
- * all rights reserved
- *
- * permission is granted to use, copy, create derivative works and
- * redistribute this software and such derivative works for any purpose,
- * so long as the name of the university of michigan is not used in
- * any advertising or publicity pertaining to the use or distribution
- * of this software without specific, written prior authorization. if
- * the above copyright notice or any other identification of the
- * university of michigan is included in any copy of any portion of
- * this software, then the disclaimer below must also be included.
- *
- * this software is provided as is, without representation from the
- * university of michigan as to its fitness for any purpose, and without
- * warranty by the university of michigan of any kind, either express
- * or implied, including without limitation the implied warranties of
- * merchantability and fitness for a particular purpose. the regents
- * of the university of michigan shall not be liable for any damages,
- * including special, indirect, incidental, or consequential damages,
- * with respect to any claim arising out or in connection with the use
- * of the software, even if it has been or is hereafter advised of the
- * possibility of such damages.
- */
#include
#include
--- 6,11 ----
***************
*** 49,56 ****
#include
#endif
- #include "afsdifs.h"
-
HANDLE main_inst;
HWND main_wnd;
char main_statusText[100];
--- 25,30 ----
***************
*** 134,147 ****
DispatchMessage(&msg);
}
- #ifdef AFSIFS
- WaitForMultipleObjects(WORKER_THREADS, hAFSDWorkerThread, TRUE, INFINITE);
- for (i = 0; i < WORKER_THREADS; i++)
- CloseHandle(hAFSDWorkerThread[i]);
- //CloseHandle(hAFSDMainThread);
- RpcMgmtStopServerListening(NULL);
- #endif
-
return (msg.wParam);
}
--- 108,113 ----
***************
*** 223,245 ****
if (code != 0)
osi_panic(reason, __FILE__, __LINE__);
- #ifndef AFSIFS
code = afsd_InitSMB(&reason, MessageBox);
- #else
- code = ifs_Init(&reason);
- #endif
if (code != 0)
osi_panic(reason, __FILE__, __LINE__);
- #ifdef AFSIFS
- DoTerminate = CreateEvent(NULL, TRUE, FALSE, TEXT("afsd_service_DoTerminate"));
- if ( GetLastError() == ERROR_ALREADY_EXISTS )
- afsi_log("Event Object Already Exists: %s", TEXT("afsd_service_DoTerminate"));
- for (cnt = 0; cnt < WORKER_THREADS; cnt++)
- hAFSDWorkerThread[cnt] = CreateThread(NULL, 0, ifs_MainLoop, 0, 0, NULL);
- #endif
-
ShowWindow(hWnd, SW_SHOWMINNOACTIVE);
UpdateWindow(hWnd);
return (TRUE);
--- 189,199 ----
***************
*** 276,284 ****
break;
case WM_DESTROY:
- #ifdef AFSIFS
- SetEvent(DoTerminate);
- #endif
RpcMgmtStopServerListening(NULL);
PostQuitMessage(0);
break;
--- 230,235 ----
Index: openafs/src/WINNT/afsd/afsd.h
diff -c openafs/src/WINNT/afsd/afsd.h:1.18.2.6 openafs/src/WINNT/afsd/afsd.h:1.18.2.8
*** openafs/src/WINNT/afsd/afsd.h:1.18.2.6 Sat Dec 22 23:52:58 2007
--- openafs/src/WINNT/afsd/afsd.h Fri Mar 7 17:24:04 2008
***************
*** 62,67 ****
--- 62,68 ----
#include "cm_buf.h"
#include "cm_memmap.h"
#include "cm_freelance.h"
+ #include "cm_performance.h"
#include "smb_ioctl.h"
#include "afsd_init.h"
#ifdef DJGPP
***************
*** 112,123 ****
extern int cm_fakeDirSize; // size (in bytes) of fake root.afs directory
extern int cm_fakeDirCallback; // state of the fake root.afs directory. indicates
! // if it needs to be refreshed
extern int cm_fakeGettingCallback; // 1 if currently updating the fake root.afs directory,
! // 0 otherwise
!
! extern int cm_fakeDirVersion; // the version number of the root.afs directory. used
#endif /* AFS_FREELANCE_CLIENT */
extern int cm_dnsEnabled;
--- 113,122 ----
extern int cm_fakeDirSize; // size (in bytes) of fake root.afs directory
extern int cm_fakeDirCallback; // state of the fake root.afs directory. indicates
! // if it needs to be refreshed
extern int cm_fakeGettingCallback; // 1 if currently updating the fake root.afs directory,
! // 0 otherwise
#endif /* AFS_FREELANCE_CLIENT */
extern int cm_dnsEnabled;
Index: openafs/src/WINNT/afsd/afsd_eventlog.c
diff -c openafs/src/WINNT/afsd/afsd_eventlog.c:1.5 openafs/src/WINNT/afsd/afsd_eventlog.c:1.5.4.3
*** openafs/src/WINNT/afsd/afsd_eventlog.c:1.5 Sun Jan 15 21:05:27 2006
--- openafs/src/WINNT/afsd/afsd_eventlog.c Sat Mar 8 09:17:32 2008
***************
*** 64,155 ****
AddEventSource()
{
HKEY hKey = NULL, hLogKey;
! UCHAR szBuf[MAX_PATH];
DWORD dwData, dwDisposition;
! BOOL bRet = TRUE;
! do {
! if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_APPLOG_SUBKEY, 0,
! KEY_QUERY_VALUE, &hLogKey ) )
! {
! // nope - create it
! if ( RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_APPLOG_SUBKEY, 0,
! NULL, REG_OPTION_NON_VOLATILE,
! KEY_ALL_ACCESS, NULL, &hLogKey,
! &dwDisposition))
! {
! bRet = FALSE;
! break;
! }
! }
!
! // Let's see if key already exists as a subkey under the
! // Application key in the EventLog registry key. If not,
! // create it.
! if ( RegOpenKeyEx( hLogKey, AFSREG_CLT_APPLOG_SUBKEY, 0,
! KEY_QUERY_VALUE, &hKey ) )
! {
! // nope - create it
! if ( RegCreateKeyEx(hLogKey, AFSREG_CLT_APPLOG_SUBKEY, 0,
! NULL, REG_OPTION_NON_VOLATILE,
! KEY_ALL_ACCESS, NULL, &hKey,
! &dwDisposition))
! {
! bRet = FALSE;
! break;
! }
!
! // Set the name of the message file
! // Get "ImagePath" from TransarcAFSDaemon service
! memset(szBuf, '\0', MAX_PATH);
! dwData = MAX_PATH;
! GetServicePath(szBuf, &dwData);
!
! // Add the name to the EventMessageFile subkey.
! if ( RegSetValueEx( hKey, // subkey handle
! AFSREG_APPLOG_MSGFILE_VALUE, // value name
! 0, // must be zero
! REG_EXPAND_SZ, // value type
! (LPBYTE) szBuf, // pointer to value data
! (DWORD)strlen(szBuf) + 1)) // length of value data
! {
! bRet = FALSE;
! break;
! }
!
! // Set the supported event types in the TypesSupported subkey.
! dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
! EVENTLOG_INFORMATION_TYPE;
!
! if ( RegSetValueEx( hKey, // subkey handle
! AFSREG_APPLOG_MSGTYPE_VALUE, // value name
! 0, // must be zero
! REG_DWORD, // value type
! (LPBYTE) &dwData, // pointer to value data
! sizeof(DWORD))) // length of value data
! {
! bRet = FALSE;
! break;
! }
! }
! else
! {
! // key was opened - read it
! memset(szBuf, '\0', MAX_PATH);
! dwData = MAX_PATH;
! if ( RegQueryValueEx( hKey, // handle to key
! AFSREG_APPLOG_MSGFILE_VALUE, // value name
! NULL, // reserved
! NULL, // type buffer
! (LPBYTE) szBuf, // data buffer
! &dwData)) // size of data buffer
! {
! bRet = FALSE;
! break;
! }
! }
! } while (0);
!
if (hKey != NULL)
RegCloseKey(hKey);
--- 64,136 ----
AddEventSource()
{
HKEY hKey = NULL, hLogKey;
! UCHAR szBuf[MAX_PATH] = "afsd_service.exe";
DWORD dwData, dwDisposition;
! static BOOL bRet = TRUE;
! static BOOL bOnce = TRUE;
! if (!bOnce)
! return bRet;
!
! if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_APPLOG_SUBKEY, 0,
! KEY_SET_VALUE, &hLogKey ) )
! {
! // nope - create it
! if ( RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_APPLOG_SUBKEY, 0,
! NULL, REG_OPTION_NON_VOLATILE,
! KEY_ALL_ACCESS, NULL, &hLogKey,
! &dwDisposition))
! {
! bRet = FALSE;
! goto done;
! }
! }
!
! // Let's see if key already exists as a subkey under the
! // Application key in the EventLog registry key. If not,
! // create it.
! if ( RegOpenKeyEx( hLogKey, AFSREG_CLT_APPLOG_SUBKEY, 0,
! KEY_SET_VALUE, &hKey ) )
! {
! // nope - create it
! if ( RegCreateKeyEx(hLogKey, AFSREG_CLT_APPLOG_SUBKEY, 0,
! NULL, REG_OPTION_NON_VOLATILE,
! KEY_ALL_ACCESS, NULL, &hKey,
! &dwDisposition))
! {
! bRet = FALSE;
! goto done;
! }
! }
!
! // Add the name to the EventMessageFile subkey.
! if ( RegSetValueEx( hKey, // subkey handle
! AFSREG_APPLOG_MSGFILE_VALUE, // value name
! 0, // must be zero
! REG_SZ, // value type
! (LPBYTE) szBuf, // pointer to value data
! (DWORD)strlen(szBuf) + 1)) // length of value data
! {
! bRet = FALSE;
! goto done;
! }
!
! // Set the supported event types in the TypesSupported subkey.
! dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
! EVENTLOG_INFORMATION_TYPE;
!
! if ( RegSetValueEx( hKey, // subkey handle
! AFSREG_APPLOG_MSGTYPE_VALUE, // value name
! 0, // must be zero
! REG_DWORD, // value type
! (LPBYTE) &dwData, // pointer to value data
! sizeof(DWORD))) // length of value data
! {
! bRet = FALSE;
! goto done;
! }
!
! done:
if (hKey != NULL)
RegCloseKey(hKey);
Index: openafs/src/WINNT/afsd/afsd_init.c
diff -c openafs/src/WINNT/afsd/afsd_init.c:1.79.2.32 openafs/src/WINNT/afsd/afsd_init.c:1.79.2.38
*** openafs/src/WINNT/afsd/afsd_init.c:1.79.2.32 Mon Feb 25 17:21:24 2008
--- openafs/src/WINNT/afsd/afsd_init.c Wed Mar 19 20:01:59 2008
***************
*** 62,70 ****
DWORD cm_mountRootLen;
int cm_logChunkSize;
int cm_chunkSize;
- #ifdef AFS_FREELANCE_CLIENT
- char *cm_FakeRootDir;
- #endif /* freelance */
int smb_UseV3 = 1;
--- 62,67 ----
***************
*** 558,566 ****
DWORD blockSize;
long logChunkSize;
DWORD stats;
DWORD dwValue;
! DWORD rx_enable_peer_stats = 0;
! DWORD rx_enable_process_stats = 0;
long traceBufSize;
long maxcpus;
long ltt, ltto;
--- 555,565 ----
DWORD blockSize;
long logChunkSize;
DWORD stats;
+ DWORD volumes;
+ DWORD cells;
DWORD dwValue;
! DWORD rx_enable_peer_stats;
! DWORD rx_enable_process_stats;
long traceBufSize;
long maxcpus;
long ltt, ltto;
***************
*** 776,785 ****
code = RegQueryValueEx(parmKey, "Stats", NULL, NULL,
(BYTE *) &stats, &dummyLen);
if (code == ERROR_SUCCESS)
! afsi_log("Status cache size %d", stats);
else {
stats = CM_CONFIGDEFAULT_STATS;
! afsi_log("Default status cache size %d", stats);
}
dummyLen = sizeof(ltt);
--- 775,804 ----
code = RegQueryValueEx(parmKey, "Stats", NULL, NULL,
(BYTE *) &stats, &dummyLen);
if (code == ERROR_SUCCESS)
! afsi_log("Status cache entries: %d", stats);
else {
stats = CM_CONFIGDEFAULT_STATS;
! afsi_log("Default status cache entries: %d", stats);
! }
!
! dummyLen = sizeof(volumes);
! code = RegQueryValueEx(parmKey, "Volumes", NULL, NULL,
! (BYTE *) &volumes, &dummyLen);
! if (code == ERROR_SUCCESS)
! afsi_log("Volumes cache entries: %d", volumes);
! else {
! volumes = CM_CONFIGDEFAULT_STATS / 3;
! afsi_log("Default volume cache entries: %d", volumes);
! }
!
! dummyLen = sizeof(cells);
! code = RegQueryValueEx(parmKey, "Cells", NULL, NULL,
! (BYTE *) &cells, &dummyLen);
! if (code == ERROR_SUCCESS)
! afsi_log("Cell cache entries: %d", cells);
! else {
! cells = CM_CONFIGDEFAULT_CELLS;
! afsi_log("Default cell cache entries: %d", cells);
}
dummyLen = sizeof(ltt);
***************
*** 1044,1062 ****
code = RegQueryValueEx(parmKey, "RxEnablePeerStats", NULL, NULL,
(BYTE *) &rx_enable_peer_stats, &dummyLen);
if (code != ERROR_SUCCESS) {
! rx_enable_peer_stats = 0;
}
if (rx_enable_peer_stats)
afsi_log("RX Peer Statistics gathering is enabled");
dummyLen = sizeof(rx_enable_process_stats);
code = RegQueryValueEx(parmKey, "RxEnableProcessStats", NULL, NULL,
(BYTE *) &rx_enable_process_stats, &dummyLen);
if (code != ERROR_SUCCESS) {
! rx_enable_process_stats = 0;
}
if (rx_enable_process_stats)
afsi_log("RX Process Statistics gathering is enabled");
dummyLen = sizeof(dwValue);
dwValue = 0;
--- 1063,1085 ----
code = RegQueryValueEx(parmKey, "RxEnablePeerStats", NULL, NULL,
(BYTE *) &rx_enable_peer_stats, &dummyLen);
if (code != ERROR_SUCCESS) {
! rx_enable_peer_stats = 1;
}
if (rx_enable_peer_stats)
afsi_log("RX Peer Statistics gathering is enabled");
+ else
+ afsi_log("RX Peer Statistics gathering is disabled");
dummyLen = sizeof(rx_enable_process_stats);
code = RegQueryValueEx(parmKey, "RxEnableProcessStats", NULL, NULL,
(BYTE *) &rx_enable_process_stats, &dummyLen);
if (code != ERROR_SUCCESS) {
! rx_enable_process_stats = 1;
}
if (rx_enable_process_stats)
afsi_log("RX Process Statistics gathering is enabled");
+ else
+ afsi_log("RX Process Statistics gathering is disabled");
dummyLen = sizeof(dwValue);
dwValue = 0;
***************
*** 1199,1205 ****
cm_initParams.nChunkFiles = 0;
cm_initParams.nStatCaches = stats;
cm_initParams.nDataCaches = (afs_uint32)(cacheBlocks > 0xFFFFFFFF ? 0xFFFFFFFF : cacheBlocks);
! cm_initParams.nVolumeCaches = stats/2;
cm_initParams.firstChunkSize = cm_chunkSize;
cm_initParams.otherChunkSize = cm_chunkSize;
cm_initParams.cacheSize = cacheSize;
--- 1222,1228 ----
cm_initParams.nChunkFiles = 0;
cm_initParams.nStatCaches = stats;
cm_initParams.nDataCaches = (afs_uint32)(cacheBlocks > 0xFFFFFFFF ? 0xFFFFFFFF : cacheBlocks);
! cm_initParams.nVolumeCaches = volumes;
cm_initParams.firstChunkSize = cm_chunkSize;
cm_initParams.otherChunkSize = cm_chunkSize;
cm_initParams.cacheSize = cacheSize;
***************
*** 1222,1228 ****
cm_InitCallback();
! code = cm_InitMappedMemory(virtualCache, cm_CachePath, stats, cm_chunkSize, cacheBlocks, blockSize);
afsi_log("cm_InitMappedMemory code %x", code);
if (code != 0) {
*reasonP = "error initializing cache file";
--- 1245,1251 ----
cm_InitCallback();
! code = cm_InitMappedMemory(virtualCache, cm_CachePath, stats, volumes, cells, cm_chunkSize, cacheBlocks, blockSize);
afsi_log("cm_InitMappedMemory code %x", code);
if (code != 0) {
*reasonP = "error initializing cache file";
***************
*** 1348,1356 ****
osi_Log0(afsd_logp, "Loading Root Volume from cell");
do {
! code = cm_GetVolumeByName(cm_data.rootCellp, cm_rootVolumeName, cm_rootUserp,
&req, CM_GETVOL_FLAG_CREATE, &cm_data.rootVolumep);
! afsi_log("cm_GetVolumeByName code %x root vol %x", code,
(code ? (cm_volume_t *)-1 : cm_data.rootVolumep));
} while (code && --attempts);
if (code != 0) {
--- 1371,1379 ----
osi_Log0(afsd_logp, "Loading Root Volume from cell");
do {
! code = cm_FindVolumeByName(cm_data.rootCellp, cm_rootVolumeName, cm_rootUserp,
&req, CM_GETVOL_FLAG_CREATE, &cm_data.rootVolumep);
! afsi_log("cm_FindVolumeByName code %x root vol %x", code,
(code ? (cm_volume_t *)-1 : cm_data.rootVolumep));
} while (code && --attempts);
if (code != 0) {
***************
*** 1401,1407 ****
code = RegQueryValueEx(parmKey, "EnableSMBAsyncStore", NULL, NULL,
(BYTE *) &dwValue, &dummyLen);
if (code == ERROR_SUCCESS)
! smb_AsyncStore = dwValue ? 1 : 0;
afsi_log("EnableSMBAsyncStore = %d", smb_AsyncStore);
dummyLen = sizeof(DWORD);
--- 1424,1430 ----
code = RegQueryValueEx(parmKey, "EnableSMBAsyncStore", NULL, NULL,
(BYTE *) &dwValue, &dummyLen);
if (code == ERROR_SUCCESS)
! smb_AsyncStore = dwValue == 2 ? 2 : (dwValue ? 1 : 0);
afsi_log("EnableSMBAsyncStore = %d", smb_AsyncStore);
dummyLen = sizeof(DWORD);
Index: openafs/src/WINNT/afsd/afsd_service.c
diff -c openafs/src/WINNT/afsd/afsd_service.c:1.52.4.23 openafs/src/WINNT/afsd/afsd_service.c:1.52.4.25
*** openafs/src/WINNT/afsd/afsd_service.c:1.52.4.23 Sat Feb 2 17:27:11 2008
--- openafs/src/WINNT/afsd/afsd_service.c Wed Mar 19 11:36:25 2008
***************
*** 23,29 ****
#ifdef _DEBUG
#include
#endif
- #include "afsdifs.h"
//#define REGISTER_POWER_NOTIFICATIONS 1
#include "afsd_flushvol.h"
--- 23,28 ----
***************
*** 34,42 ****
static SERVICE_STATUS_HANDLE StatusHandle;
HANDLE hAFSDMainThread = NULL;
- #ifdef AFSIFS
- HANDLE hAFSDWorkerThread[WORKER_THREADS];
- #endif
HANDLE WaitToTerminate;
--- 33,38 ----
***************
*** 58,66 ****
*/
static void afsd_notifier(char *msgp, char *filep, long line)
{
- #ifdef AFSIFS
- int i;
- #endif
if (!msgp)
msgp = "unspecified assert";
--- 54,59 ----
***************
*** 96,106 ****
#endif
SetEvent(WaitToTerminate);
- #ifdef AFSIFS
- WaitForMultipleObjects(WORKER_THREADS, hAFSDWorkerThread, TRUE, INFINITE);
- for (i = 0; i < WORKER_THREADS; i++)
- CloseHandle(hAFSDWorkerThread[i]);
- #endif
#ifdef JUMP
if (GetCurrentThreadId() == MainThreadId)
--- 89,94 ----
***************
*** 425,433 ****
#define MAX_DRIVES 23
static DWORD __stdcall MountGlobalDrivesThread(void * notUsed)
{
- #ifndef AFSIFS
char szAfsPath[_MAX_PATH];
- #endif
char szDriveToMapTo[5];
DWORD dwResult;
char szKeyName[256];
--- 413,419 ----
***************
*** 456,462 ****
}
}
- #ifndef AFSIFS
for (dwRetry = 0 ; dwRetry < MAX_RETRIES; dwRetry++)
{
NETRESOURCE nr;
--- 442,447 ----
***************
*** 483,492 ****
/* Disconnect any previous mappings */
dwResult = WNetCancelConnection2(szDriveToMapTo, 0, TRUE);
}
- #else
- /* FIXFIX: implement */
- afsi_log("GlobalAutoMap of %s to %s not implemented", szDriveToMapTo, szSubMount);
- #endif
}
RegCloseKey(hKey);
--- 468,473 ----
***************
*** 515,528 ****
static void DismountGlobalDrives()
{
- #ifndef AFSIFS
char szAfsPath[_MAX_PATH];
char szDriveToMapTo[5];
DWORD dwDriveSize;
DWORD dwSubMountSize;
char szSubMount[256];
DWORD dwType;
- #endif
DWORD dwResult;
char szKeyName[256];
HKEY hKey;
--- 496,507 ----
***************
*** 547,555 ****
if (dwResult != ERROR_SUCCESS)
return;
- #ifdef AFSIFS
- /* FIXFIX: implement */
- #else
while (dwIndex < MAX_DRIVES) {
dwDriveSize = sizeof(szDriveToMapTo);
dwSubMountSize = sizeof(szSubMount);
--- 526,531 ----
***************
*** 569,575 ****
afsi_log("Disconnect from GlobalAutoMap of %s to %s %s", szDriveToMapTo, szSubMount, dwResult ? "succeeded" : "failed");
}
- #endif
RegCloseKey(hKey);
}
--- 545,550 ----
***************
*** 1117,1125 ****
#endif /* JUMP */
HMODULE hHookDll;
HMODULE hAdvApi32;
- #ifdef AFSIFS
- int cnt;
- #endif
#ifdef _DEBUG
afsd_DbgBreakAllocInit();
--- 1092,1097 ----
***************
*** 1321,1341 ****
/* the following ifdef chooses the mode of operation for the service. to enable
* a runtime flag (instead of compile-time), pioctl() would need to dynamically
* determine the mode, in order to use the correct ioctl special-file path. */
- #ifndef AFSIFS
code = afsd_InitSMB(&reason, MessageBox);
if (code != 0) {
afsi_log("afsd_InitSMB failed: %s (code = %d)", reason, code);
osi_panic(reason, __FILE__, __LINE__);
}
- #else
- code = ifs_Init(&reason);
- if (code != 0) {
- afsi_log("ifs_Init failed: %s (code = %d)", reason, code);
- osi_panic(reason, __FILE__, __LINE__);
- }
- for (cnt = 0; cnt < WORKER_THREADS; cnt++)
- hAFSDWorkerThread[cnt] = CreateThread(NULL, 0, ifs_MainLoop, 0, 0, NULL);
- #endif
/* allow an exit to be called post smb initialization */
hHookDll = LoadLibrary(AFSD_HOOK_DLL);
--- 1293,1303 ----
***************
*** 1407,1419 ****
}
}
- #ifndef AFSIFS
WaitForSingleObject(WaitToTerminate, INFINITE);
- #else
- WaitForMultipleObjects(WORKER_THREADS, hAFSDWorkerThread, TRUE, INFINITE);
- for (cnt = 0; cnt < WORKER_THREADS; cnt++)
- CloseHandle(hAFSDWorkerThread[cnt]);
- #endif
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
ServiceStatus.dwWin32ExitCode = NO_ERROR;
--- 1369,1375 ----
***************
*** 1463,1472 ****
rx_Finalize();
afsi_log("rx finalization complete");
- #ifndef AFSIFS
smb_Shutdown();
afsi_log("smb shutdown complete");
- #endif
RpcShutdown();
--- 1419,1426 ----
***************
*** 1565,1573 ****
printf("Hit to terminate OpenAFS Client Service\n");
getchar();
SetEvent(WaitToTerminate);
- #ifdef AFSIFS
- dc_release_hooks();
- #endif
}
}
--- 1519,1524 ----
Index: openafs/src/WINNT/afsd/afsdifs.c
diff -c openafs/src/WINNT/afsd/afsdifs.c:1.5.4.1 openafs/src/WINNT/afsd/afsdifs.c:removed
*** openafs/src/WINNT/afsd/afsdifs.c:1.5.4.1 Thu Jul 20 17:46:18 2006
--- openafs/src/WINNT/afsd/afsdifs.c Sat Mar 22 21:01:32 2008
***************
*** 1,1160 ****
- /* copyright (c) 2005
- * the regents of the university of michigan
- * all rights reserved
- *
- * permission is granted to use, copy, create derivative works and
- * redistribute this software and such derivative works for any purpose,
- * so long as the name of the university of michigan is not used in
- * any advertising or publicity pertaining to the use or distribution
- * of this software without specific, written prior authorization. if
- * the above copyright notice or any other identification of the
- * university of michigan is included in any copy of any portion of
- * this software, then the disclaimer below must also be included.
- *
- * this software is provided as is, without representation from the
- * university of michigan as to its fitness for any purpose, and without
- * warranty by the university of michigan of any kind, either express
- * or implied, including without limitation the implied warranties of
- * merchantability and fitness for a particular purpose. the regents
- * of the university of michigan shall not be liable for any damages,
- * including special, indirect, incidental, or consequential damages,
- * with respect to any claim arising out or in connection with the use
- * of the software, even if it has been or is hereafter advised of the
- * possibility of such damages.
- */
-
- #include
- #include "afsd.h"
- #include
- #include "..\afsrdr\kif.h"
- #include "..\afsrdr\ifs_rpc.h"
-
- #include "afsdifs.h"
-
-
- /****************************/
- /* parameters, macros, etc. */
- /****************************/
- #define IFSL_SUCCEEDED(st) (!(st & IFSL_FAIL_BASE))
- #define MAP_RETURN(code) if (code) return ifs_MapCmError(code);
- #define ROOTPATH "\\"
- #define TRANSFER_BUF_SIZE (RPC_BUF_SIZE + TRANSFER_CHUNK_SIZE)
- #define SCPL_LOCK EnterCriticalSection(&scp_list_lock);
- #define SCPL_UNLOCK LeaveCriticalSection(&scp_list_lock);
-
-
- /****************************/
- /* structs */
- /****************************/
- struct user_map_entry /* how we keep users straight. total of MAX_AFS_USERS of these */
- {
- LARGE_INTEGER id; /* internal id created by kernel */
- cm_user_t *creds; /* global (thread-specific) var userp is set to this */
- };
-
- struct scp_status /* one for each unique file in afs */
- {
- struct scp_status *next; /* stored in a global chain in a chain locked by SCPL_[UN]LOCK */
- cm_scache_t *scp; /* file handle used with cm_ fns */
- ULONG fid; /* internal id generated by FID_HASH_FN from AFS's 128-bit FID */
- };
- typedef struct scp_status scp_status_t;
-
- struct readdir_context /* temporary struct, allocated as necessary, for cm_Apply callback */
- {
- char *matchString; /* for matching against */
- char *buf, *buf_pos; /* filling buffer to length, currently at buf_pos */
- ULONG_PTR length;
- ULONG count; /* number of entries packed so far */
- };
- typedef struct readdir_context readdir_context_t;
-
-
- /****************************/
- /* global vars */
- /****************************/
- /* the table user_map is used to store cm_user structs keyed on the calling
- * process' 64-bit ID token. the rpc library sets userp to point to this
- * entry; userp is specific to each thread, and thus may be used securely
- * as a global.
- */
- __declspec(thread) cm_user_t *userp;
- struct user_map_entry user_map[MAX_AFS_USERS];
-
- CRITICAL_SECTION mapLock, scp_list_lock;
-
- scp_status_t *scp_list_head = NULL;
-
-
- /****************************/
- /* error functions */
- /****************************/
- char *IfslErrorToText(unsigned long ifsl)
- {
- switch (ifsl)
- {
- case IFSL_SUCCESS:
- return "success";
- case IFSL_DOES_NOT_EXIST:
- return "does not exist";
- case IFSL_NOT_IMPLEMENTED:
- return "not implemented";
- case IFSL_END_OF_ENUM:
- return "end of enum";
- case IFSL_CANNOT_MAKE:
- return "cannot make";
- case IFSL_END_OF_FILE:
- return "end of file";
- case IFSL_NO_ACCESS:
- return "no access";
- case IFSL_BUFFER_TOO_SMALL:
- return "buffer too small";
- case IFSL_SHARING_VIOLATION:
- return "sharing violation";
- case IFSL_BAD_INPUT:
- return "bad input";
- case IFSL_GENERIC_FAILURE:
- return "generic failure";
- case IFSL_OPEN_CREATED:
- return "open created";
- case IFSL_OPEN_EXISTS:
- return "open exists";
- case IFSL_OPEN_OPENED:
- return "opened";
- case IFSL_OPEN_OVERWRITTEN:
- return "overwritten";
- case IFSL_OPEN_SUPERSCEDED:
- return "supersceded";
- case IFSL_BADFILENAME:
- return "bad filename";
- case IFSL_READONLY:
- return "read only";
- case IFSL_IS_A_DIR:
- return "is a dir";
- case IFSL_PATH_DOES_NOT_EXIST:
- return "path does not exist";
- case IFSL_IS_A_FILE:
- return "is a file";
- case IFSL_NOT_EMPTY:
- return "dir not empty";
- case IFSL_UNSPEC:
- return "unspecified error";
- default:
- return "NOT FOUND";
- }
- }
-
- unsigned long ifs_MapCmError(unsigned long code)
- {
- switch (code)
- {
- case CM_ERROR_STOPNOW:
- case 0:
- return IFSL_SUCCESS;
- case CM_ERROR_NOSUCHCELL:
- case CM_ERROR_NOSUCHVOLUME:
- case CM_ERROR_NOSUCHFILE:
- return IFSL_DOES_NOT_EXIST;
- case CM_ERROR_NOSUCHPATH:
- return IFSL_PATH_DOES_NOT_EXIST;
- case CM_ERROR_BADNTFILENAME:
- return IFSL_BADFILENAME;
- case CM_ERROR_TIMEDOUT:
- case CM_ERROR_ALLOFFLINE:
- case CM_ERROR_CLOCKSKEW:
- case CM_ERROR_REMOTECONN:
- case CM_ERROR_ALLBUSY:
- return IFSL_GENERIC_FAILURE;
- case CM_ERROR_NOACCESS:
- return IFSL_NO_ACCESS;
- case CM_ERROR_RETRY:
- case CM_ERROR_TOOBIG:
- case CM_ERROR_BADFD:
- case CM_ERROR_BADFDOP:
- case CM_ERROR_CROSSDEVLINK:
- return IFSL_GENERIC_FAILURE;
- case CM_ERROR_EXISTS:
- return IFSL_OPEN_EXISTS;
- case CM_ERROR_BADOP:
- case CM_ERROR_INVAL:
- case CM_ERROR_UNKNOWN:
- case CM_ERROR_BADSMB:
- return IFSL_GENERIC_FAILURE;
- case CM_ERROR_NOTDIR:
- case CM_ERROR_ISDIR:
- case CM_ERROR_READONLY:
- return IFSL_BAD_INPUT;
- case CM_ERROR_BUFFERTOOSMALL:
- return IFSL_BUFFER_TOO_SMALL;
- case CM_ERROR_WOULDBLOCK:
- case CM_ERROR_BADSHARENAME:
- case CM_ERROR_NOMORETOKENS:
- case CM_ERROR_NOTEMPTY:
- case CM_ERROR_USESTD:
- case CM_ERROR_ATSYS:
- return IFSL_GENERIC_FAILURE;
- case CM_ERROR_NOFILES:
- case CM_ERROR_BADTID:
- return IFSL_END_OF_ENUM;
- case CM_ERROR_PARTIALWRITE:
- case CM_ERROR_NOIPC:
- case CM_ERROR_RENAME_IDENTICAL:
- case CM_ERROR_AMBIGUOUS_FILENAME:
- return IFSL_GENERIC_FAILURE;
- case IFSL_SHARING_VIOLATION:
- return IFSL_SHARING_VIOLATION;
- case IFSL_NOT_EMPTY:
- return IFSL_NOT_EMPTY;
- case CM_ERROR_SPACE:
- case CM_ERROR_QUOTA:
- return IFSL_OVERQUOTA;
- }
- return IFSL_GENERIC_FAILURE;
- }
-
-
- /****************************/
- /* support fns */
- /****************************/
- cm_scache_t *ifs_FindScp(ULONG fid) /* walk list to find scp<->fid mapping */
- {
- scp_status_t *curr;
-
- SCPL_LOCK;
-
- curr = scp_list_head;
- while (curr)
- {
- if (curr->fid == fid)
- {
- SCPL_UNLOCK;
- return curr->scp;
- }
- curr = curr->next;
- }
- SCPL_UNLOCK;
- return NULL;
- }
-
- /* must call with scp write-locked. will always return correct results
- unless network fails (it loops properly). */
- ifs_CheckAcl(cm_scache_t *scp, ULONG access, ULONG *granted)
- {
- long code;
- cm_req_t req;
-
- cm_InitReq(&req);
-
- /* ripped from cm_scache.c */
- while (1)
- {
- if (cm_HaveAccessRights(scp, userp, access, granted))
- {
- return 0;
- }
- else
- {
- /* we don't know the required access rights */
- code = cm_GetAccessRights(scp, userp, &req);
- MAP_RETURN(code);
- continue;
- }
- }
-
- return 0;
- }
-
- /* extract data from scp. an ifs_ support function to centralize changes. */
- ifs_CopyInfo(cm_scache_t *scp, ULONG *attribs, LARGE_INTEGER *size,
- LARGE_INTEGER *creation, LARGE_INTEGER *access,
- LARGE_INTEGER *change, LARGE_INTEGER *written)
- {
- access->QuadPart = 0; /* these mappings are not quite correct. we can */
- change->QuadPart = scp->clientModTime; /* leave them zero, if necessary. */
- written->QuadPart = scp->clientModTime;
- creation->QuadPart = scp->serverModTime;
-
- *attribs = 0;
- if (scp->fileType == CM_SCACHETYPE_DIRECTORY ||
- scp->fileType == CM_SCACHETYPE_SYMLINK ||
- scp->fileType == CM_SCACHETYPE_MOUNTPOINT/* ||
- scp->fileType == 0*/)
- *attribs |= FILE_ATTRIBUTE_DIRECTORY;
-
- /*if (!attribs && scp->fileType == CM_SCACHETYPE_FILE)
- *attribs |= FILE_ATTRIBUTE_NORMAL;*/
-
- if (*attribs == FILE_ATTRIBUTE_DIRECTORY)
- size->QuadPart = 0;
- else
- *size = scp->length;
-
- return 0;
- }
-
-
- /* close and zero scp pointer. zeroing pointer should
- help eliminate accessing discarded cache entries. */
- void ifs_InternalClose(cm_scache_t **scpp)
- {
- osi_assert(scpp && *scpp);
-
- lock_ObtainMutex(&((*scpp)->mx));
- cm_ReleaseSCache(*scpp);
-
- lock_ReleaseMutex(&((*scpp)->mx));
- *scpp = NULL;
- }
-
- /* normalizes path by removing trailing slashes. separates last
- * path component with a null, so that *dirp points to parent path
- * and *filep points to filename. modifies string path.
- */
- BOOLEAN ifs_FindComponents(char *path, const char **dirp, const char **filep)
- {
- char *lastSep;
- BOOLEAN removed;
- static char emptyPath[] = "\\"; /* if the path contains only one component, this is the parent. */
-
- osi_assert(path);
-
- if (strlen(path))
- removed = (path[strlen(path)-1] == '\\');
- else
- removed = 1;
-
- lastSep = strrchr(path, '\\');
- while (lastSep == path + strlen(path) - 1)
- {
- *lastSep = '\0';
- lastSep = strrchr(path, '\\');
- }
-
- if (lastSep)
- {
- *lastSep = '\0';
-
- *dirp = path;
- *filep = lastSep + 1;
- }
- else
- {
- lastSep = path + strlen(path);
-
- *dirp = emptyPath;
- *filep = path;
- }
-
- return removed;
- }
-
- /* here to make maintenance easy */
- unsigned long ifs_ConvertFileName(wchar_t *in, unsigned int inchars, char *out, unsigned int outchars)
- {
- unsigned long code;
-
- code = WideCharToMultiByte(CP_UTF8, 0/*WC_NO_BEST_FIT_CHARS*/, in, inchars, out, outchars-1, NULL, NULL);
- if (!code)
- return IFSL_BADFILENAME;
-
- return 0;
- }
-
- /* called by rpc_ library to let us initialize environment.
- * call with id of zero to clear current thread auth. */
- ifs_ImpersonateClient(LARGE_INTEGER user_id)
- {
- int x, empty;
-
- if (!user_id.QuadPart)
- {
- userp = NULL;
- return 0;
- }
-
- empty = -1;
- EnterCriticalSection(&mapLock);
- for (x = 0; x < MAX_AFS_USERS; x++)
- {
- if (user_map[x].id.QuadPart == 0)
- empty = x;
- if (user_map[x].id.QuadPart == user_id.QuadPart)
- goto done;
- }
- if (empty == -1)
- {
- LeaveCriticalSection(&mapLock);
- return -1;
- }
- user_map[empty].id = user_id;
- user_map[empty].creds = cm_NewUser();
- x = empty;
-
- done:
- userp = user_map[x].creds;
- LeaveCriticalSection(&mapLock);
-
- return 0;
- }
-
-
- /****************************/
- /* upcalls */
- /****************************/
- long uc_namei(WCHAR *name, ULONG *fid) /* performs name<->fid mapping, and enters it into table */
- {
- char *buffer; /* we support semi-infinite path lengths */
- long code;
- cm_scache_t *scp, *dscp;
- char *dirp, *filep;
- cm_req_t req;
- scp_status_t *st;
- short len;
-
- cm_InitReq(&req);
-
- len = (short)wcslen(name)+20; /* characters *should* map 1<->1, but in case */
- buffer = malloc(len);
- code = ifs_ConvertFileName(name, -1, buffer, len);
- if (code)
- {
- free(buffer);
- MAP_RETURN(code);
- }
- ifs_FindComponents(buffer, &dirp, &filep);
-
- code = cm_NameI(cm_data.rootSCachep, dirp, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, ROOTPATH, &req, &dscp);
- if (code)
- {
- free(buffer);
- MAP_RETURN(code);
- }
- if (*filep)
- code = cm_Lookup(dscp, filep, 0, userp, &req, &scp);
- else
- cm_HoldSCache(scp = dscp);
- cm_ReleaseSCache(dscp);
-
- if (code)
- {
- free(buffer);
- MAP_RETURN(code);
- }
-
- if (ifs_FindScp(FID_HASH_FN(&scp->fid)))
- {
- osi_assertx(ifs_FindScp(FID_HASH_FN(&scp->fid)) == scp, "uc_namei: same fid hash for two files");
- *fid = FID_HASH_FN(&scp->fid);
- osi_assert(scp->refCount > 1);
- cm_ReleaseSCache(scp);
- }
- else
- {
- SCPL_LOCK;
- st = malloc(sizeof(scp_status_t));
- st->scp = scp;
- st->fid = FID_HASH_FN(&scp->fid);
- st->next = scp_list_head;
- scp_list_head = st;
- SCPL_UNLOCK;
- osi_assert(scp->refCount == 1);
- *fid = st->fid;
- }
-
- free(buffer);
-
- return 0;
- }
-
- /* this should only be called right after open, so we do not need to stat file.
- * we only check the server's restrictions. sharing violations are handled in the
- * kernel. the access mode we grant sticks with the file_object until its death. */
- long uc_check_access(ULONG fid, ULONG access, ULONG *granted)
- {
- ULONG afs_acc, afs_gr;
- cm_scache_t *scp;
- ULONG gr;
- BOOLEAN file, dir;
-
- gr = 0;
-
- scp = ifs_FindScp(fid);
- if (!scp)
- return IFSL_BAD_INPUT;
-
- file = (scp->fileType == CM_SCACHETYPE_FILE);
- dir = !file;
-
- /* access definitions from prs_fs.h */
- afs_acc = 0;
- if (access & FILE_READ_DATA)
- afs_acc |= PRSFS_READ;
- if (file && ((access & FILE_WRITE_DATA) || (access & FILE_APPEND_DATA)))
- afs_acc |= PRSFS_WRITE;
- if (access & FILE_WRITE_EA || access & FILE_WRITE_ATTRIBUTES)
- afs_acc |= PRSFS_WRITE;
- if (dir && ((access & FILE_ADD_FILE) || (access & FILE_ADD_SUBDIRECTORY)))
- afs_acc |= PRSFS_INSERT;
- if (dir && (access & FILE_LIST_DIRECTORY))
- afs_acc |= PRSFS_LOOKUP;
- if (access & FILE_READ_EA || access & FILE_READ_ATTRIBUTES)
- afs_acc |= PRSFS_LOOKUP;
- if (file && (access & FILE_EXECUTE))
- afs_acc |= PRSFS_WRITE;
- if (dir && (access & FILE_TRAVERSE))
- afs_acc |= PRSFS_READ;
- if (dir && (access & FILE_DELETE_CHILD))
- afs_acc |= PRSFS_DELETE;
- if ((access & DELETE))
- afs_acc |= PRSFS_DELETE;
-
- /* check ACL with server */
- lock_ObtainMutex(&(scp->mx));
- ifs_CheckAcl(scp, afs_acc, &afs_gr);
- lock_ReleaseMutex(&(scp->mx));
-
- *granted = 0;
- if (afs_gr & PRSFS_READ)
- *granted |= FILE_READ_DATA | FILE_EXECUTE;
- if (afs_gr & PRSFS_WRITE)
- *granted |= FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES | FILE_EXECUTE;
- if (afs_gr & PRSFS_INSERT)
- *granted |= (dir ? FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY : 0) | (file ? FILE_ADD_SUBDIRECTORY : 0);
- if (afs_gr & PRSFS_LOOKUP)
- *granted |= (dir ? FILE_LIST_DIRECTORY : 0) | FILE_READ_EA | FILE_READ_ATTRIBUTES;
- if (afs_gr & PRSFS_DELETE)
- *granted |= FILE_DELETE_CHILD | DELETE;
- if (afs_gr & PRSFS_LOCK)
- *granted |= 0;
- if (afs_gr & PRSFS_ADMINISTER)
- *granted |= 0;
-
- * granted |= SYNCHRONIZE | READ_CONTROL;
-
- return 0;
- }
-
- long uc_create(WCHAR *name, ULONG attribs, LARGE_INTEGER alloc, ULONG access, ULONG *granted, ULONG *fid)
- {
- char *buffer; /* we support semi-infinite path lengths */
- long code;
- cm_scache_t *scp, *dscp;
- char *dirp, *filep;
- unsigned char removed;
- cm_req_t req;
- scp_status_t *st;
- cm_attr_t attr;
- short len;
-
- cm_InitReq(&req);
-
- len = (short)wcslen(name)+20; /* characters *should* map 1<->1, but in case */
- buffer = malloc(len);
- code = ifs_ConvertFileName(name, -1, buffer, len);
- if (code)
- {
- free(buffer);
- MAP_RETURN(code);
- }
- removed = ifs_FindComponents(buffer, &dirp, &filep);
-
- /* lookup the parent directory, which must exist */
- code = cm_NameI(cm_data.rootSCachep, dirp, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, ROOTPATH, &req, &dscp);
- if (code)
- {
- free(buffer);
- MAP_RETURN(code);
- }
-
- osi_assert(filep);
- if (*filep)
- {
- attr.mask = CM_ATTRMASK_LENGTH;
- attr.length = alloc;
-
- if (attribs & FILE_ATTRIBUTE_DIRECTORY)
- {
- code = cm_MakeDir(dscp, filep, 0, &attr, userp, &req);
- if (!code)
- code = cm_Lookup(dscp, filep, 0, userp, &req, &scp);
- }
- else
- code = cm_Create(dscp, filep, 0, &attr, &scp, userp, &req);
- }
- cm_ReleaseSCache(dscp);
-
- if (code)
- {
- free(buffer);
- MAP_RETURN(code);
- }
-
- SCPL_LOCK;
- st = malloc(sizeof(scp_status_t));
- st->scp = scp;
- st->fid = FID_HASH_FN(&scp->fid);
- st->next = scp_list_head;
- scp_list_head = st;
- SCPL_UNLOCK;
-
- *fid = st->fid;
- *granted = access;
-
- free(buffer);
-
- return 0;
- }
-
- /* this does not fill the attribs member completely. additional flags must
- be added in the kernel, such as read-only. */
- long uc_stat(ULONG fid, ULONG *attribs, LARGE_INTEGER *size, LARGE_INTEGER *creation,
- LARGE_INTEGER *access, LARGE_INTEGER *change, LARGE_INTEGER *written)
- {
- cm_scache_t *scp;
- cm_req_t req;
- ULONG code;
-
- scp = ifs_FindScp(fid);
- if (!scp)
- return IFSL_BAD_INPUT;
-
- /* stat file; don't want callback */
- cm_InitReq(&req);
- lock_ObtainMutex(&(scp->mx));
- cm_HoldUser(userp);
- code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_GETSTATUS);
- cm_ReleaseUser(userp);
-
- if (code)
- lock_ReleaseMutex(&(scp->mx));
- MAP_RETURN(code);
-
- code = ifs_CopyInfo(scp, attribs, size, creation, access, change, written);
- lock_ReleaseMutex(&(scp->mx));
- MAP_RETURN(code);
-
- return 0;
- }
-
- /* set atime, mtime, etc. */
- long uc_setinfo(ULONG fid, ULONG attribs, LARGE_INTEGER creation, LARGE_INTEGER access,
- LARGE_INTEGER change, LARGE_INTEGER written)
- {
- return IFSL_GENERIC_FAILURE;
- }
-
- /* FIXFIX: this code may not catch over-quota errors, because the end
- * of the file is not written to the server by the time this returns. */
- /* truncate or extend file, in cache and on server */
- long uc_trunc(ULONG fid, LARGE_INTEGER size)
- {
- ULONG code;
- cm_scache_t *scp;
- cm_req_t req;
- osi_hyper_t oldLen;
-
- scp = ifs_FindScp(fid);
- if (!scp)
- return IFSL_BAD_INPUT;
-
- /* we have already checked permissions in the kernel; but, if we do not
- * have access as this userp, code will fail in rpc layer.
- */
-
- cm_InitReq(&req);
- lock_ObtainMutex(&(scp->mx));
-
- code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_GETSTATUS);
-
- if (code)
- lock_ReleaseMutex(&(scp->mx));
- MAP_RETURN(code);
-
- oldLen = scp->length;
- lock_ReleaseMutex(&(scp->mx));
-
- code = cm_SetLength(scp, &size, userp, &req);
- MAP_RETURN(code);
- /*code = cm_FSync(scp, userp, &req);
- MAP_RETURN(code);*/
- /*code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_GETSTATUS);
- MAP_RETURN(code);*/
-
- #if 0
- /* attempt to write last byte of file. fails to bring out quota errors because of delayed writing. */
- if (oldLen.QuadPart < size.QuadPart)
- {
- writePos.QuadPart = size.QuadPart - 1;
- WriteData(scp, writePos, 1, &"\0\0\0", userp, &written);
- MAP_RETURN(code);
- if (written != 1)
- return IFSL_UNSPEC;
- }
- #endif
-
- return 0;
- }
-
- /* read data from a file */
- long uc_read(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *read, char *data)
- {
- ULONG code;
- cm_scache_t *scp;
-
- *read = 0;
-
- scp = ifs_FindScp(fid);
- if (!scp)
- return IFSL_BAD_INPUT;
-
- if (scp->fileType == CM_SCACHETYPE_DIRECTORY)
- return IFSL_IS_A_DIR;
-
- code = ReadData(scp, offset, (unsigned long)length, data, userp, read);
- MAP_RETURN(code);
-
- return 0;
- }
-
- /* FIXFIX: this does not catch all overquota errors, because the file
- * is not necessarily written to the server when this returns. */
- /* write data to a file */
- long uc_write(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *written, char *data)
- {
- ULONG code;
- cm_scache_t *scp;
-
- scp = ifs_FindScp(fid);
- if (!scp)
- return IFSL_BAD_INPUT;
-
- if (offset.QuadPart == -1)
- offset = scp->length;
- code = WriteData(scp, offset, (unsigned long)length, data, userp, written);
- MAP_RETURN(code);
-
- return 0;
- }
-
- long uc_rename(ULONG fid, WCHAR *curr, WCHAR *new_dir, WCHAR *new_name, ULONG *new_fid)
- {
- int code;
- cm_req_t req;
- char *curdir, *curfile, *newdir, *newfile;
- cm_scache_t *dscp1, *dscp2, *scp;
- char b1[MAX_PATH], b2[MAX_PATH], b3[MAX_PATH];
- wchar_t b3_w[MAX_PATH];
-
- code = !(scp = ifs_FindScp(fid));
- if (!code)
- code = ifs_ConvertFileName(curr, -1, b1, MAX_PATH);
- if (!code)
- code = ifs_ConvertFileName(new_name, -1, b2, MAX_PATH);
- if (!code)
- code = ifs_ConvertFileName(new_dir, -1, b3, MAX_PATH);
- if (!code)
- {
- ifs_FindComponents(b1, &curdir, &curfile);
- ifs_FindComponents(b2, &newdir, &newfile);
- newdir = b3;
- uc_close(fid);
- code = cm_NameI(cm_data.rootSCachep, curdir, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, ROOTPATH, &req, &dscp1);
- }
- if (!code)
- {
- if (!strcmp(curdir, newdir))
- {
- dscp2 = dscp1;
- dscp1->refCount++;
- }
- else
- code = cm_NameI(cm_data.rootSCachep, newdir, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, ROOTPATH, &req, &dscp2);
- if (!code)
- {
- code = cm_Rename(dscp1, curfile, dscp2, newfile, userp, &req);
- if (!code)
- {
- strcat(b3, "\\");
- strcat(b3, b2);
- mbstowcs(b3_w, b3, MAX_PATH);
- uc_namei(b3_w, new_fid);
- }
- else
- {
- code = uc_namei(curr, new_fid);
- }
- ifs_InternalClose(&dscp2);
- }
- else
- {
- code = uc_namei(curr, new_fid);
- }
- ifs_InternalClose(&dscp1);
- }
-
- MAP_RETURN(code);
- return 0;
- }
-
- uc_flush(ULONG fid)
- {
- ULONG code;
- cm_scache_t *scp;
- cm_req_t req;
-
- scp = ifs_FindScp(fid);
- if (!scp)
- return IFSL_BAD_INPUT;
-
- cm_InitReq(&req);
- code = cm_FSync(scp, userp, &req);
-
- MAP_RETURN(code);
- return 0;
- }
-
- ifs_ReaddirCallback(cm_scache_t *scp, cm_dirEntry_t *entry, void *param, osi_hyper_t *offset)
- {
- readdir_context_t *context;
- ULONG name_len;
- readdir_data_t *info;
- char short_name[14], *endp;
- ULONG code;
- cm_req_t req;
- cm_scache_t *child_scp;
- cm_fid_t child_fid;
- int t;
-
- context = param;
-
- name_len = (ULONG) strlen(entry->name);
-
- info = (readdir_data_t *)context->buf_pos;
- if (context->length - (context->buf_pos - context->buf) < sizeof(readdir_data_t) + name_len * sizeof(WCHAR) + sizeof(LARGE_INTEGER))
- {
- if (context->count == 0)
- return CM_ERROR_BUFFERTOOSMALL;
- info->cookie = *offset;
- return CM_ERROR_STOPNOW;
- }
-
- if ((context->matchString && context->matchString[0] && (!strcmp(context->matchString, entry->name) || context->matchString[0]=='*')) ||
- !(context->matchString && context->matchString[0]))
- ;
- else
- return 0;
-
- cm_InitReq(&req);
- cm_HoldUser(userp);
- child_scp = NULL;
-
- child_fid.cell = scp->fid.cell;
- child_fid.volume = scp->fid.volume;
- child_fid.vnode = ntohl(entry->fid.vnode);
- child_fid.unique = ntohl(entry->fid.unique);
- code = cm_GetSCache(&child_fid, &child_scp, userp, &req);
- if (code || !child_scp)
- {
- cm_ReleaseUser(userp);
- return 0;
- }
-
- {
- lock_ObtainMutex(&child_scp->mx);
- code = cm_SyncOp(child_scp, NULL, userp, &req, 0, CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK);
- lock_ReleaseMutex(&child_scp->mx);
- }
-
- if (code) /* perhaps blank fields we do not know, and continue. bad filents should not prevent readdirs. */
- ;
-
- info->cookie = *offset;
-
- lock_ObtainMutex(&(child_scp->mx));
- code = ifs_CopyInfo(child_scp, &info->attribs, &info->size, &info->creation, &info->access, &info->change, &info->write);
- #if 0
- /* make files we do not have write access to read-only */
- /* this is a handy feature, but it takes a lot of time and traffic to enumerate */
- ifs_CheckAcl(child_scp, FILE_WRITE_DATA, &gr); /* perhaps add flag to not loop, to avoid network traffic if not found*/
- if (gr & FILE_READ_DATA && !(gr & FILE_WRITE_DATA))
- info->attribs |= FILE_ATTRIBUTE_READONLY;
- #endif
- lock_ReleaseMutex(&(child_scp->mx));
- ifs_InternalClose(&child_scp);
- MAP_RETURN(code);
-
- cm_Gen8Dot3Name(entry, short_name, &endp);
- *endp = '\0';
- info->short_name_length = (CCHAR)sizeof(WCHAR)*((t=MultiByteToWideChar(CP_UTF8, 0, short_name, -1, info->short_name, 14))?t-1:0);
- info->name_length = sizeof(WCHAR)*((t=MultiByteToWideChar(CP_UTF8, 0, entry->name, -1, info->name, 600))?t-1:0);
-
- context->buf_pos = ((char*)info) + sizeof(readdir_data_t) + info->name_length;
- context->count++;
-
- info = (readdir_data_t *)context->buf_pos;
- info->cookie.QuadPart = -1;
-
- return 0;
- }
-
- long uc_readdir(ULONG fid, LARGE_INTEGER cookie_in, WCHAR *filter, ULONG *count, char *data, ULONG_PTR *len)
- {
- ULONG code;
- char buffer[2048];
- cm_req_t req;
- cm_scache_t *scp;
- readdir_context_t context;
- LARGE_INTEGER cookie;
-
- if (cookie_in.QuadPart == -1)
- {
- *len = 0;
- *count = 0;
- return 0;
- }
-
- scp = ifs_FindScp(fid);
- if (!scp)
- return IFSL_BAD_INPUT;
- code = ifs_ConvertFileName(filter, -1, buffer, 2048);
- if (code)
- return code;
-
- cm_InitReq(&req);
- cm_HoldUser(userp);
-
- cookie = cookie_in;
- context.matchString = buffer;
- context.buf_pos = context.buf = data;
- context.length = *len;
- context.count = 0;
- *count = 0;
-
- ((LARGE_INTEGER *)context.buf)->QuadPart = -1;
-
- code = cm_ApplyDir(scp, ifs_ReaddirCallback, &context, &cookie, userp, &req, NULL);
-
- context.buf_pos += sizeof(LARGE_INTEGER);
-
- *count = context.count;
-
- cm_ReleaseUser(userp);
- *len = context.buf_pos - context.buf;
-
- code = ifs_MapCmError(code);
- return code;
- }
-
- long uc_close(ULONG fid)
- {
- cm_scache_t *scp;
- cm_req_t req;
- scp_status_t *prev, *curr;
-
- scp = ifs_FindScp(fid);
- if (!scp)
- return IFSL_BAD_INPUT;
-
- cm_InitReq(&req);
- cm_FSync(scp, userp, &req);
-
- SCPL_LOCK; /* perhaps this should be earlier */
-
- lock_ObtainMutex(&(scp->mx));
- cm_ReleaseSCache(scp);
- lock_ReleaseMutex(&(scp->mx));
-
- prev = NULL, curr = scp_list_head;
-
- while (curr)
- {
- if (curr->fid == fid)
- {
- if (prev)
- prev->next = curr->next;
- else
- scp_list_head = curr->next;
- free(curr);
- break;
- }
- prev = curr;
- curr = curr->next;
- }
-
- SCPL_UNLOCK;
-
- return 0;
- }
-
- long uc_unlink(WCHAR *name)
- {
- char buffer[2048];
- long code;
- cm_scache_t *dscp;
- char *dirp, *filep;
- unsigned char removed;
- cm_req_t req;
-
- cm_InitReq(&req);
-
- code = ifs_ConvertFileName(name, -1, buffer, 2048);
- MAP_RETURN(code);
- removed = ifs_FindComponents(buffer, &dirp, &filep);
-
- if (!(*filep))
- return IFSL_BADFILENAME;
-
- code = cm_NameI(cm_data.rootSCachep, dirp, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, ROOTPATH, &req, &dscp);
- MAP_RETURN(code);
-
- code = cm_Unlink(dscp, filep, userp, &req);
- if (code)
- code = cm_RemoveDir(dscp, filep, userp, &req);
-
- cm_ReleaseSCache(dscp);
- MAP_RETURN(code);
-
- return 0;
- }
-
-
- long uc_ioctl_write(ULONG length, char *data, ULONG_PTR *key)
- {
- smb_ioctl_t *iop;
-
- iop = malloc(sizeof(smb_ioctl_t));
- memset(iop, 0, sizeof(smb_ioctl_t));
- smb_IoctlPrepareWrite(NULL, iop);
-
- memcpy(iop->inDatap + iop->inCopied, data, length);
- iop->inCopied += length;
- *key = (ULONG_PTR)iop;
-
- return 0;
- }
-
- long uc_ioctl_read(ULONG_PTR key, ULONG *length, char *data)
- {
- smb_ioctl_t *iop;
-
- iop = (smb_ioctl_t *)key;
- osi_assert(iop);
-
- cm_HoldUser(userp);
- smb_IoctlPrepareRead(NULL, iop, userp);
- cm_ReleaseUser(userp);
-
- *length = iop->outDatap - iop->outAllocp;
- memcpy(data, iop->outAllocp, *length);
- free(iop);
-
- return 0;
- }
-
- int ifs_Init(char **reason)
- {
- HANDLE kcom;
-
- kcom = CreateFile("\\\\.\\afscom\\upcallhook", GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
- 0, NULL);
- if (kcom == INVALID_HANDLE_VALUE)
- {
- *reason = "error creating communications file";
- return CM_ERROR_REMOTECONN;
- }
- CloseHandle(kcom);
-
- memset(user_map, 0, MAX_AFS_USERS*sizeof(struct user_map_entry));
- InitializeCriticalSection(&mapLock);
- InitializeCriticalSection(&scp_list_lock);
-
- return 0;
- }
-
- ifs_TransactRpc(char *outbuf, int outlen, char *inbuf, int *inlen)
- {
- HANDLE hf;
- DWORD read = 0;
- DWORD inmax;
-
- if (!outbuf || !inbuf)
- return IFSL_GENERIC_FAILURE;
-
- hf = CreateFile("\\\\.\\afscom\\downcall", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
- if (hf == INVALID_HANDLE_VALUE)
- return 0;
-
- inmax = *inlen;
- if (!DeviceIoControl(hf, IOCTL_AFSRDR_DOWNCALL, outbuf, outlen, inbuf, inmax, inlen, NULL))
- {
- CloseHandle(hf);
- return IFSL_GENERIC_FAILURE;
- }
-
- CloseHandle(hf);
- return inlen ? IFSL_SUCCESS : IFSL_GENERIC_FAILURE;
- }
-
-
- DWORD WINAPI ifs_MainLoop(LPVOID param)
- {
- HANDLE pipe;
- DWORD written;
- unsigned char *bufIn, *bufOut;
- DWORD lenIn;
- rpc_t rpc;
- BOOL st;
-
- bufIn = VirtualAlloc(NULL, TRANSFER_BUF_SIZE, MEM_COMMIT, PAGE_READWRITE);
- bufOut = VirtualAlloc(NULL, TRANSFER_BUF_SIZE, MEM_COMMIT, PAGE_READWRITE);
- if (!bufIn || !bufOut)
- {
- if (bufIn) VirtualFree(bufIn, 0, MEM_RELEASE);
- if (bufOut) VirtualFree(bufOut, 0, MEM_RELEASE);
- osi_panic("ifs: allocate transfer buffers", __FILE__, __LINE__);
- }
-
- pipe = CreateFile("\\\\.\\afscom\\upcallhook", GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
- 0, NULL);
- if (pipe == INVALID_HANDLE_VALUE)
- {
- VirtualFree(bufIn, 0, MEM_RELEASE);
- VirtualFree(bufOut, 0, MEM_RELEASE);
- osi_panic("ifs: creating communications handle", __FILE__, __LINE__);
- }
-
- while (1)
- {
- /* just check if the event is already signalled, do not wait */
- if (WaitForSingleObject(WaitToTerminate, 0) == WAIT_OBJECT_0)
- break;
-
- /* read request... */
- st = ReadFile(pipe, bufIn, TRANSFER_BUF_SIZE, &lenIn, NULL);
- if (!st) {
- if (GetLastError() == ERROR_INVALID_HANDLE)
- break;
- else
- continue;
- }
-
- ZeroMemory(&rpc, sizeof(rpc));
- rpc.in_buf = rpc.in_pos = bufIn;
- rpc.out_buf = rpc.out_pos = bufOut;
-
- /* ...process it... */
- rpc_parse(&rpc);
-
- /* ...and write it back */
- st = WriteFile(pipe, rpc.out_buf, rpc.out_pos - rpc.out_buf, &written, NULL);
- if (!st)
- if (GetLastError() == ERROR_INVALID_HANDLE)
- break;
- else
- continue;
- }
-
- return (DWORD)1;
- }
--- 0 ----
Index: openafs/src/WINNT/afsd/afsdifs.h
diff -c openafs/src/WINNT/afsd/afsdifs.h:1.1 openafs/src/WINNT/afsd/afsdifs.h:removed
*** openafs/src/WINNT/afsd/afsdifs.h:1.1 Wed Jun 15 12:51:45 2005
--- openafs/src/WINNT/afsd/afsdifs.h Sat Mar 22 21:01:32 2008
***************
*** 1,33 ****
- /* copyright (c) 2005
- * the regents of the university of michigan
- * all rights reserved
- *
- * permission is granted to use, copy, create derivative works and
- * redistribute this software and such derivative works for any purpose,
- * so long as the name of the university of michigan is not used in
- * any advertising or publicity pertaining to the use or distribution
- * of this software without specific, written prior authorization. if
- * the above copyright notice or any other identification of the
- * university of michigan is included in any copy of any portion of
- * this software, then the disclaimer below must also be included.
- *
- * this software is provided as is, without representation from the
- * university of michigan as to its fitness for any purpose, and without
- * warranty by the university of michigan of any kind, either express
- * or implied, including without limitation the implied warranties of
- * merchantability and fitness for a particular purpose. the regents
- * of the university of michigan shall not be liable for any damages,
- * including special, indirect, incidental, or consequential damages,
- * with respect to any claim arising out or in connection with the use
- * of the software, even if it has been or is hereafter advised of the
- * possibility of such damages.
- */
-
- int ifs_Init(char **reason);
- DWORD WINAPI ifs_MainLoop(LPVOID);
-
-
- long ReadData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op,
- cm_user_t *userp, long *readp);
- long WriteData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op,
- cm_user_t *userp, long *readp);
--- 0 ----
Index: openafs/src/WINNT/afsd/cm.h
diff -c openafs/src/WINNT/afsd/cm.h:1.17.2.11 openafs/src/WINNT/afsd/cm.h:1.17.2.13
*** openafs/src/WINNT/afsd/cm.h:1.17.2.11 Fri Feb 8 21:32:19 2008
--- openafs/src/WINNT/afsd/cm.h Thu Mar 13 00:39:17 2008
***************
*** 90,97 ****
#define CM_ERROR_BPLUS_NOMATCH (CM_ERROR_BASE+55)
#define CM_ERROR_EAS_NOT_SUPPORTED (CM_ERROR_BASE+56)
#define CM_ERROR_RANGE_NOT_LOCKED (CM_ERROR_BASE+57)
! /* Used by cm_FollowMountPoint and cm_GetVolumeByName */
#define RWVOL 0
#define ROVOL 1
#define BACKVOL 2
--- 90,99 ----
#define CM_ERROR_BPLUS_NOMATCH (CM_ERROR_BASE+55)
#define CM_ERROR_EAS_NOT_SUPPORTED (CM_ERROR_BASE+56)
#define CM_ERROR_RANGE_NOT_LOCKED (CM_ERROR_BASE+57)
+ #define CM_ERROR_NOSUCHDEVICE (CM_ERROR_BASE+58)
+ #define CM_ERROR_LOCK_NOT_GRANTED (CM_ERROR_BASE+59)
! /* Used by cm_FollowMountPoint and cm_FindVolumeByName */
#define RWVOL 0
#define ROVOL 1
#define BACKVOL 2
Index: openafs/src/WINNT/afsd/cm_access.c
diff -c openafs/src/WINNT/afsd/cm_access.c:1.7.2.17 openafs/src/WINNT/afsd/cm_access.c:1.7.2.18
*** openafs/src/WINNT/afsd/cm_access.c:1.7.2.17 Sun Feb 24 01:28:57 2008
--- openafs/src/WINNT/afsd/cm_access.c Sun Mar 2 23:25:40 2008
***************
*** 59,65 ****
if (!aclScp)
return 0;
if (aclScp != scp) {
! code = lock_TryMutex(&aclScp->mx);
if (code == 0) {
/* can't get lock safely and easily */
cm_ReleaseSCache(aclScp);
--- 59,65 ----
if (!aclScp)
return 0;
if (aclScp != scp) {
! code = lock_TryRead(&aclScp->rw);
if (code == 0) {
/* can't get lock safely and easily */
cm_ReleaseSCache(aclScp);
***************
*** 69,75 ****
/* check that we have a callback, too */
if (!cm_HaveCallback(aclScp)) {
/* can't use it */
! lock_ReleaseMutex(&aclScp->mx);
cm_ReleaseSCache(aclScp);
return 0;
}
--- 69,75 ----
/* check that we have a callback, too */
if (!cm_HaveCallback(aclScp)) {
/* can't use it */
! lock_ReleaseRead(&aclScp->rw);
cm_ReleaseSCache(aclScp);
return 0;
}
***************
*** 78,84 ****
release = 1;
}
! lock_AssertMutex(&aclScp->mx);
/* now if rights is a subset of the public rights, we're done.
* Otherwise, if we an explicit acl entry, we're also in good shape,
--- 78,84 ----
release = 1;
}
! lock_AssertAny(&aclScp->rw);
/* now if rights is a subset of the public rights, we're done.
* Otherwise, if we an explicit acl entry, we're also in good shape,
***************
*** 139,145 ****
done:
if (didLock)
! lock_ReleaseMutex(&aclScp->mx);
if (release)
cm_ReleaseSCache(aclScp);
return code;
--- 139,145 ----
done:
if (didLock)
! lock_ReleaseRead(&aclScp->rw);
if (release)
cm_ReleaseSCache(aclScp);
return code;
***************
*** 175,197 ****
} else {
/* not a dir, use parent dir's acl */
cm_SetFid(&tfid, scp->fid.cell, scp->fid.volume, scp->parentVnode, scp->parentUnique);
! lock_ReleaseMutex(&scp->mx);
code = cm_GetSCache(&tfid, &aclScp, userp, reqp);
if (code) {
! lock_ObtainMutex(&scp->mx);
goto _done;
}
osi_Log2(afsd_logp, "GetAccess parent scp %x user %x", aclScp, userp);
! lock_ObtainMutex(&aclScp->mx);
code = cm_SyncOp(aclScp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_FORCECB);
if (!code)
cm_SyncOpDone(aclScp, NULL,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
! lock_ReleaseMutex(&aclScp->mx);
cm_ReleaseSCache(aclScp);
! lock_ObtainMutex(&scp->mx);
}
_done:
--- 175,197 ----
} else {
/* not a dir, use parent dir's acl */
cm_SetFid(&tfid, scp->fid.cell, scp->fid.volume, scp->parentVnode, scp->parentUnique);
! lock_ReleaseWrite(&scp->rw);
code = cm_GetSCache(&tfid, &aclScp, userp, reqp);
if (code) {
! lock_ObtainWrite(&scp->rw);
goto _done;
}
osi_Log2(afsd_logp, "GetAccess parent scp %x user %x", aclScp, userp);
! lock_ObtainWrite(&aclScp->rw);
code = cm_SyncOp(aclScp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_FORCECB);
if (!code)
cm_SyncOpDone(aclScp, NULL,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
! lock_ReleaseWrite(&aclScp->rw);
cm_ReleaseSCache(aclScp);
! lock_ObtainWrite(&scp->rw);
}
_done:
Index: openafs/src/WINNT/afsd/cm_aclent.c
diff -c openafs/src/WINNT/afsd/cm_aclent.c:1.14.2.3 openafs/src/WINNT/afsd/cm_aclent.c:1.14.2.4
*** openafs/src/WINNT/afsd/cm_aclent.c:1.14.2.3 Tue Feb 5 12:11:45 2008
--- openafs/src/WINNT/afsd/cm_aclent.c Sun Mar 2 23:25:40 2008
***************
*** 41,47 ****
/*
* Remove the entry from the vnode's list
*/
! lock_AssertMutex(&aclp->backp->mx);
laclpp = &aclp->backp->randomACLp;
for (taclp = *laclpp; taclp; laclpp = &taclp->nextp, taclp = *laclpp) {
if (taclp == aclp)
--- 41,47 ----
/*
* Remove the entry from the vnode's list
*/
! lock_AssertWrite(&aclp->backp->rw);
laclpp = &aclp->backp->randomACLp;
for (taclp = *laclpp; taclp; laclpp = &taclp->nextp, taclp = *laclpp) {
if (taclp == aclp)
***************
*** 129,141 ****
if (aclp->backp && scp != aclp->backp) {
ascp = aclp->backp;
lock_ReleaseWrite(&cm_aclLock);
! lock_ObtainMutex(&ascp->mx);
lock_ObtainWrite(&cm_aclLock);
}
CleanupACLEnt(aclp);
if (ascp)
! lock_ReleaseMutex(&ascp->mx);
return aclp;
}
--- 129,141 ----
if (aclp->backp && scp != aclp->backp) {
ascp = aclp->backp;
lock_ReleaseWrite(&cm_aclLock);
! lock_ObtainWrite(&ascp->rw);
lock_ObtainWrite(&cm_aclLock);
}
CleanupACLEnt(aclp);
if (ascp)
! lock_ReleaseWrite(&ascp->rw);
return aclp;
}
Index: openafs/src/WINNT/afsd/cm_buf.c
diff -c openafs/src/WINNT/afsd/cm_buf.c:1.31.2.28 openafs/src/WINNT/afsd/cm_buf.c:1.31.2.36
*** openafs/src/WINNT/afsd/cm_buf.c:1.31.2.28 Sat Feb 23 16:14:19 2008
--- openafs/src/WINNT/afsd/cm_buf.c Thu Mar 6 20:14:13 2008
***************
*** 130,139 ****
* double check that the refCount is actually zero
* before we remove the buffer from the LRU queue.
*/
! if (!writeLocked) {
! lock_ReleaseRead(&buf_globalLock);
! lock_ObtainWrite(&buf_globalLock);
! }
if (bp->refCount == 0 &&
!(bp->flags & CM_BUF_INLRU)) {
--- 130,137 ----
* double check that the refCount is actually zero
* before we remove the buffer from the LRU queue.
*/
! if (!writeLocked)
! lock_ConvertRToW(&buf_globalLock);
if (bp->refCount == 0 &&
!(bp->flags & CM_BUF_INLRU)) {
***************
*** 145,154 ****
bp->flags |= CM_BUF_INLRU;
}
! if (!writeLocked) {
! lock_ReleaseWrite(&buf_globalLock);
! lock_ObtainRead(&buf_globalLock);
! }
}
}
--- 143,150 ----
bp->flags |= CM_BUF_INLRU;
}
! if (!writeLocked)
! lock_ConvertWToR(&buf_globalLock);
}
}
***************
*** 204,214 ****
/* now go through our percentage of the buffers */
for (bpp = &cm_data.buf_dirtyListp; bp = *bpp; ) {
-
/* all dirty buffers are held when they are added to the
* dirty list. No need for an additional hold.
*/
!
if (bp->flags & CM_BUF_DIRTY) {
/* start cleaning the buffer; don't touch log pages since
* the log code counts on knowing exactly who is writing
--- 200,209 ----
/* now go through our percentage of the buffers */
for (bpp = &cm_data.buf_dirtyListp; bp = *bpp; ) {
/* all dirty buffers are held when they are added to the
* dirty list. No need for an additional hold.
*/
! lock_ObtainMutex(&bp->mx);
if (bp->flags & CM_BUF_DIRTY) {
/* start cleaning the buffer; don't touch log pages since
* the log code counts on knowing exactly who is writing
***************
*** 216,248 ****
*/
cm_InitReq(&req);
req.flags |= CM_REQ_NORETRY;
! wasDirty |= buf_CleanAsync(bp, &req);
}
/* the buffer may or may not have been dirty
* and if dirty may or may not have been cleaned
* successfully. check the dirty flag again.
*/
! if (!(bp->flags & CM_BUF_DIRTY)) {
! lock_ObtainMutex(&bp->mx);
! if (!(bp->flags & CM_BUF_DIRTY)) {
! /* remove the buffer from the dirty list */
! lock_ObtainWrite(&buf_globalLock);
! *bpp = bp->dirtyp;
! bp->dirtyp = NULL;
! if (cm_data.buf_dirtyListp == NULL)
! cm_data.buf_dirtyListEndp = NULL;
! buf_ReleaseLocked(bp, TRUE);
! lock_ReleaseWrite(&buf_globalLock);
! } else {
! /* advance the pointer so we don't loop forever */
! bpp = &bp->dirtyp;
! }
! lock_ReleaseMutex(&bp->mx);
! } else {
! /* advance the pointer so we don't loop forever */
! bpp = &bp->dirtyp;
! }
} /* for loop over a bunch of buffers */
} /* whole daemon's while loop */
}
--- 211,237 ----
*/
cm_InitReq(&req);
req.flags |= CM_REQ_NORETRY;
! wasDirty |= buf_CleanAsyncLocked(bp, &req);
}
/* the buffer may or may not have been dirty
* and if dirty may or may not have been cleaned
* successfully. check the dirty flag again.
*/
! if (!(bp->flags & CM_BUF_DIRTY)) {
! /* remove the buffer from the dirty list */
! lock_ObtainWrite(&buf_globalLock);
! *bpp = bp->dirtyp;
! bp->dirtyp = NULL;
! if (cm_data.buf_dirtyListp == NULL)
! cm_data.buf_dirtyListEndp = NULL;
! buf_ReleaseLocked(bp, TRUE);
! lock_ReleaseWrite(&buf_globalLock);
! } else {
! /* advance the pointer so we don't loop forever */
! bpp = &bp->dirtyp;
! }
! lock_ReleaseMutex(&bp->mx);
} /* for loop over a bunch of buffers */
} /* whole daemon's while loop */
}
***************
*** 571,582 ****
release = 1;
}
if ( scp ) {
! lock_ObtainMutex(&scp->mx);
if (scp->flags & CM_SCACHEFLAG_WAITING) {
osi_Log1(buf_logp, "buf_WaitIO waking scp 0x%p", scp);
osi_Wakeup((LONG_PTR)&scp->flags);
}
! lock_ReleaseMutex(&scp->mx);
}
}
--- 560,571 ----
release = 1;
}
if ( scp ) {
! lock_ObtainRead(&scp->rw);
if (scp->flags & CM_SCACHEFLAG_WAITING) {
osi_Log1(buf_logp, "buf_WaitIO waking scp 0x%p", scp);
osi_Wakeup((LONG_PTR)&scp->flags);
}
! lock_ReleaseRead(&scp->rw);
}
}
***************
*** 657,663 ****
offset = bp->offset;
LargeIntegerAdd(offset, ConvertLongToLargeInteger(bp->dirty_offset));
! code = (*cm_buf_opsp->Writep)(scp, &offset, bp->dirty_length, 0, bp->userp, reqp);
osi_Log3(buf_logp, "buf_CleanAsyncLocked I/O on scp 0x%p buf 0x%p, done=%d", scp, bp, code);
cm_ReleaseSCache(scp);
--- 646,661 ----
offset = bp->offset;
LargeIntegerAdd(offset, ConvertLongToLargeInteger(bp->dirty_offset));
! code = (*cm_buf_opsp->Writep)(scp, &offset,
! #if 1
! /* we might as well try to write all of the contiguous
! * dirty buffers in one RPC
! */
! cm_chunkSize,
! #else
! bp->dirty_length,
! #endif
! 0, bp->userp, reqp);
osi_Log3(buf_logp, "buf_CleanAsyncLocked I/O on scp 0x%p buf 0x%p, done=%d", scp, bp, code);
cm_ReleaseSCache(scp);
***************
*** 678,684 ****
bp->dirty_offset = 0;
bp->dirty_length = 0;
bp->error = code;
! bp->dataVersion = -1; /* bad */
bp->dirtyCounter++;
}
--- 676,682 ----
bp->dirty_offset = 0;
bp->dirty_length = 0;
bp->error = code;
! bp->dataVersion = CM_BUF_VERSION_BAD; /* bad */
bp->dirtyCounter++;
}
***************
*** 775,786 ****
bp->flags &= ~CM_BUF_INHASH;
}
- /* bump the soft reference counter now, to invalidate softRefs; no
- * wakeup is required since people don't sleep waiting for this
- * counter to change.
- */
- bp->idCounter++;
-
/* make the fid unrecognizable */
memset(&bp->fid, 0, sizeof(cm_fid_t));
}
--- 773,778 ----
***************
*** 914,920 ****
/* clean up junk flags */
bp->flags &= ~(CM_BUF_EOF | CM_BUF_ERROR);
! bp->dataVersion = -1; /* unknown so far */
/* now hash in as our new buffer, and give it the
* appropriate label, if requested.
--- 906,912 ----
/* clean up junk flags */
bp->flags &= ~(CM_BUF_EOF | CM_BUF_ERROR);
! bp->dataVersion = CM_BUF_VERSION_BAD; /* unknown so far */
/* now hash in as our new buffer, and give it the
* appropriate label, if requested.
***************
*** 1196,1202 ****
* has been invalidate (by having its DV stomped upon), then
* count it as free, since it isn't really being utilized.
*/
! if (!(bufp->flags & CM_BUF_INHASH) || bufp->dataVersion <= 0)
count++;
}
lock_ReleaseRead(&buf_globalLock);
--- 1188,1194 ----
* has been invalidate (by having its DV stomped upon), then
* count it as free, since it isn't really being utilized.
*/
! if (!(bufp->flags & CM_BUF_INHASH) || bufp->dataVersion == CM_BUF_VERSION_BAD)
count++;
}
lock_ReleaseRead(&buf_globalLock);
***************
*** 1217,1231 ****
}
/* wait for a buffer's cleaning to finish */
! void buf_CleanWait(cm_scache_t * scp, cm_buf_t *bp)
{
osi_assertx(bp->magic == CM_BUF_MAGIC, "invalid cm_buf_t magic");
! lock_ObtainMutex(&bp->mx);
if (bp->flags & CM_BUF_WRITING) {
buf_WaitIO(scp, bp);
}
! lock_ReleaseMutex(&bp->mx);
}
/* set the dirty flag on a buffer, and set associated write-ahead log,
--- 1209,1225 ----
}
/* wait for a buffer's cleaning to finish */
! void buf_CleanWait(cm_scache_t * scp, cm_buf_t *bp, afs_uint32 locked)
{
osi_assertx(bp->magic == CM_BUF_MAGIC, "invalid cm_buf_t magic");
! if (!locked)
! lock_ObtainMutex(&bp->mx);
if (bp->flags & CM_BUF_WRITING) {
buf_WaitIO(scp, bp);
}
! if (!locked)
! lock_ReleaseMutex(&bp->mx);
}
/* set the dirty flag on a buffer, and set associated write-ahead log,
***************
*** 1331,1337 ****
req.flags |= CM_REQ_NORETRY;
buf_CleanAsync(bp, &req);
! buf_CleanWait(NULL, bp);
/* relock and release buffer */
lock_ObtainRead(&buf_globalLock);
--- 1325,1331 ----
req.flags |= CM_REQ_NORETRY;
buf_CleanAsync(bp, &req);
! buf_CleanWait(NULL, bp, FALSE);
/* relock and release buffer */
lock_ObtainRead(&buf_globalLock);
***************
*** 1442,1448 ****
LargeIntegerLessThan(*sizep, bufEnd)) {
buf_WaitIO(scp, bufp);
}
! lock_ObtainMutex(&scp->mx);
/* make sure we have a callback (so we have the right value for
* the length), and wait for it to be safe to do a truncate.
--- 1436,1442 ----
LargeIntegerLessThan(*sizep, bufEnd)) {
buf_WaitIO(scp, bufp);
}
! lock_ObtainWrite(&scp->rw);
/* make sure we have a callback (so we have the right value for
* the length), and wait for it to be safe to do a truncate.
***************
*** 1472,1478 ****
bufp->flags &= ~CM_BUF_DIRTY;
bufp->dirty_offset = 0;
bufp->dirty_length = 0;
! bufp->dataVersion = -1; /* known bad */
bufp->dirtyCounter++;
}
else {
--- 1466,1472 ----
bufp->flags &= ~CM_BUF_DIRTY;
bufp->dirty_offset = 0;
bufp->dirty_length = 0;
! bufp->dataVersion = CM_BUF_VERSION_BAD; /* known bad */
bufp->dirtyCounter++;
}
else {
***************
*** 1495,1501 ****
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS
| CM_SCACHESYNC_SETSIZE | CM_SCACHESYNC_BUFLOCKED);
! lock_ReleaseMutex(&scp->mx);
lock_ReleaseMutex(&bufp->mx);
if (!code) {
--- 1489,1495 ----
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS
| CM_SCACHESYNC_SETSIZE | CM_SCACHESYNC_BUFLOCKED);
! lock_ReleaseWrite(&scp->rw);
lock_ReleaseMutex(&bufp->mx);
if (!code) {
***************
*** 1552,1570 ****
if (code && code != CM_ERROR_BADFD)
goto skip;
! /* if the scp's FID is bad its because we received VNOVNODE
! * when attempting to FetchStatus before the write. This
! * page therefore contains data that can no longer be stored.
! */
! lock_ObtainMutex(&bp->mx);
! bp->flags &= ~CM_BUF_DIRTY;
! bp->flags |= CM_BUF_ERROR;
! bp->error = code;
! bp->dirty_offset = 0;
! bp->dirty_length = 0;
! bp->dataVersion = -1; /* known bad */
! bp->dirtyCounter++;
! lock_ReleaseMutex(&bp->mx);
/* actually, we only know that buffer is clean if ref
* count is 1, since we don't have buffer itself locked.
--- 1546,1566 ----
if (code && code != CM_ERROR_BADFD)
goto skip;
! if (code == CM_ERROR_BADFD) {
! /* if the scp's FID is bad its because we received VNOVNODE
! * when attempting to FetchStatus before the write. This
! * page therefore contains data that can no longer be stored.
! */
! lock_ObtainMutex(&bp->mx);
! bp->flags &= ~CM_BUF_DIRTY;
! bp->flags |= CM_BUF_ERROR;
! bp->error = CM_ERROR_BADFD;
! bp->dirty_offset = 0;
! bp->dirty_length = 0;
! bp->dataVersion = CM_BUF_VERSION_BAD; /* known bad */
! bp->dirtyCounter++;
! lock_ReleaseMutex(&bp->mx);
! }
/* actually, we only know that buffer is clean if ref
* count is 1, since we don't have buffer itself locked.
***************
*** 1582,1588 ****
lock_ReleaseWrite(&buf_globalLock);
}
! if (code != CM_ERROR_BADFD)
(*cm_buf_opsp->Unstabilizep)(scp, userp);
}
--- 1578,1584 ----
lock_ReleaseWrite(&buf_globalLock);
}
! if (code == 0)
(*cm_buf_opsp->Unstabilizep)(scp, userp);
}
***************
*** 1605,1618 ****
return code;
}
! /* Must be called with scp->mx held */
long buf_ForceDataVersion(cm_scache_t * scp, afs_uint64 fromVersion, afs_uint64 toVersion)
{
cm_buf_t * bp;
afs_uint32 i;
int found = 0;
! lock_AssertMutex(&scp->mx);
i = BUF_FILEHASH(&scp->fid);
--- 1601,1614 ----
return code;
}
! /* Must be called with scp->rw held */
long buf_ForceDataVersion(cm_scache_t * scp, afs_uint64 fromVersion, afs_uint64 toVersion)
{
cm_buf_t * bp;
afs_uint32 i;
int found = 0;
! lock_AssertAny(&scp->rw);
i = BUF_FILEHASH(&scp->fid);
***************
*** 1652,1672 ****
for (; bp; bp = nbp) {
/* clean buffer synchronously */
if (cm_FidCmp(&bp->fid, &scp->fid) == 0) {
- if (userp) {
- cm_HoldUser(userp);
- lock_ObtainMutex(&bp->mx);
- if (bp->userp)
- cm_ReleaseUser(bp->userp);
- bp->userp = userp;
- lock_ReleaseMutex(&bp->mx);
- }
- wasDirty = buf_CleanAsync(bp, reqp);
- buf_CleanWait(scp, bp);
lock_ObtainMutex(&bp->mx);
! if (bp->flags & CM_BUF_ERROR) {
! code = bp->error;
! if (code == 0)
! code = -1;
}
lock_ReleaseMutex(&bp->mx);
}
--- 1648,1668 ----
for (; bp; bp = nbp) {
/* clean buffer synchronously */
if (cm_FidCmp(&bp->fid, &scp->fid) == 0) {
lock_ObtainMutex(&bp->mx);
! if (bp->flags & CM_BUF_DIRTY) {
! if (userp) {
! cm_HoldUser(userp);
! if (bp->userp)
! cm_ReleaseUser(bp->userp);
! bp->userp = userp;
! }
! wasDirty = buf_CleanAsyncLocked(bp, reqp);
! buf_CleanWait(scp, bp, TRUE);
! if (bp->flags & CM_BUF_ERROR) {
! code = bp->error;
! if (code == 0)
! code = -1;
! }
}
lock_ReleaseMutex(&bp->mx);
}
***************
*** 1853,1859 ****
bp->dirty_length = 0;
bp->flags |= CM_BUF_ERROR;
bp->error = VNOVNODE;
! bp->dataVersion = -1; /* bad */
bp->dirtyCounter++;
if (bp->flags & CM_BUF_WAITING) {
osi_Log2(buf_logp, "BUF CleanDirtyBuffers Waking [scp 0x%x] bp 0x%x", scp, bp);
--- 1849,1855 ----
bp->dirty_length = 0;
bp->flags |= CM_BUF_ERROR;
bp->error = VNOVNODE;
! bp->dataVersion = CM_BUF_VERSION_BAD; /* bad */
bp->dirtyCounter++;
if (bp->flags & CM_BUF_WAITING) {
osi_Log2(buf_logp, "BUF CleanDirtyBuffers Waking [scp 0x%x] bp 0x%x", scp, bp);
Index: openafs/src/WINNT/afsd/cm_buf.h
diff -c openafs/src/WINNT/afsd/cm_buf.h:1.12.4.10 openafs/src/WINNT/afsd/cm_buf.h:1.12.4.13
*** openafs/src/WINNT/afsd/cm_buf.h:1.12.4.10 Sat Feb 23 02:30:18 2008
--- openafs/src/WINNT/afsd/cm_buf.h Sun Mar 2 16:56:18 2008
***************
*** 23,31 ****
/* default buffer size */
#define CM_BUF_BLOCKSIZE CM_CONFIGDEFAULT_BLOCKSIZE
- /* default hash size */
- #define CM_BUF_HASHSIZE 1024
-
/* cache type */
#define CM_BUF_CACHETYPE_FILE 1
#define CM_BUF_CACHETYPE_VIRTUAL 2
--- 23,28 ----
***************
*** 39,49 ****
/* another hash fn */
#define BUF_FILEHASH(fidp) ((fidp)->hash % cm_data.buf_hashSize)
- /* backup over pointer to the buffer */
- #define BUF_OVERTOBUF(op) ((cm_buf_t *)(((char *)op) - ((long)(&((cm_buf_t *)0)->over))))
-
#define CM_BUF_MAGIC ('B' | 'U' <<8 | 'F'<<16 | 'F'<<24)
/* represents a single buffer */
typedef struct cm_buf {
osi_queue_t q; /* queue of all zero-refcount buffers */
--- 36,45 ----
/* another hash fn */
#define BUF_FILEHASH(fidp) ((fidp)->hash % cm_data.buf_hashSize)
#define CM_BUF_MAGIC ('B' | 'U' <<8 | 'F'<<16 | 'F'<<24)
+ #define CM_BUF_VERSION_BAD 0xFFFFFFFFFFFFFFFF
+
/* represents a single buffer */
typedef struct cm_buf {
osi_queue_t q; /* queue of all zero-refcount buffers */
***************
*** 63,75 ****
struct cm_buf *dirtyp; /* next in the dirty list */
osi_mutex_t mx; /* mutex protecting structure except refcount */
afs_int32 refCount; /* reference count (buf_globalLock) */
! long idCounter; /* counter for softrefs; bumped at each recycle */
! long dirtyCounter; /* bumped at each dirty->clean transition */
osi_hyper_t offset; /* offset */
cm_fid_t fid; /* file ID */
afs_uint32 flags; /* flags we're using */
char *datap; /* data in this buffer */
! unsigned long error; /* last error code, if CM_BUF_ERROR is set */
cm_user_t *userp; /* user who wrote to the buffer last */
/* fields added for the CM; locked by scp->mx */
--- 59,70 ----
struct cm_buf *dirtyp; /* next in the dirty list */
osi_mutex_t mx; /* mutex protecting structure except refcount */
afs_int32 refCount; /* reference count (buf_globalLock) */
! afs_uint32 dirtyCounter; /* bumped at each dirty->clean transition */
osi_hyper_t offset; /* offset */
cm_fid_t fid; /* file ID */
afs_uint32 flags; /* flags we're using */
char *datap; /* data in this buffer */
! afs_uint32 error; /* last error code, if CM_BUF_ERROR is set */
cm_user_t *userp; /* user who wrote to the buffer last */
/* fields added for the CM; locked by scp->mx */
***************
*** 102,122 ****
/* waiting is done based on scp->flags. Removing bits from cmFlags
should be followed by waking the scp. */
- /* represents soft reference which is OK to lose on a recycle */
- typedef struct cm_softRef {
- cm_buf_t *bufp; /* buffer (may get reused) */
- long counter; /* counter of changes to identity */
- } cm_softRef_t;
-
#define CM_BUF_READING 1 /* now reading buffer from the disk */
#define CM_BUF_WRITING 2 /* now writing buffer to the disk */
#define CM_BUF_INHASH 4 /* in the hash table */
! #define CM_BUF_DIRTY 8 /* buffer is dirty */
! #define CM_BUF_INLRU 0x10 /* in lru queue */
! #define CM_BUF_ERROR 0x20 /* something went wrong on delayed write */
#define CM_BUF_WAITING 0x40 /* someone's waiting for a flag to change */
! #define CM_BUF_EVWAIT 0x80 /* someone's waiting for the buffer event */
! #define CM_BUF_EOF 0x100 /* read 0 bytes; used for detecting EOF */
typedef struct cm_buf_ops {
long (*Writep)(void *, osi_hyper_t *, long, long, struct cm_user *,
--- 97,111 ----
/* waiting is done based on scp->flags. Removing bits from cmFlags
should be followed by waking the scp. */
#define CM_BUF_READING 1 /* now reading buffer from the disk */
#define CM_BUF_WRITING 2 /* now writing buffer to the disk */
#define CM_BUF_INHASH 4 /* in the hash table */
! #define CM_BUF_DIRTY 8 /* buffer is dirty */
! #define CM_BUF_INLRU 0x10 /* in lru queue */
! #define CM_BUF_ERROR 0x20 /* something went wrong on delayed write */
#define CM_BUF_WAITING 0x40 /* someone's waiting for a flag to change */
!
! #define CM_BUF_EOF 0x100 /* read 0 bytes; used for detecting EOF */
typedef struct cm_buf_ops {
long (*Writep)(void *, osi_hyper_t *, long, long, struct cm_user *,
***************
*** 159,165 ****
extern long buf_CleanAsync(cm_buf_t *, cm_req_t *);
! extern void buf_CleanWait(cm_scache_t *, cm_buf_t *);
extern void buf_SetDirty(cm_buf_t *, afs_uint32 offset, afs_uint32 length);
--- 148,154 ----
extern long buf_CleanAsync(cm_buf_t *, cm_req_t *);
! extern void buf_CleanWait(cm_scache_t *, cm_buf_t *, afs_uint32 locked);
extern void buf_SetDirty(cm_buf_t *, afs_uint32 offset, afs_uint32 length);
Index: openafs/src/WINNT/afsd/cm_callback.c
diff -c openafs/src/WINNT/afsd/cm_callback.c:1.41.4.34 openafs/src/WINNT/afsd/cm_callback.c:1.41.4.41
*** openafs/src/WINNT/afsd/cm_callback.c:1.41.4.34 Fri Feb 22 19:17:34 2008
--- openafs/src/WINNT/afsd/cm_callback.c Wed Mar 19 09:59:30 2008
***************
*** 27,33 ****
#include
#include
- #include <../afsrdr/kif.h>
/*extern void afsi_log(char *pattern, ...);*/
--- 27,32 ----
***************
*** 130,143 ****
/* for directories, this sends a change notification on the dir itself */
if (scp->fileType == CM_SCACHETYPE_DIRECTORY) {
- #ifndef AFSIFS
if (scp->flags & CM_SCACHEFLAG_ANYWATCH)
smb_NotifyChange(0,
FILE_NOTIFY_GENERIC_DIRECTORY_FILTER,
scp, NULL, NULL, TRUE);
- #else
- dc_break_callback(FID_HASH_FN(&scp->fid));
- #endif
} else {
/* and for files, this sends a change notification on the file's parent dir */
cm_fid_t tfid;
--- 129,138 ----
***************
*** 145,160 ****
cm_SetFid(&tfid, scp->fid.cell, scp->fid.volume, scp->parentVnode, scp->parentUnique);
dscp = cm_FindSCache(&tfid);
- #ifndef AFSIFS
if ( dscp &&
dscp->flags & CM_SCACHEFLAG_ANYWATCH )
smb_NotifyChange( 0,
FILE_NOTIFY_GENERIC_FILE_FILTER,
dscp, NULL, NULL, TRUE);
- #else
- if (dscp)
- dc_break_callback(FID_HASH_FN(&dscp->fid));
- #endif
if (dscp)
cm_ReleaseSCache(dscp);
}
--- 140,150 ----
***************
*** 209,217 ****
osi_Log4(afsd_logp, "RevokeCallback Discarding SCache scp 0x%p vol %u vn %u uniq %u",
scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
! lock_ObtainMutex(&scp->mx);
cm_DiscardSCache(scp);
! lock_ReleaseMutex(&scp->mx);
cm_CallbackNotifyChange(scp);
--- 199,207 ----
osi_Log4(afsd_logp, "RevokeCallback Discarding SCache scp 0x%p vol %u vn %u uniq %u",
scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
! lock_ObtainWrite(&scp->rw);
cm_DiscardSCache(scp);
! lock_ReleaseWrite(&scp->rw);
cm_CallbackNotifyChange(scp);
***************
*** 257,276 ****
cm_HoldSCacheNoLock(scp);
lock_ReleaseWrite(&cm_scacheLock);
! lock_ObtainMutex(&scp->mx);
osi_Log4(afsd_logp, "RevokeVolumeCallback Discarding SCache scp 0x%p vol %u vn %u uniq %u",
scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
cm_DiscardSCache(scp);
! lock_ReleaseMutex(&scp->mx);
cm_CallbackNotifyChange(scp);
lock_ObtainWrite(&cm_scacheLock);
cm_ReleaseSCacheNoLock(scp);
!
! if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp) {
! scp->volp->cbExpiresRO = 0;
}
-
}
} /* search one hash bucket */
} /* search all hash buckets */
--- 247,268 ----
cm_HoldSCacheNoLock(scp);
lock_ReleaseWrite(&cm_scacheLock);
! lock_ObtainWrite(&scp->rw);
osi_Log4(afsd_logp, "RevokeVolumeCallback Discarding SCache scp 0x%p vol %u vn %u uniq %u",
scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
cm_DiscardSCache(scp);
! lock_ReleaseWrite(&scp->rw);
cm_CallbackNotifyChange(scp);
lock_ObtainWrite(&cm_scacheLock);
cm_ReleaseSCacheNoLock(scp);
! if (scp->flags & CM_SCACHEFLAG_PURERO) {
! cm_volume_t *volp = cm_GetVolumeByFID(&scp->fid);
! if (volp) {
! volp->cbExpiresRO = 0;
! cm_PutVolume(volp);
! }
}
}
} /* search one hash bucket */
} /* search all hash buckets */
***************
*** 358,366 ****
cm_server_t *tsp = NULL;
cm_cell_t* cellp = NULL;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_ENTER(&callp->lock);
- #endif
if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
host = rx_HostOf(peerp);
port = rx_PortOf(peerp);
--- 350,355 ----
***************
*** 393,401 ****
else
cm_RevokeCallback(callp, cellp, tfidp);
}
- #ifdef HOLD_CALL_MUTEX
- MUTEX_EXIT(&callp->lock);
- #endif
return 0;
}
--- 382,387 ----
***************
*** 435,443 ****
unsigned long host = 0;
unsigned short port = 0;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_ENTER(&callp->lock);
- #endif
if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
host = rx_HostOf(peerp);
port = rx_PortOf(peerp);
--- 421,426 ----
***************
*** 484,490 ****
for (scp=cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) {
cm_HoldSCacheNoLock(scp);
lock_ReleaseWrite(&cm_scacheLock);
! lock_ObtainMutex(&scp->mx);
discarded = 0;
if (scp->cbExpires > 0 && scp->cbServerp != NULL) {
/* we have a callback, now decide if we should clear it */
--- 467,473 ----
for (scp=cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) {
cm_HoldSCacheNoLock(scp);
lock_ReleaseWrite(&cm_scacheLock);
! lock_ObtainWrite(&scp->rw);
discarded = 0;
if (scp->cbExpires > 0 && scp->cbServerp != NULL) {
/* we have a callback, now decide if we should clear it */
***************
*** 495,508 ****
discarded = 1;
}
}
! lock_ReleaseMutex(&scp->mx);
if (discarded)
cm_CallbackNotifyChange(scp);
lock_ObtainWrite(&cm_scacheLock);
cm_ReleaseSCacheNoLock(scp);
! if (discarded && (scp->flags & CM_SCACHEFLAG_PURERO) && scp->volp && scp->volp->cbExpiresRO != 0)
! scp->volp->cbExpiresRO = 0;
} /* search one hash bucket */
} /* search all hash buckets */
--- 478,497 ----
discarded = 1;
}
}
! lock_ReleaseWrite(&scp->rw);
if (discarded)
cm_CallbackNotifyChange(scp);
lock_ObtainWrite(&cm_scacheLock);
cm_ReleaseSCacheNoLock(scp);
! if (discarded && (scp->flags & CM_SCACHEFLAG_PURERO)) {
! cm_volume_t *volp = cm_GetVolumeByFID(&scp->fid);
! if (volp) {
! if (volp->cbExpiresRO != 0)
! volp->cbExpiresRO = 0;
! cm_PutVolume(volp);
! }
! }
} /* search one hash bucket */
} /* search all hash buckets */
***************
*** 518,526 ****
cm_PutServer(tsp);
}
}
- #ifdef HOLD_CALL_MUTEX
- MUTEX_EXIT(&callp->lock);
- #endif
return 0;
}
--- 507,512 ----
***************
*** 552,560 ****
unsigned long host = 0;
unsigned short port = 0;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_ENTER(&callp->lock);
- #endif
if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
host = rx_HostOf(peerp);
port = rx_PortOf(peerp);
--- 538,543 ----
***************
*** 564,572 ****
ntohl(host),
ntohs(port));
- #ifdef HOLD_CALL_MUTEX
- MUTEX_EXIT(&callp->lock);
- #endif
return 0;
}
--- 547,552 ----
***************
*** 597,609 ****
extern osi_rwlock_t cm_aclLock;
extern osi_rwlock_t buf_globalLock;
- extern osi_rwlock_t cm_callbackLock;
extern osi_rwlock_t cm_cellLock;
extern osi_rwlock_t cm_connLock;
extern osi_rwlock_t cm_daemonLock;
extern osi_rwlock_t cm_dnlcLock;
extern osi_rwlock_t cm_scacheLock;
extern osi_rwlock_t cm_serverLock;
extern osi_rwlock_t cm_userLock;
extern osi_rwlock_t cm_utilsLock;
extern osi_rwlock_t cm_volumeLock;
--- 577,589 ----
extern osi_rwlock_t cm_aclLock;
extern osi_rwlock_t buf_globalLock;
extern osi_rwlock_t cm_cellLock;
extern osi_rwlock_t cm_connLock;
extern osi_rwlock_t cm_daemonLock;
extern osi_rwlock_t cm_dnlcLock;
extern osi_rwlock_t cm_scacheLock;
extern osi_rwlock_t cm_serverLock;
+ extern osi_rwlock_t cm_syscfgLock;
extern osi_rwlock_t cm_userLock;
extern osi_rwlock_t cm_utilsLock;
extern osi_rwlock_t cm_volumeLock;
***************
*** 629,634 ****
--- 609,615 ----
{"buf_globalLock", (char*)&buf_globalLock, LOCKTYPE_RW},
{"cm_serverLock", (char*)&cm_serverLock, LOCKTYPE_RW},
{"cm_callbackLock", (char*)&cm_callbackLock, LOCKTYPE_RW},
+ {"cm_syscfgLock", (char*)&cm_syscfgLock, LOCKTYPE_RW},
{"cm_aclLock", (char*)&cm_aclLock, LOCKTYPE_RW},
{"cm_cellLock", (char*)&cm_cellLock, LOCKTYPE_RW},
{"cm_connLock", (char*)&cm_connLock, LOCKTYPE_RW},
***************
*** 661,669 ****
unsigned long host = 0;
unsigned short port = 0;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_ENTER(&callp->lock);
- #endif
if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
host = rx_HostOf(peerp);
port = rx_PortOf(peerp);
--- 642,647 ----
***************
*** 706,714 ****
code = 0;
}
- #ifdef HOLD_CALL_MUTEX
- MUTEX_EXIT(&callp->lock);
- #endif
return code;
}
--- 684,689 ----
***************
*** 724,732 ****
unsigned long host = 0;
unsigned short port = 0;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_ENTER(&callp->lock);
- #endif
if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
host = rx_HostOf(peerp);
port = rx_PortOf(peerp);
--- 699,704 ----
***************
*** 761,778 ****
cep->netFid.Vnode = scp->fid.vnode;
cep->netFid.Unique = scp->fid.unique;
cep->lock.waitStates = 0;
! cep->lock.exclLocked = scp->mx.flags;
cep->lock.readersReading = 0;
! cep->lock.numWaiting = scp->mx.waiters;
cep->lock.pid_last_reader = 0;
cep->lock.pid_writer = 0;
cep->lock.src_indicator = 0;
cep->Length = scp->length.LowPart;
cep->DataVersion = (afs_uint32)(scp->dataVersion & 0xFFFFFFFF);
cep->callback = afs_data_pointer_to_int32(scp->cbServerp);
! if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp)
! cep->cbExpires = scp->volp->cbExpiresRO;
! else
cep->cbExpires = scp->cbExpires;
cep->refCount = scp->refCount;
cep->opens = scp->openReads;
--- 733,754 ----
cep->netFid.Vnode = scp->fid.vnode;
cep->netFid.Unique = scp->fid.unique;
cep->lock.waitStates = 0;
! cep->lock.exclLocked = scp->rw.flags;
cep->lock.readersReading = 0;
! cep->lock.numWaiting = scp->rw.waiters;
cep->lock.pid_last_reader = 0;
cep->lock.pid_writer = 0;
cep->lock.src_indicator = 0;
cep->Length = scp->length.LowPart;
cep->DataVersion = (afs_uint32)(scp->dataVersion & 0xFFFFFFFF);
cep->callback = afs_data_pointer_to_int32(scp->cbServerp);
! if (scp->flags & CM_SCACHEFLAG_PURERO) {
! cm_volume_t *volp = cm_GetVolumeByFID(&scp->fid);
! if (volp) {
! cep->cbExpires = volp->cbExpiresRO;
! cm_PutVolume(volp);
! }
! } else
cep->cbExpires = scp->cbExpires;
cep->refCount = scp->refCount;
cep->opens = scp->openReads;
***************
*** 818,826 ****
fcnDone:
lock_ReleaseRead(&cm_scacheLock);
- #ifdef HOLD_CALL_MUTEX
- MUTEX_EXIT(&callp->lock);
- #endif
return (code);
}
--- 794,799 ----
***************
*** 836,844 ****
unsigned long host = 0;
unsigned short port = 0;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_ENTER(&callp->lock);
- #endif
if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
host = rx_HostOf(peerp);
port = rx_PortOf(peerp);
--- 809,814 ----
***************
*** 873,881 ****
cep->netFid.Vnode = scp->fid.vnode;
cep->netFid.Unique = scp->fid.unique;
cep->lock.waitStates = 0;
! cep->lock.exclLocked = scp->mx.flags;
cep->lock.readersReading = 0;
! cep->lock.numWaiting = scp->mx.waiters;
cep->lock.pid_last_reader = 0;
cep->lock.pid_writer = 0;
cep->lock.src_indicator = 0;
--- 843,851 ----
cep->netFid.Vnode = scp->fid.vnode;
cep->netFid.Unique = scp->fid.unique;
cep->lock.waitStates = 0;
! cep->lock.exclLocked = scp->rw.flags;
cep->lock.readersReading = 0;
! cep->lock.numWaiting = scp->rw.waiters;
cep->lock.pid_last_reader = 0;
cep->lock.pid_writer = 0;
cep->lock.src_indicator = 0;
***************
*** 887,895 ****
#endif
cep->DataVersion = (afs_uint32)(scp->dataVersion & 0xFFFFFFFF);
cep->callback = afs_data_pointer_to_int32(scp->cbServerp);
! if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp)
! cep->cbExpires = scp->volp->cbExpiresRO;
! else
cep->cbExpires = scp->cbExpires;
cep->refCount = scp->refCount;
cep->opens = scp->openReads;
--- 857,869 ----
#endif
cep->DataVersion = (afs_uint32)(scp->dataVersion & 0xFFFFFFFF);
cep->callback = afs_data_pointer_to_int32(scp->cbServerp);
! if (scp->flags & CM_SCACHEFLAG_PURERO) {
! cm_volume_t *volp = cm_GetVolumeByFID(&scp->fid);
! if (volp) {
! cep->cbExpires = volp->cbExpiresRO;
! cm_PutVolume(volp);
! }
! } else
cep->cbExpires = scp->cbExpires;
cep->refCount = scp->refCount;
cep->opens = scp->openReads;
***************
*** 935,943 ****
fcnDone:
lock_ReleaseRead(&cm_scacheLock);
- #ifdef HOLD_CALL_MUTEX
- MUTEX_EXIT(&callp->lock);
- #endif
return (code);
}
--- 909,914 ----
***************
*** 950,958 ****
unsigned long host = 0;
unsigned short port = 0;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_ENTER(&callp->lock);
- #endif
if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
host = rx_HostOf(peerp);
port = rx_PortOf(peerp);
--- 921,926 ----
***************
*** 962,970 ****
ntohl(host), ntohs(port));
*vp = -1;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_EXIT(&callp->lock);
- #endif
return RXGEN_OPCODE;
}
--- 930,935 ----
***************
*** 978,986 ****
unsigned long host = 0;
unsigned short port = 0;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_ENTER(&callp->lock);
- #endif
if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
host = rx_HostOf(peerp);
port = rx_PortOf(peerp);
--- 943,948 ----
***************
*** 989,997 ****
osi_Log2(afsd_logp, "SRXAFSCB_GetXStats from host 0x%x port %d - not implemented",
ntohl(host), ntohs(port));
- #ifdef HOLD_CALL_MUTEX
- MUTEX_EXIT(&callp->lock);
- #endif
return RXGEN_OPCODE;
}
--- 951,956 ----
***************
*** 1008,1043 ****
SRXAFSCB_WhoAreYou(struct rx_call *callp, struct interfaceAddr* addr)
{
int i;
- int cm_noIPAddr; /* number of client network interfaces */
- int cm_IPAddr[CM_MAXINTERFACE_ADDR]; /* client's IP address in host order */
- int cm_SubnetMask[CM_MAXINTERFACE_ADDR];/* client's subnet mask in host order*/
- int cm_NetMtu[CM_MAXINTERFACE_ADDR]; /* client's MTU sizes */
- int cm_NetFlags[CM_MAXINTERFACE_ADDR]; /* network flags */
long code;
struct rx_connection *connp;
struct rx_peer *peerp;
unsigned long host = 0;
unsigned short port = 0;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_ENTER(&callp->lock);
- #endif
if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
host = rx_HostOf(peerp);
port = rx_PortOf(peerp);
}
- /* get network related info */
- cm_noIPAddr = CM_MAXINTERFACE_ADDR;
- code = syscfg_GetIFInfo(&cm_noIPAddr,
- cm_IPAddr, cm_SubnetMask,
- cm_NetMtu, cm_NetFlags);
-
- /* return all network interface addresses */
osi_Log2(afsd_logp, "SRXAFSCB_WhoAreYou from host 0x%x port %d",
ntohl(host),
ntohs(port));
addr->numberOfInterfaces = cm_noIPAddr;
addr->uuid = cm_data.Uuid;
for ( i=0; i < cm_noIPAddr; i++ ) {
--- 967,1002 ----
SRXAFSCB_WhoAreYou(struct rx_call *callp, struct interfaceAddr* addr)
{
int i;
long code;
struct rx_connection *connp;
struct rx_peer *peerp;
unsigned long host = 0;
unsigned short port = 0;
if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
host = rx_HostOf(peerp);
port = rx_PortOf(peerp);
}
osi_Log2(afsd_logp, "SRXAFSCB_WhoAreYou from host 0x%x port %d",
ntohl(host),
ntohs(port));
+ lock_ObtainRead(&cm_syscfgLock);
+ if (cm_LanAdapterChangeDetected) {
+ lock_ConvertRToW(&cm_syscfgLock);
+ if (cm_LanAdapterChangeDetected) {
+ /* get network related info */
+ cm_noIPAddr = CM_MAXINTERFACE_ADDR;
+ code = syscfg_GetIFInfo(&cm_noIPAddr,
+ cm_IPAddr, cm_SubnetMask,
+ cm_NetMtu, cm_NetFlags);
+ cm_LanAdapterChangeDetected = 0;
+ }
+ lock_ConvertWToR(&cm_syscfgLock);
+ }
+
+ /* return all network interface addresses */
addr->numberOfInterfaces = cm_noIPAddr;
addr->uuid = cm_data.Uuid;
for ( i=0; i < cm_noIPAddr; i++ ) {
***************
*** 1047,1055 ****
cm_NetMtu[i] : rx_mtu;
}
! #ifdef HOLD_CALL_MUTEX
! MUTEX_EXIT(&callp->lock);
! #endif
return 0;
}
--- 1006,1013 ----
cm_NetMtu[i] : rx_mtu;
}
! lock_ReleaseRead(&cm_syscfgLock);
!
return 0;
}
***************
*** 1078,1086 ****
char *p,*q;
int code = 0;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_ENTER(&callp->lock);
- #endif
if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
host = rx_HostOf(peerp);
port = rx_PortOf(peerp);
--- 1036,1041 ----
***************
*** 1103,1111 ****
ntohl(host),
ntohs(port));
- #ifdef HOLD_CALL_MUTEX
- MUTEX_EXIT(&callp->lock);
- #endif
return code;
}
--- 1058,1063 ----
***************
*** 1155,1163 ****
unsigned short port = 0;
int rc;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_ENTER(&callp->lock);
- #endif
if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
host = rx_HostOf(peerp);
port = rx_PortOf(peerp);
--- 1107,1112 ----
***************
*** 1172,1180 ****
rc = GetCellCommon(a_cellnum, a_name, a_hosts);
- #ifdef HOLD_CALL_MUTEX
- MUTEX_EXIT(&callp->lock);
- #endif
return rc;
}
--- 1121,1126 ----
***************
*** 1187,1221 ****
int i;
afs_int32 *dataBuffP;
afs_int32 dataBytes;
- int cm_noIPAddr; /* number of client network interfaces */
- int cm_IPAddr[CM_MAXINTERFACE_ADDR]; /* client's IP address in host order */
- int cm_SubnetMask[CM_MAXINTERFACE_ADDR];/* client's subnet mask in host order*/
- int cm_NetMtu[CM_MAXINTERFACE_ADDR]; /* client's MTU sizes */
- int cm_NetFlags[CM_MAXINTERFACE_ADDR]; /* network flags */
long code;
struct rx_connection *connp;
struct rx_peer *peerp;
unsigned long host = 0;
unsigned short port = 0;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_ENTER(&callp->lock);
- #endif
if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
host = rx_HostOf(peerp);
port = rx_PortOf(peerp);
}
- /* get network related info */
- cm_noIPAddr = CM_MAXINTERFACE_ADDR;
- code = syscfg_GetIFInfo(&cm_noIPAddr,
- cm_IPAddr, cm_SubnetMask,
- cm_NetMtu, cm_NetFlags);
-
osi_Log2(afsd_logp, "SRXAFSCB_TellMeAboutYourself from host 0x%x port %d",
ntohl(host),
ntohs(port));
/* return all network interface addresses */
addr->numberOfInterfaces = cm_noIPAddr;
addr->uuid = cm_data.Uuid;
--- 1133,1167 ----
int i;
afs_int32 *dataBuffP;
afs_int32 dataBytes;
long code;
struct rx_connection *connp;
struct rx_peer *peerp;
unsigned long host = 0;
unsigned short port = 0;
if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
host = rx_HostOf(peerp);
port = rx_PortOf(peerp);
}
osi_Log2(afsd_logp, "SRXAFSCB_TellMeAboutYourself from host 0x%x port %d",
ntohl(host),
ntohs(port));
+ lock_ObtainRead(&cm_syscfgLock);
+ if (cm_LanAdapterChangeDetected) {
+ lock_ConvertRToW(&cm_syscfgLock);
+ if (cm_LanAdapterChangeDetected) {
+ /* get network related info */
+ cm_noIPAddr = CM_MAXINTERFACE_ADDR;
+ code = syscfg_GetIFInfo(&cm_noIPAddr,
+ cm_IPAddr, cm_SubnetMask,
+ cm_NetMtu, cm_NetFlags);
+ cm_LanAdapterChangeDetected = 0;
+ }
+ lock_ConvertWToR(&cm_syscfgLock);
+ }
+
/* return all network interface addresses */
addr->numberOfInterfaces = cm_noIPAddr;
addr->uuid = cm_data.Uuid;
***************
*** 1225,1230 ****
--- 1171,1177 ----
addr->mtu[i] = (rx_mtu == -1 || (rx_mtu != -1 && cm_NetMtu[i] < rx_mtu)) ?
cm_NetMtu[i] : rx_mtu;
}
+ lock_ReleaseRead(&cm_syscfgLock);
dataBytes = 1 * sizeof(afs_int32);
dataBuffP = (afs_int32 *) osi_Alloc(dataBytes);
***************
*** 1232,1240 ****
capabilities->Capabilities_len = dataBytes / sizeof(afs_int32);
capabilities->Capabilities_val = dataBuffP;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_EXIT(&callp->lock);
- #endif
return 0;
}
--- 1179,1184 ----
***************
*** 1271,1279 ****
unsigned long host = 0;
unsigned short port = 0;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_ENTER(&callp->lock);
- #endif
if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
host = rx_HostOf(peerp);
port = rx_PortOf(peerp);
--- 1215,1220 ----
***************
*** 1286,1294 ****
*a_srvr_addr = 0xffffffff;
*a_srvr_rank = 0xffffffff;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_EXIT(&callp->lock);
- #endif
return 0;
}
--- 1227,1232 ----
***************
*** 1323,1331 ****
unsigned short port = 0;
int rc;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_ENTER(&callp->lock);
- #endif
if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
host = rx_HostOf(peerp);
port = rx_PortOf(peerp);
--- 1261,1266 ----
***************
*** 1373,1381 ****
unsigned long host = 0;
unsigned short port = 0;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_ENTER(&callp->lock);
- #endif
if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
host = rx_HostOf(peerp);
port = rx_PortOf(peerp);
--- 1308,1313 ----
***************
*** 1393,1401 ****
}
*a_name = t_name;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_EXIT(&callp->lock);
- #endif
return 0;
}
--- 1325,1330 ----
***************
*** 1475,1483 ****
unsigned long host = 0;
unsigned short port = 0;
- #ifdef HOLD_CALL_MUTEX
- MUTEX_ENTER(&callp->lock);
- #endif
if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
host = rx_HostOf(peerp);
port = rx_PortOf(peerp);
--- 1404,1409 ----
***************
*** 1505,1513 ****
config->cacheConfig_val = t_config;
config->cacheConfig_len = (*configCount)/sizeof(afs_uint32);
- #ifdef HOLD_CALL_MUTEX
- MUTEX_EXIT(&callp->lock);
- #endif
return 0;
}
--- 1431,1436 ----
***************
*** 1559,1567 ****
} else if (fdc==2 && !fgc) { // we're in good shape
if (cm_getLocalMountPointChange()) { // check for changes
cm_clearLocalMountPointChange(); // clear the changefile
! lock_ReleaseMutex(&scp->mx); // this is re-locked in reInitLocalMountPoints
cm_reInitLocalMountPoints(); // start reinit
! lock_ObtainMutex(&scp->mx); // now get the lock back
return 0;
}
return 1; // no change
--- 1482,1490 ----
} else if (fdc==2 && !fgc) { // we're in good shape
if (cm_getLocalMountPointChange()) { // check for changes
cm_clearLocalMountPointChange(); // clear the changefile
! lock_ReleaseWrite(&scp->rw); // this is re-locked in reInitLocalMountPoints
cm_reInitLocalMountPoints(); // start reinit
! lock_ObtainWrite(&scp->rw); // now get the lock back
return 0;
}
return 1; // no change
***************
*** 1573,1589 ****
if (scp->cbServerp != NULL) {
return 1;
} else if (cm_OfflineROIsValid) {
! switch (cm_GetVolumeStatus(scp->volp, scp->fid.volume)) {
! case vl_offline:
! case vl_alldown:
! case vl_unknown:
! return 1;
! default:
! return 0;
}
! } else {
! return 0;
}
}
/* need to detect a broken callback that races with our obtaining a callback.
--- 1496,1517 ----
if (scp->cbServerp != NULL) {
return 1;
} else if (cm_OfflineROIsValid) {
! cm_volume_t *volp = cm_GetVolumeByFID(&scp->fid);
! if (volp) {
! switch (cm_GetVolumeStatus(volp, scp->fid.volume)) {
! case vl_offline:
! case vl_alldown:
! case vl_unknown:
! cm_PutVolume(volp);
! return 1;
! default:
! cm_PutVolume(volp);
! return 0;
! }
}
! return 1;
}
+ return 0;
}
/* need to detect a broken callback that races with our obtaining a callback.
***************
*** 1618,1624 ****
/* Called at the end of a callback-granting call, to remove the callback
* info from the scache entry, if necessary.
*
! * Called with scp locked, so we can discard the callbacks easily with
* this locking hierarchy.
*/
void cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp,
--- 1546,1552 ----
/* Called at the end of a callback-granting call, to remove the callback
* info from the scache entry, if necessary.
*
! * Called with scp write locked, so we can discard the callbacks easily with
* this locking hierarchy.
*/
void cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp,
***************
*** 1657,1664 ****
serverp = cbrp->serverp;
}
scp->cbExpires = cbrp->startTime + cbp->ExpirationTime;
! if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp)
! scp->volp->cbExpiresRO = scp->cbExpires;
} else {
if (freeFlag)
serverp = cbrp->serverp;
--- 1585,1597 ----
serverp = cbrp->serverp;
}
scp->cbExpires = cbrp->startTime + cbp->ExpirationTime;
! if (scp->flags & CM_SCACHEFLAG_PURERO) {
! cm_volume_t * volp = cm_GetVolumeByFID(&scp->fid);
! if (volp) {
! volp->cbExpiresRO = scp->cbExpires;
! cm_PutVolume(volp);
! }
! }
} else {
if (freeFlag)
serverp = cbrp->serverp;
***************
*** 1696,1705 ****
cbrp->callbackCount, revp->callbackCount,
cm_callbackCount);
discardScp = 1;
!
! if ((scp->flags & CM_SCACHEFLAG_PURERO) && scp->volp &&
! (revp->flags & (CM_RACINGFLAG_CANCELVOL | CM_RACINGFLAG_CANCELALL)))
! scp->volp->cbExpiresRO = 0;
}
if (freeFlag)
free(revp);
--- 1629,1642 ----
cbrp->callbackCount, revp->callbackCount,
cm_callbackCount);
discardScp = 1;
! if ((scp->flags & CM_SCACHEFLAG_PURERO) &&
! (revp->flags & (CM_RACINGFLAG_CANCELVOL | CM_RACINGFLAG_CANCELALL))) {
! cm_volume_t *volp = cm_GetVolumeByFID(&scp->fid);
! if (volp) {
! volp->cbExpiresRO = 0;
! cm_PutVolume(volp);
! }
! }
}
if (freeFlag)
free(revp);
***************
*** 1713,1721 ****
if ( discardScp ) {
cm_DiscardSCache(scp);
! lock_ReleaseMutex(&scp->mx);
cm_CallbackNotifyChange(scp);
! lock_ObtainMutex(&scp->mx);
}
if ( serverp ) {
--- 1650,1658 ----
if ( discardScp ) {
cm_DiscardSCache(scp);
! lock_ReleaseWrite(&scp->rw);
cm_CallbackNotifyChange(scp);
! lock_ObtainWrite(&scp->rw);
}
if ( serverp ) {
***************
*** 1804,1810 ****
}
cm_StartCallbackGrantingCall(scp, &cbr);
sfid = scp->fid;
! lock_ReleaseMutex(&scp->mx);
/* now make the RPC */
osi_Log4(afsd_logp, "CALL FetchStatus scp 0x%p vol %u vn %u uniq %u",
--- 1741,1747 ----
}
cm_StartCallbackGrantingCall(scp, &cbr);
sfid = scp->fid;
! lock_ReleaseWrite(&scp->rw);
/* now make the RPC */
osi_Log4(afsd_logp, "CALL FetchStatus scp 0x%p vol %u vn %u uniq %u",
***************
*** 1829,1835 ****
osi_Log4(afsd_logp, "CALL FetchStatus SUCCESS scp 0x%p vol %u vn %u uniq %u",
scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
! lock_ObtainMutex(&scp->mx);
if (code == 0) {
cm_EndCallbackGrantingCall(scp, &cbr, &callback, 0);
cm_MergeStatus(NULL, scp, &afsStatus, &volSync, userp, 0);
--- 1766,1772 ----
osi_Log4(afsd_logp, "CALL FetchStatus SUCCESS scp 0x%p vol %u vn %u uniq %u",
scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
! lock_ObtainWrite(&scp->rw);
if (code == 0) {
cm_EndCallbackGrantingCall(scp, &cbr, &callback, 0);
cm_MergeStatus(NULL, scp, &afsStatus, &volSync, userp, 0);
***************
*** 1862,1868 ****
long cm_CBServersUp(cm_scache_t *scp, time_t * downTime)
{
cm_vol_state_t *statep;
! cm_volume_t * volp = scp->volp;
afs_uint32 volID = scp->fid.volume;
cm_serverRef_t *tsrp;
int found;
--- 1799,1805 ----
long cm_CBServersUp(cm_scache_t *scp, time_t * downTime)
{
cm_vol_state_t *statep;
! cm_volume_t * volp;
afs_uint32 volID = scp->fid.volume;
cm_serverRef_t *tsrp;
int found;
***************
*** 1872,1877 ****
--- 1809,1818 ----
if (scp->cbServerp == NULL)
return 1;
+ volp = cm_GetVolumeByFID(&scp->fid);
+ if (!volp)
+ return 1;
+
if (volp->rw.ID == volID) {
statep = &volp->rw;
} else if (volp->ro.ID == volID) {
***************
*** 1879,1885 ****
} else if (volp->bk.ID == volID) {
statep = &volp->bk;
}
!
if (statep->state == vl_online)
return 1;
--- 1820,1826 ----
} else if (volp->bk.ID == volID) {
statep = &volp->bk;
}
! cm_PutVolume(volp);
if (statep->state == vl_online)
return 1;
***************
*** 1911,1921 ****
for (i=0; inextp) {
downTime = 0;
! if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp) {
! if (scp->volp->cbExpiresRO > scp->cbExpires && scp->cbExpires > 0)
! scp->cbExpires = scp->volp->cbExpiresRO;
}
-
if (scp->cbServerp && scp->cbExpires > 0 && now > scp->cbExpires &&
(cm_CBServersUp(scp, &downTime) || downTime == 0 || downTime >= scp->cbExpires))
{
--- 1852,1865 ----
for (i=0; inextp) {
downTime = 0;
! if (scp->flags & CM_SCACHEFLAG_PURERO) {
! cm_volume_t *volp = cm_GetVolumeByFID(&scp->fid);
! if (volp) {
! if (volp->cbExpiresRO > scp->cbExpires && scp->cbExpires > 0)
! scp->cbExpires = volp->cbExpiresRO;
! cm_PutVolume(volp);
! }
}
if (scp->cbServerp && scp->cbExpires > 0 && now > scp->cbExpires &&
(cm_CBServersUp(scp, &downTime) || downTime == 0 || downTime >= scp->cbExpires))
{
***************
*** 1924,1932 ****
osi_Log4(afsd_logp, "Callback Expiration Discarding SCache scp 0x%p vol %u vn %u uniq %u",
scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
! lock_ObtainMutex(&scp->mx);
cm_DiscardSCache(scp);
! lock_ReleaseMutex(&scp->mx);
cm_CallbackNotifyChange(scp);
lock_ObtainWrite(&cm_scacheLock);
--- 1868,1876 ----
osi_Log4(afsd_logp, "Callback Expiration Discarding SCache scp 0x%p vol %u vn %u uniq %u",
scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
! lock_ObtainWrite(&scp->rw);
cm_DiscardSCache(scp);
! lock_ReleaseWrite(&scp->rw);
cm_CallbackNotifyChange(scp);
lock_ObtainWrite(&cm_scacheLock);
***************
*** 1978,1984 ****
cm_InitReq(&req);
! code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
&req, CM_GETVOL_FLAG_NO_LRU_UPDATE | CM_GETVOL_FLAG_NO_RESET, &volp);
if (code == 0) {
cm_UpdateVolumeStatus(volp, tsrvp->ids[i]);
--- 1922,1928 ----
cm_InitReq(&req);
! code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
&req, CM_GETVOL_FLAG_NO_LRU_UPDATE | CM_GETVOL_FLAG_NO_RESET, &volp);
if (code == 0) {
cm_UpdateVolumeStatus(volp, tsrvp->ids[i]);
Index: openafs/src/WINNT/afsd/cm_config.h
diff -c openafs/src/WINNT/afsd/cm_config.h:1.8.6.6 openafs/src/WINNT/afsd/cm_config.h:1.8.6.8
*** openafs/src/WINNT/afsd/cm_config.h:1.8.6.6 Mon Feb 25 10:34:31 2008
--- openafs/src/WINNT/afsd/cm_config.h Wed Mar 19 20:01:59 2008
***************
*** 13,23 ****
#define CM_CONFIGDEFAULT_CACHESIZE 98304
#define CM_CONFIGDEFAULT_BLOCKSIZE 4096
#define CM_CONFIGDEFAULT_ASYNCSTORESIZE 131072 /* 128K */
#define CM_CONFIGDEFAULT_STATS 10000
#define CM_CONFIGDEFAULT_CHUNKSIZE 18 /* 256KB */
! #define CM_CONFIGDEFAULT_DAEMONS 1
#define CM_CONFIGDEFAULT_SVTHREADS 25
! #define CM_CONFIGDEFAULT_TRACEBUFSIZE 5000
#ifndef __CM_CONFIG_INTERFACES_ONLY__
--- 13,24 ----
#define CM_CONFIGDEFAULT_CACHESIZE 98304
#define CM_CONFIGDEFAULT_BLOCKSIZE 4096
#define CM_CONFIGDEFAULT_ASYNCSTORESIZE 131072 /* 128K */
+ #define CM_CONFIGDEFAULT_CELLS 1024
#define CM_CONFIGDEFAULT_STATS 10000
#define CM_CONFIGDEFAULT_CHUNKSIZE 18 /* 256KB */
! #define CM_CONFIGDEFAULT_DAEMONS 4
#define CM_CONFIGDEFAULT_SVTHREADS 25
! #define CM_CONFIGDEFAULT_TRACEBUFSIZE 10000
#ifndef __CM_CONFIG_INTERFACES_ONLY__
Index: openafs/src/WINNT/afsd/cm_conn.c
diff -c openafs/src/WINNT/afsd/cm_conn.c:1.49.2.35 openafs/src/WINNT/afsd/cm_conn.c:1.49.2.39
*** openafs/src/WINNT/afsd/cm_conn.c:1.49.2.35 Mon Feb 25 17:21:24 2008
--- openafs/src/WINNT/afsd/cm_conn.c Thu Mar 13 00:39:17 2008
***************
*** 20,25 ****
--- 20,26 ----
#include
#include
#include
+ #include
#include
osi_rwlock_t cm_connLock;
***************
*** 36,44 ****
void cm_PutConn(cm_conn_t *connp)
{
! lock_ObtainWrite(&cm_connLock);
! osi_assertx(connp->refCount-- > 0, "cm_conn_t refcount 0");
! lock_ReleaseWrite(&cm_connLock);
}
void cm_InitConn(void)
--- 37,44 ----
void cm_PutConn(cm_conn_t *connp)
{
! afs_int32 refCount = InterlockedDecrement(&connp->refCount);
! osi_assertx(refCount >= 0, "cm_conn_t refcount underflow");
}
void cm_InitConn(void)
***************
*** 127,133 ****
if (!cellp)
return CM_ERROR_NOSUCHCELL;
! code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, CM_GETVOL_FLAG_CREATE, &volp);
if (code)
return code;
--- 127,133 ----
if (!cellp)
return CM_ERROR_NOSUCHCELL;
! code = cm_FindVolumeByID(cellp, fidp->volume, userp, reqp, CM_GETVOL_FLAG_CREATE, &volp);
if (code)
return code;
***************
*** 213,219 ****
#endif
/* leave 5 seconds margin for sleep */
! timeLeft = HardDeadtimeout - timeUsed;
/* get a pointer to the cell */
if (errorCode) {
--- 213,222 ----
#endif
/* leave 5 seconds margin for sleep */
! if (reqp->flags & CM_REQ_NORETRY)
! timeLeft = 0;
! else
! timeLeft = HardDeadtimeout - timeUsed;
/* get a pointer to the cell */
if (errorCode) {
***************
*** 232,238 ****
}
if (errorCode == CM_ERROR_TIMEDOUT) {
! if (timeLeft > 5 ) {
thrd_Sleep(3000);
cm_CheckServers(CM_FLAG_CHECKDOWNSERVERS, cellp);
retry = 1;
--- 235,241 ----
}
if (errorCode == CM_ERROR_TIMEDOUT) {
! if ( timeLeft > 5 ) {
thrd_Sleep(3000);
cm_CheckServers(CM_FLAG_CHECKDOWNSERVERS, cellp);
retry = 1;
***************
*** 242,248 ****
else if (errorCode == UAEWOULDBLOCK || errorCode == EWOULDBLOCK ||
errorCode == UAEAGAIN || errorCode == EAGAIN) {
osi_Log0(afsd_logp, "cm_Analyze passed EWOULDBLOCK or EAGAIN.");
! if (timeLeft > 5 ) {
thrd_Sleep(1000);
retry = 1;
}
--- 245,251 ----
else if (errorCode == UAEWOULDBLOCK || errorCode == EWOULDBLOCK ||
errorCode == UAEAGAIN || errorCode == EAGAIN) {
osi_Log0(afsd_logp, "cm_Analyze passed EWOULDBLOCK or EAGAIN.");
! if ( timeLeft > 5 ) {
thrd_Sleep(1000);
retry = 1;
}
***************
*** 281,287 ****
if (timeLeft > 7 && fidp) {
thrd_Sleep(5000);
! code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp,
CM_GETVOL_FLAG_NO_LRU_UPDATE,
&volp);
if (code == 0) {
--- 284,290 ----
if (timeLeft > 7 && fidp) {
thrd_Sleep(5000);
! code = cm_FindVolumeByID(cellp, fidp->volume, userp, reqp,
CM_GETVOL_FLAG_NO_LRU_UPDATE,
&volp);
if (code == 0) {
***************
*** 313,319 ****
thrd_Sleep(5000);
if (fidp) { /* File Server query */
! code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp,
CM_GETVOL_FLAG_NO_LRU_UPDATE,
&volp);
if (code == 0) {
--- 316,322 ----
thrd_Sleep(5000);
if (fidp) { /* File Server query */
! code = cm_FindVolumeByID(cellp, fidp->volume, userp, reqp,
CM_GETVOL_FLAG_NO_LRU_UPDATE,
&volp);
if (code == 0) {
***************
*** 383,389 ****
if (tsrp->server == serverp && tsrp->status == srv_not_busy) {
tsrp->status = srv_busy;
if (fidp) { /* File Server query */
! code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp,
CM_GETVOL_FLAG_NO_LRU_UPDATE,
&volp);
if (code == 0) {
--- 386,392 ----
if (tsrp->server == serverp && tsrp->status == srv_not_busy) {
tsrp->status = srv_busy;
if (fidp) { /* File Server query */
! code = cm_FindVolumeByID(cellp, fidp->volume, userp, reqp,
CM_GETVOL_FLAG_NO_LRU_UPDATE,
&volp);
if (code == 0) {
***************
*** 494,500 ****
}
if (fidp) { /* File Server query */
! code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp,
CM_GETVOL_FLAG_NO_LRU_UPDATE,
&volp);
if (code == 0) {
--- 497,503 ----
}
if (fidp) { /* File Server query */
! code = cm_FindVolumeByID(cellp, fidp->volume, userp, reqp,
CM_GETVOL_FLAG_NO_LRU_UPDATE,
&volp);
if (code == 0) {
***************
*** 538,557 ****
pscp = cm_FindSCacheParent(scp);
! lock_ObtainMutex(&scp->mx);
lock_ObtainWrite(&cm_scacheLock);
cm_RemoveSCacheFromHashTable(scp);
lock_ReleaseWrite(&cm_scacheLock);
cm_LockMarkSCacheLost(scp);
scp->flags |= CM_SCACHEFLAG_DELETED;
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
if (pscp) {
if (cm_HaveCallback(pscp)) {
! lock_ObtainMutex(&pscp->mx);
cm_DiscardSCache(pscp);
! lock_ReleaseMutex(&pscp->mx);
}
cm_ReleaseSCache(pscp);
}
--- 541,560 ----
pscp = cm_FindSCacheParent(scp);
! lock_ObtainWrite(&scp->rw);
lock_ObtainWrite(&cm_scacheLock);
cm_RemoveSCacheFromHashTable(scp);
lock_ReleaseWrite(&cm_scacheLock);
cm_LockMarkSCacheLost(scp);
scp->flags |= CM_SCACHEFLAG_DELETED;
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
if (pscp) {
if (cm_HaveCallback(pscp)) {
! lock_ObtainWrite(&pscp->rw);
cm_DiscardSCache(pscp);
! lock_ReleaseWrite(&pscp->rw);
}
cm_ReleaseSCache(pscp);
}
***************
*** 615,620 ****
--- 618,627 ----
if ( timeLeft > 2 )
retry = 1;
}
+ } else if (errorCode >= ERROR_TABLE_BASE_RXK && errorCode < ERROR_TABLE_BASE_RXK + 256) {
+ reqp->tokenErrorServp = serverp;
+ reqp->tokenError = errorCode;
+ retry = 1;
} else if (errorCode == VICECONNBAD || errorCode == VICETOKENDEAD) {
cm_ForceNewConnections(serverp);
if ( timeLeft > 2 )
***************
*** 663,668 ****
--- 670,707 ----
case VICETOKENDEAD : s = "VICETOKENDEAD"; break;
case WSAEWOULDBLOCK : s = "WSAEWOULDBLOCK"; break;
case UAEWOULDBLOCK : s = "UAEWOULDBLOCK"; break;
+ case VL_IDEXIST : s = "VL_IDEXIST"; break;
+ case VL_IO : s = "VL_IO"; break;
+ case VL_NAMEEXIST : s = "VL_NAMEEXIST"; break;
+ case VL_CREATEFAIL : s = "VL_CREATEFAIL"; break;
+ case VL_NOENT : s = "VL_NOENT"; break;
+ case VL_EMPTY : s = "VL_EMPTY"; break;
+ case VL_ENTDELETED : s = "VL_ENTDELETED"; break;
+ case VL_BADNAME : s = "VL_BADNAME"; break;
+ case VL_BADINDEX : s = "VL_BADINDEX"; break;
+ case VL_BADVOLTYPE : s = "VL_BADVOLTYPE"; break;
+ case VL_BADSERVER : s = "VL_BADSERVER"; break;
+ case VL_BADPARTITION : s = "VL_BADPARTITION"; break;
+ case VL_REPSFULL : s = "VL_REPSFULL"; break;
+ case VL_NOREPSERVER : s = "VL_NOREPSERVER"; break;
+ case VL_DUPREPSERVER : s = "VL_DUPREPSERVER"; break;
+ case VL_RWNOTFOUND : s = "VL_RWNOTFOUND"; break;
+ case VL_BADREFCOUNT : s = "VL_BADREFCOUNT"; break;
+ case VL_SIZEEXCEEDED : s = "VL_SIZEEXCEEDED"; break;
+ case VL_BADENTRY : s = "VL_BADENTRY"; break;
+ case VL_BADVOLIDBUMP : s = "VL_BADVOLIDBUMP"; break;
+ case VL_IDALREADYHASHED: s = "VL_IDALREADYHASHED"; break;
+ case VL_ENTRYLOCKED : s = "VL_ENTRYLOCKED"; break;
+ case VL_BADVOLOPER : s = "VL_BADVOLOPER"; break;
+ case VL_BADRELLOCKTYPE : s = "VL_BADRELLOCKTYPE"; break;
+ case VL_RERELEASE : s = "VL_RERELEASE"; break;
+ case VL_BADSERVERFLAG : s = "VL_BADSERVERFLAG"; break;
+ case VL_PERM : s = "VL_PERM"; break;
+ case VL_NOMEM : s = "VL_NOMEM"; break;
+ case VL_BADVERSION : s = "VL_BADVERSION"; break;
+ case VL_INDEXERANGE : s = "VL_INDEXERANGE"; break;
+ case VL_MULTIPADDR : s = "VL_MULTIPADDR"; break;
+ case VL_BADMASK : s = "VL_BADMASK"; break;
case CM_ERROR_NOSUCHCELL : s = "CM_ERROR_NOSUCHCELL"; break;
case CM_ERROR_NOSUCHVOLUME : s = "CM_ERROR_NOSUCHVOLUME"; break;
case CM_ERROR_TIMEDOUT : s = "CM_ERROR_TIMEDOUT"; break;
***************
*** 767,777 ****
timeLeft = ConnDeadtimeout - timeUsed - 5;
hardTimeLeft = HardDeadtimeout - timeUsed - 5;
! lock_ObtainWrite(&cm_serverLock);
for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
tsp = tsrp->server;
cm_GetServerNoLock(tsp);
! lock_ReleaseWrite(&cm_serverLock);
if (!(tsp->flags & CM_SERVERFLAG_DOWN)) {
allDown = 0;
if (tsrp->status == srv_deleted) {
--- 806,827 ----
timeLeft = ConnDeadtimeout - timeUsed - 5;
hardTimeLeft = HardDeadtimeout - timeUsed - 5;
! lock_ObtainRead(&cm_serverLock);
for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
tsp = tsrp->server;
+ if (reqp->tokenErrorServp) {
+ /*
+ * search the list until we find the server
+ * that failed last time. When we find it
+ * clear the error, skip it and try the one
+ * in the list.
+ */
+ if (tsp == reqp->tokenErrorServp)
+ reqp->tokenErrorServp = NULL;
+ continue;
+ }
cm_GetServerNoLock(tsp);
! lock_ReleaseRead(&cm_serverLock);
if (!(tsp->flags & CM_SERVERFLAG_DOWN)) {
allDown = 0;
if (tsrp->status == srv_deleted) {
***************
*** 807,820 ****
firstError = code;
}
}
! lock_ObtainWrite(&cm_serverLock);
cm_PutServerNoLock(tsp);
}
! lock_ReleaseWrite(&cm_serverLock);
if (firstError == 0) {
if (allDown)
! firstError = CM_ERROR_ALLDOWN;
else if (allBusy)
firstError = CM_ERROR_ALLBUSY;
else if (allOffline || (someBusy && someOffline))
--- 857,870 ----
firstError = code;
}
}
! lock_ObtainRead(&cm_serverLock);
cm_PutServerNoLock(tsp);
}
! lock_ReleaseRead(&cm_serverLock);
if (firstError == 0) {
if (allDown)
! firstError = (reqp->tokenError ? reqp->tokenError : CM_ERROR_ALLDOWN);
else if (allBusy)
firstError = CM_ERROR_ALLBUSY;
else if (allOffline || (someBusy && someOffline))
***************
*** 914,920 ****
userp = cm_rootUserp;
lock_ObtainMutex(&userp->mx);
! lock_ObtainWrite(&cm_connLock);
for (tcp = serverp->connsp; tcp; tcp=tcp->nextp) {
if (tcp->userp == userp)
break;
--- 964,970 ----
userp = cm_rootUserp;
lock_ObtainMutex(&userp->mx);
! lock_ObtainRead(&cm_connLock);
for (tcp = serverp->connsp; tcp; tcp=tcp->nextp) {
if (tcp->userp == userp)
break;
***************
*** 923,928 ****
--- 973,987 ----
/* find ucell structure */
ucellp = cm_GetUCell(userp, serverp->cellp);
if (!tcp) {
+ lock_ConvertRToW(&cm_connLock);
+ for (tcp = serverp->connsp; tcp; tcp=tcp->nextp) {
+ if (tcp->userp == userp)
+ break;
+ }
+ if (tcp) {
+ lock_ReleaseWrite(&cm_connLock);
+ goto haveconn;
+ }
cm_GetServer(serverp);
tcp = malloc(sizeof(*tcp));
memset(tcp, 0, sizeof(*tcp));
***************
*** 937,943 ****
--- 996,1008 ----
cm_NewRXConnection(tcp, ucellp, serverp);
tcp->refCount = 1;
lock_ReleaseMutex(&tcp->mx);
+ lock_ReleaseWrite(&cm_connLock);
} else {
+ lock_ReleaseRead(&cm_connLock);
+ haveconn:
+ InterlockedIncrement(&tcp->refCount);
+
+ lock_ObtainMutex(&tcp->mx);
if ((tcp->flags & CM_CONN_FLAG_FORCE_NEW) ||
(tcp->ucgen < ucellp->gen) ||
(tcp->cryptlevel != (cryptall ? (ucellp->flags & CM_UCELLFLAG_RXKAD ? rxkad_crypt : rxkad_clear) : rxkad_clear)))
***************
*** 946,960 ****
osi_Log0(afsd_logp, "cm_ConnByServer replace connection due to token update");
else
osi_Log0(afsd_logp, "cm_ConnByServer replace connection due to crypt change");
- lock_ObtainMutex(&tcp->mx);
tcp->flags &= ~CM_CONN_FLAG_FORCE_NEW;
rx_DestroyConnection(tcp->callp);
cm_NewRXConnection(tcp, ucellp, serverp);
- lock_ReleaseMutex(&tcp->mx);
}
! tcp->refCount++;
}
- lock_ReleaseWrite(&cm_connLock);
lock_ReleaseMutex(&userp->mx);
/* return this pointer to our caller */
--- 1011,1022 ----
osi_Log0(afsd_logp, "cm_ConnByServer replace connection due to token update");
else
osi_Log0(afsd_logp, "cm_ConnByServer replace connection due to crypt change");
tcp->flags &= ~CM_CONN_FLAG_FORCE_NEW;
rx_DestroyConnection(tcp->callp);
cm_NewRXConnection(tcp, ucellp, serverp);
}
! lock_ReleaseMutex(&tcp->mx);
}
lock_ReleaseMutex(&userp->mx);
/* return this pointer to our caller */
***************
*** 979,988 ****
if (code)
return 0;
! lock_ObtainWrite(&cm_serverLock);
for (tsrp = *serverspp; tsrp; tsrp=tsrp->next) {
tsp = tsrp->server;
- cm_GetServerNoLock(tsp);
if (!(tsp->flags & CM_SERVERFLAG_DOWN)) {
allDown = 0;
if (tsrp->status == srv_busy) {
--- 1041,1049 ----
if (code)
return 0;
! lock_ObtainRead(&cm_serverLock);
for (tsrp = *serverspp; tsrp; tsrp=tsrp->next) {
tsp = tsrp->server;
if (!(tsp->flags & CM_SERVERFLAG_DOWN)) {
allDown = 0;
if (tsrp->status == srv_busy) {
***************
*** 996,1004 ****
allBusy = 0;
}
}
- cm_PutServerNoLock(tsp);
}
! lock_ReleaseWrite(&cm_serverLock);
cm_FreeServerList(serverspp, 0);
if (allDown)
--- 1057,1064 ----
allBusy = 0;
}
}
}
! lock_ReleaseRead(&cm_serverLock);
cm_FreeServerList(serverspp, 0);
if (allDown)
Index: openafs/src/WINNT/afsd/cm_conn.h
diff -c openafs/src/WINNT/afsd/cm_conn.h:1.13.4.9 openafs/src/WINNT/afsd/cm_conn.h:1.13.4.10
*** openafs/src/WINNT/afsd/cm_conn.h:1.13.4.9 Sat Dec 22 23:52:58 2007
--- openafs/src/WINNT/afsd/cm_conn.h Fri Mar 7 17:16:06 2008
***************
*** 24,32 ****
struct rx_connection *callp; /* locked by mx */
struct cm_user *userp; /* locked by mx; a held reference */
osi_mutex_t mx; /* mutex for some of these fields */
! unsigned long refCount; /* locked by cm_connLock */
int ucgen; /* ucellp's generation number */
! long flags; /* locked by mx */
int cryptlevel; /* encrytion status */
} cm_conn_t;
--- 24,32 ----
struct rx_connection *callp; /* locked by mx */
struct cm_user *userp; /* locked by mx; a held reference */
osi_mutex_t mx; /* mutex for some of these fields */
! afs_int32 refCount; /* Interlocked */
int ucgen; /* ucellp's generation number */
! afs_uint32 flags; /* locked by mx */
int cryptlevel; /* encrytion status */
} cm_conn_t;
***************
*** 42,48 ****
int rpcError; /* RPC error code */
int volumeError; /* volume error code */
int accessError; /* access error code */
! int flags;
char * tidPathp;
char * relPathp;
} cm_req_t;
--- 42,50 ----
int rpcError; /* RPC error code */
int volumeError; /* volume error code */
int accessError; /* access error code */
! struct cm_server * tokenErrorServp; /* server that reported a token error other than expired */
! int tokenError;
! afs_uint32 flags;
char * tidPathp;
char * relPathp;
} cm_req_t;
Index: openafs/src/WINNT/afsd/cm_daemon.c
diff -c openafs/src/WINNT/afsd/cm_daemon.c:1.16.4.25 openafs/src/WINNT/afsd/cm_daemon.c:1.16.4.28
*** openafs/src/WINNT/afsd/cm_daemon.c:1.16.4.25 Thu Jan 10 18:00:41 2008
--- openafs/src/WINNT/afsd/cm_daemon.c Sat Mar 8 18:25:08 2008
***************
*** 38,43 ****
--- 38,44 ----
long cm_daemonCheckLockInterval = 60;
long cm_daemonTokenCheckInterval = 180;
long cm_daemonCheckOfflineVolInterval = 600;
+ long cm_daemonPerformanceTuningInterval = 0;
osi_rwlock_t cm_daemonLock;
***************
*** 77,82 ****
--- 78,84 ----
if (Result == NO_ERROR && daemon_ShutdownFlag == 0) {
lastIPAddrChange = osi_Time();
smb_SetLanAdapterChangeDetected();
+ cm_SetLanAdapterChangeDetected();
thrd_ResetEvent(cm_IPAddrDaemon_ShutdownEvent);
}
}
***************
*** 111,117 ****
/* we found a request */
for (rp = cm_bkgListEndp; rp; rp = (cm_bkgRequest_t *) osi_QPrev(&rp->q))
{
! if (cm_ServerAvailable(&rp->scp->fid, rp->userp))
break;
}
if (rp == NULL) {
--- 113,120 ----
/* we found a request */
for (rp = cm_bkgListEndp; rp; rp = (cm_bkgRequest_t *) osi_QPrev(&rp->q))
{
! if (cm_ServerAvailable(&rp->scp->fid, rp->userp) &&
! !(rp->scp->flags & CM_SCACHEFLAG_DATASTORING))
break;
}
if (rp == NULL) {
***************
*** 143,148 ****
--- 146,155 ----
lock_ObtainWrite(&cm_daemonLock);
+ /*
+ * Keep the following list synchronized with the
+ * error code list in cm_BkgStore
+ */
switch ( code ) {
case 0: /* success */
osi_Log1(afsd_logp,"cm_BkgDaemon SUCCESS: request 0x%p", rp);
***************
*** 274,333 ****
dummyLen = sizeof(DWORD);
code = RegQueryValueEx(parmKey, "daemonCheckDownInterval", NULL, NULL,
(BYTE *) &dummy, &dummyLen);
! if (code == ERROR_SUCCESS)
cm_daemonCheckDownInterval = dummy;
afsi_log("daemonCheckDownInterval is %d", cm_daemonCheckDownInterval);
dummyLen = sizeof(DWORD);
code = RegQueryValueEx(parmKey, "daemonCheckUpInterval", NULL, NULL,
(BYTE *) &dummy, &dummyLen);
! if (code == ERROR_SUCCESS)
cm_daemonCheckUpInterval = dummy;
afsi_log("daemonCheckUpInterval is %d", cm_daemonCheckUpInterval);
dummyLen = sizeof(DWORD);
code = RegQueryValueEx(parmKey, "daemonCheckVolInterval", NULL, NULL,
(BYTE *) &dummy, &dummyLen);
! if (code == ERROR_SUCCESS)
cm_daemonCheckVolInterval = dummy;
afsi_log("daemonCheckVolInterval is %d", cm_daemonCheckVolInterval);
dummyLen = sizeof(DWORD);
code = RegQueryValueEx(parmKey, "daemonCheckCBInterval", NULL, NULL,
(BYTE *) &dummy, &dummyLen);
! if (code == ERROR_SUCCESS)
cm_daemonCheckCBInterval = dummy;
afsi_log("daemonCheckCBInterval is %d", cm_daemonCheckCBInterval);
dummyLen = sizeof(DWORD);
code = RegQueryValueEx(parmKey, "daemonCheckVolCBInterval", NULL, NULL,
(BYTE *) &dummy, &dummyLen);
! if (code == ERROR_SUCCESS)
cm_daemonCheckVolCBInterval = dummy;
afsi_log("daemonCheckVolCBInterval is %d", cm_daemonCheckVolCBInterval);
dummyLen = sizeof(DWORD);
code = RegQueryValueEx(parmKey, "daemonCheckLockInterval", NULL, NULL,
(BYTE *) &dummy, &dummyLen);
! if (code == ERROR_SUCCESS)
cm_daemonCheckLockInterval = dummy;
afsi_log("daemonCheckLockInterval is %d", cm_daemonCheckLockInterval);
dummyLen = sizeof(DWORD);
code = RegQueryValueEx(parmKey, "daemonCheckTokenInterval", NULL, NULL,
(BYTE *) &dummy, &dummyLen);
! if (code == ERROR_SUCCESS)
cm_daemonTokenCheckInterval = dummy;
afsi_log("daemonCheckTokenInterval is %d", cm_daemonTokenCheckInterval);
dummyLen = sizeof(DWORD);
code = RegQueryValueEx(parmKey, "daemonCheckOfflineVolInterval", NULL, NULL,
(BYTE *) &dummy, &dummyLen);
! if (code == ERROR_SUCCESS)
cm_daemonCheckOfflineVolInterval = dummy;
afsi_log("daemonCheckOfflineVolInterval is %d", cm_daemonCheckOfflineVolInterval);
RegCloseKey(parmKey);
}
/* periodic check daemon */
--- 281,350 ----
dummyLen = sizeof(DWORD);
code = RegQueryValueEx(parmKey, "daemonCheckDownInterval", NULL, NULL,
(BYTE *) &dummy, &dummyLen);
! if (code == ERROR_SUCCESS && dummy)
cm_daemonCheckDownInterval = dummy;
afsi_log("daemonCheckDownInterval is %d", cm_daemonCheckDownInterval);
dummyLen = sizeof(DWORD);
code = RegQueryValueEx(parmKey, "daemonCheckUpInterval", NULL, NULL,
(BYTE *) &dummy, &dummyLen);
! if (code == ERROR_SUCCESS && dummy)
cm_daemonCheckUpInterval = dummy;
afsi_log("daemonCheckUpInterval is %d", cm_daemonCheckUpInterval);
dummyLen = sizeof(DWORD);
code = RegQueryValueEx(parmKey, "daemonCheckVolInterval", NULL, NULL,
(BYTE *) &dummy, &dummyLen);
! if (code == ERROR_SUCCESS && dummy)
cm_daemonCheckVolInterval = dummy;
afsi_log("daemonCheckVolInterval is %d", cm_daemonCheckVolInterval);
dummyLen = sizeof(DWORD);
code = RegQueryValueEx(parmKey, "daemonCheckCBInterval", NULL, NULL,
(BYTE *) &dummy, &dummyLen);
! if (code == ERROR_SUCCESS && dummy)
cm_daemonCheckCBInterval = dummy;
afsi_log("daemonCheckCBInterval is %d", cm_daemonCheckCBInterval);
dummyLen = sizeof(DWORD);
code = RegQueryValueEx(parmKey, "daemonCheckVolCBInterval", NULL, NULL,
(BYTE *) &dummy, &dummyLen);
! if (code == ERROR_SUCCESS && dummy)
cm_daemonCheckVolCBInterval = dummy;
afsi_log("daemonCheckVolCBInterval is %d", cm_daemonCheckVolCBInterval);
dummyLen = sizeof(DWORD);
code = RegQueryValueEx(parmKey, "daemonCheckLockInterval", NULL, NULL,
(BYTE *) &dummy, &dummyLen);
! if (code == ERROR_SUCCESS && dummy)
cm_daemonCheckLockInterval = dummy;
afsi_log("daemonCheckLockInterval is %d", cm_daemonCheckLockInterval);
dummyLen = sizeof(DWORD);
code = RegQueryValueEx(parmKey, "daemonCheckTokenInterval", NULL, NULL,
(BYTE *) &dummy, &dummyLen);
! if (code == ERROR_SUCCESS && dummy)
cm_daemonTokenCheckInterval = dummy;
afsi_log("daemonCheckTokenInterval is %d", cm_daemonTokenCheckInterval);
dummyLen = sizeof(DWORD);
code = RegQueryValueEx(parmKey, "daemonCheckOfflineVolInterval", NULL, NULL,
(BYTE *) &dummy, &dummyLen);
! if (code == ERROR_SUCCESS && dummy)
cm_daemonCheckOfflineVolInterval = dummy;
afsi_log("daemonCheckOfflineVolInterval is %d", cm_daemonCheckOfflineVolInterval);
+ dummyLen = sizeof(DWORD);
+ code = RegQueryValueEx(parmKey, "daemonPerformanceTuningInterval", NULL, NULL,
+ (BYTE *) &dummy, &dummyLen);
+ if (code == ERROR_SUCCESS)
+ cm_daemonPerformanceTuningInterval = dummy;
+ afsi_log("daemonPerformanceTuningInterval is %d", cm_daemonPerformanceTuningInterval);
+
RegCloseKey(parmKey);
+
+ if (cm_daemonPerformanceTuningInterval)
+ cm_PerformanceTuningInit();
}
/* periodic check daemon */
***************
*** 342,347 ****
--- 359,365 ----
time_t lastUpServerCheck;
time_t lastTokenCacheCheck;
time_t lastBusyVolCheck;
+ time_t lastPerformanceCheck;
char thostName[200];
unsigned long code;
struct hostent *thp;
***************
*** 390,395 ****
--- 408,415 ----
lastUpServerCheck = now - cm_daemonCheckUpInterval/2 + (rand() % cm_daemonCheckUpInterval);
lastTokenCacheCheck = now - cm_daemonTokenCheckInterval/2 + (rand() % cm_daemonTokenCheckInterval);
lastBusyVolCheck = now - cm_daemonCheckOfflineVolInterval/2 * (rand() % cm_daemonCheckOfflineVolInterval);
+ if (cm_daemonPerformanceTuningInterval)
+ lastPerformanceCheck = now - cm_daemonPerformanceTuningInterval/2 * (rand() % cm_daemonPerformanceTuningInterval);
while (daemon_ShutdownFlag == 0) {
/* check to see if the listener threads halted due to network
***************
*** 540,546 ****
if (daemon_ShutdownFlag == 1) {
break;
}
! thrd_Sleep(10000); /* sleep 10 seconds */
}
thrd_SetEvent(cm_Daemon_ShutdownEvent);
}
--- 560,577 ----
if (daemon_ShutdownFlag == 1) {
break;
}
!
! if (cm_daemonPerformanceTuningInterval &&
! now > lastPerformanceCheck + cm_daemonPerformanceTuningInterval &&
! daemon_ShutdownFlag == 0) {
! lastPerformanceCheck = now;
! cm_PerformanceTuningCheck();
! if (daemon_ShutdownFlag == 1)
! break;
! now = osi_Time();
! }
!
! thrd_Sleep(10000); /* sleep 10 seconds */
}
thrd_SetEvent(cm_Daemon_ShutdownEvent);
}
Index: openafs/src/WINNT/afsd/cm_dcache.c
diff -c openafs/src/WINNT/afsd/cm_dcache.c:1.30.2.27 openafs/src/WINNT/afsd/cm_dcache.c:1.30.2.30
*** openafs/src/WINNT/afsd/cm_dcache.c:1.30.2.27 Sun Feb 24 01:33:20 2008
--- openafs/src/WINNT/afsd/cm_dcache.c Thu Mar 6 09:34:29 2008
***************
*** 83,91 ****
* buffer, although more likely it will just return a new, empty, buffer.
*/
! lock_ObtainMutex(&scp->mx);
if (scp->flags & CM_SCACHEFLAG_DELETED) {
! lock_ReleaseMutex(&scp->mx);
return CM_ERROR_NOSUCHFILE;
}
--- 83,91 ----
* buffer, although more likely it will just return a new, empty, buffer.
*/
! lock_ObtainWrite(&scp->rw);
if (scp->flags & CM_SCACHEFLAG_DELETED) {
! lock_ReleaseWrite(&scp->rw);
return CM_ERROR_NOSUCHFILE;
}
***************
*** 94,106 ****
code = cm_SetupStoreBIOD(scp, offsetp, length, &biod, userp, reqp);
if (code) {
osi_Log1(afsd_logp, "cm_SetupStoreBIOD code %x", code);
! lock_ReleaseMutex(&scp->mx);
return code;
}
if (biod.length == 0) {
osi_Log0(afsd_logp, "cm_SetupStoreBIOD length 0");
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseBIOD(&biod, 1, 0); /* should be a NOOP */
return 0;
}
--- 94,106 ----
code = cm_SetupStoreBIOD(scp, offsetp, length, &biod, userp, reqp);
if (code) {
osi_Log1(afsd_logp, "cm_SetupStoreBIOD code %x", code);
! lock_ReleaseWrite(&scp->rw);
return code;
}
if (biod.length == 0) {
osi_Log0(afsd_logp, "cm_SetupStoreBIOD length 0");
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseBIOD(&biod, 1, 0); /* should be a NOOP */
return 0;
}
***************
*** 145,151 ****
require_64bit_ops = 1;
}
! lock_ReleaseMutex(&scp->mx);
/* now we're ready to do the store operation */
do {
--- 145,151 ----
require_64bit_ops = 1;
}
! lock_ReleaseWrite(&scp->rw);
/* now we're ready to do the store operation */
do {
***************
*** 262,268 ****
osi_Log1(afsd_logp, "CALL StoreData SUCCESS scp 0x%p", scp);
/* now, clean up our state */
! lock_ObtainMutex(&scp->mx);
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_STOREDATA_EXCL);
--- 262,268 ----
osi_Log1(afsd_logp, "CALL StoreData SUCCESS scp 0x%p", scp);
/* now, clean up our state */
! lock_ObtainWrite(&scp->rw);
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_STOREDATA_EXCL);
***************
*** 304,310 ****
else if (code == CM_ERROR_QUOTA)
scp->flags |= CM_SCACHEFLAG_OVERQUOTA;
}
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseBIOD(&biod, 1, code);
return code;
--- 304,310 ----
else if (code == CM_ERROR_QUOTA)
scp->flags |= CM_SCACHEFLAG_OVERQUOTA;
}
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseBIOD(&biod, 1, code);
return code;
***************
*** 350,356 ****
require_64bit_ops = 1;
}
! lock_ReleaseMutex(&scp->mx);
cm_AFSFidFromFid(&tfid, &scp->fid);
--- 350,356 ----
require_64bit_ops = 1;
}
! lock_ReleaseWrite(&scp->rw);
cm_AFSFidFromFid(&tfid, &scp->fid);
***************
*** 401,407 ****
code = cm_MapRPCError(code, reqp);
/* now, clean up our state */
! lock_ObtainMutex(&scp->mx);
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_STOREDATA_EXCL);
--- 401,407 ----
code = cm_MapRPCError(code, reqp);
/* now, clean up our state */
! lock_ObtainWrite(&scp->rw);
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_STOREDATA_EXCL);
***************
*** 442,452 ****
cm_scache_t *scp = vscp;
long code;
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_SETSIZE);
if (code) {
! lock_ReleaseMutex(&scp->mx);
return code;
}
--- 442,452 ----
cm_scache_t *scp = vscp;
long code;
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_SETSIZE);
if (code) {
! lock_ReleaseWrite(&scp->rw);
return code;
}
***************
*** 460,466 ****
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_SETSIZE);
! lock_ReleaseMutex(&scp->mx);
/* always succeeds */
return 0;
--- 460,466 ----
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_SETSIZE);
! lock_ReleaseWrite(&scp->rw);
/* always succeeds */
return 0;
***************
*** 549,562 ****
tlength = *length;
tblocksize = ConvertLongToLargeInteger(cm_data.buf_blockSize);
stop = 0;
! lock_ObtainMutex(&scp->mx);
while (LargeIntegerGreaterThanZero(tlength)) {
/* get callback so we can do a meaningful dataVersion comparison */
code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
scp->flags &= ~CM_SCACHEFLAG_PREFETCHING;
! lock_ReleaseMutex(&scp->mx);
return code;
}
--- 549,562 ----
tlength = *length;
tblocksize = ConvertLongToLargeInteger(cm_data.buf_blockSize);
stop = 0;
! lock_ObtainWrite(&scp->rw);
while (LargeIntegerGreaterThanZero(tlength)) {
/* get callback so we can do a meaningful dataVersion comparison */
code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
scp->flags &= ~CM_SCACHEFLAG_PREFETCHING;
! lock_ReleaseWrite(&scp->rw);
return code;
}
***************
*** 569,575 ****
/* We cheat slightly by not locking the bp mutex. */
if (bp) {
if ((bp->cmFlags & (CM_BUF_CMFETCHING | CM_BUF_CMSTORING)) == 0
! && bp->dataVersion != scp->dataVersion)
stop = 1;
buf_Release(bp);
bp = NULL;
--- 569,575 ----
/* We cheat slightly by not locking the bp mutex. */
if (bp) {
if ((bp->cmFlags & (CM_BUF_CMFETCHING | CM_BUF_CMSTORING)) == 0
! && (bp->dataVersion < scp->bufDataVersionLow || bp->dataVersion > scp->dataVersion))
stop = 1;
buf_Release(bp);
bp = NULL;
***************
*** 600,606 ****
*realBasep = tbase;
code = 0;
}
! lock_ReleaseMutex(&scp->mx);
return code;
}
--- 600,606 ----
*realBasep = tbase;
code = 0;
}
! lock_ReleaseWrite(&scp->rw);
return code;
}
***************
*** 632,641 ****
osi_Log4(afsd_logp, "Finished BKG store scp 0x%p, offset 0x%x:%08x, code 0x%x", scp, p2, p1, code);
}
! lock_ObtainMutex(&scp->mx);
! cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_ASYNCSTORE);
! lock_ReleaseMutex(&scp->mx);
!
return code;
}
--- 632,656 ----
osi_Log4(afsd_logp, "Finished BKG store scp 0x%p, offset 0x%x:%08x, code 0x%x", scp, p2, p1, code);
}
! /*
! * Keep the following list synchronized with the
! * error code list in cm_BkgDaemon
! */
! switch ( code ) {
! case CM_ERROR_TIMEDOUT: /* or server restarting */
! case CM_ERROR_RETRY:
! case CM_ERROR_WOULDBLOCK:
! case CM_ERROR_ALLBUSY:
! case CM_ERROR_ALLDOWN:
! case CM_ERROR_ALLOFFLINE:
! case CM_ERROR_PARTIALWRITE:
! break; /* cm_BkgDaemon will re-insert the request in the queue */
! case 0:
! default:
! lock_ObtainWrite(&scp->rw);
! cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_ASYNCSTORE);
! lock_ReleaseWrite(&scp->rw);
! }
return code;
}
***************
*** 693,699 ****
offset = LargeIntegerAdd(offset, tblocksize) )
{
if (mxheld) {
! lock_ReleaseMutex(&scp->mx);
mxheld = 0;
}
--- 708,714 ----
offset = LargeIntegerAdd(offset, tblocksize) )
{
if (mxheld) {
! lock_ReleaseWrite(&scp->rw);
mxheld = 0;
}
***************
*** 709,715 ****
}
if (!mxheld) {
! lock_ObtainMutex(&scp->mx);
mxheld = 1;
}
--- 724,730 ----
}
if (!mxheld) {
! lock_ObtainWrite(&scp->rw);
mxheld = 1;
}
***************
*** 720,731 ****
}
if (!mxheld) {
! lock_ObtainMutex(&scp->mx);
mxheld = 1;
}
cm_ClearPrefetchFlag(LargeIntegerGreaterThanZero(fetched) ? 0 : code,
scp, &base, &fetched);
! lock_ReleaseMutex(&scp->mx);
osi_Log4(afsd_logp, "Ending BKG prefetch scp 0x%p, code %d bytes 0x%x:%x",
scp, code, fetched.HighPart, fetched.LowPart);
--- 735,746 ----
}
if (!mxheld) {
! lock_ObtainWrite(&scp->rw);
mxheld = 1;
}
cm_ClearPrefetchFlag(LargeIntegerGreaterThanZero(fetched) ? 0 : code,
scp, &base, &fetched);
! lock_ReleaseWrite(&scp->rw);
osi_Log4(afsd_logp, "Ending BKG prefetch scp 0x%p, code %d bytes 0x%x:%x",
scp, code, fetched.HighPart, fetched.LowPart);
***************
*** 750,759 ****
readLength = ConvertLongToLargeInteger(count);
! lock_ObtainMutex(&scp->mx);
if ((scp->flags & CM_SCACHEFLAG_PREFETCHING)
|| LargeIntegerLessThanOrEqualTo(readBase, scp->prefetch.base)) {
! lock_ReleaseMutex(&scp->mx);
return;
}
scp->flags |= CM_SCACHEFLAG_PREFETCHING;
--- 765,774 ----
readLength = ConvertLongToLargeInteger(count);
! lock_ObtainWrite(&scp->rw);
if ((scp->flags & CM_SCACHEFLAG_PREFETCHING)
|| LargeIntegerLessThanOrEqualTo(readBase, scp->prefetch.base)) {
! lock_ReleaseWrite(&scp->rw);
return;
}
scp->flags |= CM_SCACHEFLAG_PREFETCHING;
***************
*** 764,770 ****
if (LargeIntegerGreaterThan(scp->prefetch.end, readBase))
readBase = scp->prefetch.end;
! lock_ReleaseMutex(&scp->mx);
code = cm_CheckFetchRange(scp, &readBase, &readLength, userp, reqp,
&realBase);
--- 779,785 ----
if (LargeIntegerGreaterThan(scp->prefetch.end, readBase))
readBase = scp->prefetch.end;
! lock_ReleaseWrite(&scp->rw);
code = cm_CheckFetchRange(scp, &readBase, &readLength, userp, reqp,
&realBase);
***************
*** 814,822 ****
biop->reserved = 0;
/* reserve a chunk's worth of buffers */
! lock_ReleaseMutex(&scp->mx);
buf_ReserveBuffers(cm_chunkSize / cm_data.buf_blockSize);
! lock_ObtainMutex(&scp->mx);
bufp = NULL;
for (temp = 0; temp < inSize; temp += cm_data.buf_blockSize) {
--- 829,837 ----
biop->reserved = 0;
/* reserve a chunk's worth of buffers */
! lock_ReleaseWrite(&scp->rw);
buf_ReserveBuffers(cm_chunkSize / cm_data.buf_blockSize);
! lock_ObtainWrite(&scp->rw);
bufp = NULL;
for (temp = 0; temp < inSize; temp += cm_data.buf_blockSize) {
***************
*** 826,834 ****
bufp = buf_Find(scp, &tbase);
if (bufp) {
/* get buffer mutex and scp mutex safely */
! lock_ReleaseMutex(&scp->mx);
lock_ObtainMutex(&bufp->mx);
! lock_ObtainMutex(&scp->mx);
flags = CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_STOREDATA | CM_SCACHESYNC_BUFLOCKED;
code = cm_SyncOp(scp, bufp, userp, reqp, 0, flags);
--- 841,849 ----
bufp = buf_Find(scp, &tbase);
if (bufp) {
/* get buffer mutex and scp mutex safely */
! lock_ReleaseWrite(&scp->rw);
lock_ObtainMutex(&bufp->mx);
! lock_ObtainWrite(&scp->rw);
flags = CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_STOREDATA | CM_SCACHESYNC_BUFLOCKED;
code = cm_SyncOp(scp, bufp, userp, reqp, 0, flags);
***************
*** 902,910 ****
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);
bufp = NULL;
--- 917,925 ----
break;
/* try to lock it, and quit if we can't (simplifies locking) */
! lock_ReleaseWrite(&scp->rw);
code = lock_TryMutex(&bufp->mx);
! lock_ObtainWrite(&scp->rw);
if (code == 0) {
buf_Release(bufp);
bufp = NULL;
***************
*** 962,970 ****
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);
bufp = NULL;
--- 977,985 ----
break;
/* try to lock it, and quit if we can't (simplifies locking) */
! lock_ReleaseWrite(&scp->rw);
code = lock_TryMutex(&bufp->mx);
! lock_ObtainWrite(&scp->rw);
if (code == 0) {
buf_Release(bufp);
bufp = NULL;
***************
*** 1053,1059 ****
/* copy out size, since it may change */
fileSize = scp->serverLength;
! lock_ReleaseMutex(&scp->mx);
pageBase = *offsetp;
collected = pageBase.LowPart & (cm_chunkSize - 1);
--- 1068,1074 ----
/* copy out size, since it may change */
fileSize = scp->serverLength;
! lock_ReleaseWrite(&scp->rw);
pageBase = *offsetp;
collected = pageBase.LowPart & (cm_chunkSize - 1);
***************
*** 1093,1099 ****
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;
}
--- 1108,1114 ----
code = buf_Get(scp, &pageBase, &tbp);
if (code) {
//lock_ReleaseMutex(&cm_bufGetMutex);
! lock_ObtainWrite(&scp->rw);
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
return code;
}
***************
*** 1158,1169 ****
/* now lock the buffer lock */
lock_ObtainMutex(&tbp->mx);
! lock_ObtainMutex(&scp->mx);
/* don't bother fetching over data that is already current */
if (tbp->dataVersion <= scp->dataVersion && tbp->dataVersion >= scp->bufDataVersionLow) {
/* we don't need this buffer, since it is current */
! lock_ReleaseMutex(&scp->mx);
lock_ReleaseMutex(&tbp->mx);
break;
}
--- 1173,1184 ----
/* now lock the buffer lock */
lock_ObtainMutex(&tbp->mx);
! lock_ObtainWrite(&scp->rw);
/* don't bother fetching over data that is already current */
if (tbp->dataVersion <= scp->dataVersion && tbp->dataVersion >= scp->bufDataVersionLow) {
/* we don't need this buffer, since it is current */
! lock_ReleaseWrite(&scp->rw);
lock_ReleaseMutex(&tbp->mx);
break;
}
***************
*** 1177,1183 ****
*/
code = cm_SyncOp(scp, tbp, userp, reqp, 0, flags);
if (code) {
! lock_ReleaseMutex(&scp->mx);
lock_ReleaseMutex(&tbp->mx);
break;
}
--- 1192,1198 ----
*/
code = cm_SyncOp(scp, tbp, userp, reqp, 0, flags);
if (code) {
! lock_ReleaseWrite(&scp->rw);
lock_ReleaseMutex(&tbp->mx);
break;
}
***************
*** 1185,1197 ****
/* don't fetch over dirty buffers */
if (tbp->flags & CM_BUF_DIRTY) {
cm_SyncOpDone(scp, tbp, flags);
! lock_ReleaseMutex(&scp->mx);
lock_ReleaseMutex(&tbp->mx);
break;
}
/* Release locks */
! lock_ReleaseMutex(&scp->mx);
lock_ReleaseMutex(&tbp->mx);
/* add the buffer to the list */
--- 1200,1212 ----
/* don't fetch over dirty buffers */
if (tbp->flags & CM_BUF_DIRTY) {
cm_SyncOpDone(scp, tbp, flags);
! lock_ReleaseWrite(&scp->rw);
lock_ReleaseMutex(&tbp->mx);
break;
}
/* Release locks */
! lock_ReleaseWrite(&scp->rw);
lock_ReleaseMutex(&tbp->mx);
/* add the buffer to the list */
***************
*** 1225,1231 ****
}
/* Caller expects this */
! lock_ObtainMutex(&scp->mx);
/* if we got a failure setting up the first buffer, then we don't have
* any side effects yet, and we also have failed an operation that the
--- 1240,1246 ----
}
/* Caller expects this */
! lock_ObtainWrite(&scp->rw);
/* if we got a failure setting up the first buffer, then we don't have
* any side effects yet, and we also have failed an operation that the
***************
*** 1279,1285 ****
/* now, mark I/O as done, unlock the buffer and release it */
lock_ObtainMutex(&bufp->mx);
! lock_ObtainMutex(&scp->mx);
cm_SyncOpDone(scp, bufp, flags);
/* turn off writing and wakeup users */
--- 1294,1300 ----
/* now, mark I/O as done, unlock the buffer and release it */
lock_ObtainMutex(&bufp->mx);
! lock_ObtainWrite(&scp->rw);
cm_SyncOpDone(scp, bufp, flags);
/* turn off writing and wakeup users */
***************
*** 1296,1310 ****
}
}
! lock_ReleaseMutex(&scp->mx);
lock_ReleaseMutex(&bufp->mx);
buf_Release(bufp);
bufp = NULL;
}
} else {
! lock_ObtainMutex(&scp->mx);
cm_SyncOpDone(scp, NULL, flags);
! lock_ReleaseMutex(&scp->mx);
}
/* clean things out */
--- 1311,1325 ----
}
}
! lock_ReleaseWrite(&scp->rw);
lock_ReleaseMutex(&bufp->mx);
buf_Release(bufp);
bufp = NULL;
}
} else {
! lock_ObtainWrite(&scp->rw);
cm_SyncOpDone(scp, NULL, flags);
! lock_ReleaseWrite(&scp->rw);
}
/* clean things out */
***************
*** 1377,1399 ****
* which case we just retry.
*/
if (bufp->dataVersion <= scp->dataVersion && bufp->dataVersion >= scp->bufDataVersionLow || biod.length == 0) {
! if ((bufp->dataVersion == -1 || bufp->dataVersion < scp->dataVersion) &&
LargeIntegerGreaterThanOrEqualTo(bufp->offset, scp->serverLength))
{
! osi_Log3(afsd_logp, "Bad DVs %I64d, %I64d or length 0x%x",
! bufp->dataVersion, scp->dataVersion, biod.length);
! if (bufp->dataVersion == -1)
memset(bufp->datap, 0, cm_data.buf_blockSize);
bufp->dataVersion = scp->dataVersion;
}
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseBIOD(&biod, 0, 0);
! lock_ObtainMutex(&scp->mx);
return 0;
}
! lock_ReleaseMutex(&scp->mx);
if (LargeIntegerGreaterThan(LargeIntegerAdd(biod.offset,
ConvertLongToLargeInteger(biod.length)),
--- 1392,1423 ----
* which case we just retry.
*/
if (bufp->dataVersion <= scp->dataVersion && bufp->dataVersion >= scp->bufDataVersionLow || biod.length == 0) {
! if ((bufp->dataVersion == CM_BUF_VERSION_BAD || bufp->dataVersion < scp->bufDataVersionLow) &&
LargeIntegerGreaterThanOrEqualTo(bufp->offset, scp->serverLength))
{
! osi_Log4(afsd_logp, "Bad DVs 0x%x != (0x%x -> 0x%x) or length 0x%x",
! bufp->dataVersion, scp->bufDataVersionLow, scp->dataVersion, biod.length);
! if (bufp->dataVersion == CM_BUF_VERSION_BAD)
memset(bufp->datap, 0, cm_data.buf_blockSize);
bufp->dataVersion = scp->dataVersion;
}
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseBIOD(&biod, 0, 0);
! lock_ObtainWrite(&scp->rw);
! return 0;
! } else if ((bufp->dataVersion == CM_BUF_VERSION_BAD || bufp->dataVersion < scp->bufDataVersionLow)
! && (scp->mask & CM_SCACHEMASK_TRUNCPOS) &&
! LargeIntegerGreaterThanOrEqualTo(bufp->offset, scp->truncPos)) {
! memset(bufp->datap, 0, cm_data.buf_blockSize);
! bufp->dataVersion = scp->dataVersion;
! lock_ReleaseWrite(&scp->rw);
! cm_ReleaseBIOD(&biod, 0, 0);
! lock_ObtainWrite(&scp->rw);
return 0;
}
! lock_ReleaseWrite(&scp->rw);
if (LargeIntegerGreaterThan(LargeIntegerAdd(biod.offset,
ConvertLongToLargeInteger(biod.length)),
***************
*** 1401,1410 ****
require_64bit_ops = 1;
}
! #ifdef DISKCACHE95
! DPRINTF("cm_GetBuffer: fetching data scpDV=%I64d bufDV=%I64d scp=%x bp=%x dcp=%x\n",
! scp->dataVersion, bufp->dataVersion, scp, bufp, bufp->dcp);
! #endif /* DISKCACHE95 */
#ifdef AFS_FREELANCE_CLIENT
--- 1425,1433 ----
require_64bit_ops = 1;
}
! osi_Log2(afsd_logp, "cm_GetBuffer: fetching data scp %p bufp %p", scp, bufp);
! osi_Log3(afsd_logp, "cm_GetBuffer: fetching data scpDV 0x%x scpDVLow 0x%x bufDV 0x%x",
! scp->dataVersion, scp->bufDataVersionLow, bufp->dataVersion);
#ifdef AFS_FREELANCE_CLIENT
***************
*** 1593,1599 ****
* this buffer will start a prefetch.
*/
tbufp->cmFlags |= CM_BUF_CMFULLYFETCHED;
! lock_ObtainMutex(&scp->mx);
if (scp->flags & CM_SCACHEFLAG_WAITING) {
osi_Log1(afsd_logp, "CM GetBuffer Waking scp 0x%p", scp);
osi_Wakeup((LONG_PTR) &scp->flags);
--- 1616,1622 ----
* this buffer will start a prefetch.
*/
tbufp->cmFlags |= CM_BUF_CMFULLYFETCHED;
! lock_ObtainWrite(&scp->rw);
if (scp->flags & CM_SCACHEFLAG_WAITING) {
osi_Log1(afsd_logp, "CM GetBuffer Waking scp 0x%p", scp);
osi_Wakeup((LONG_PTR) &scp->flags);
***************
*** 1603,1609 ****
*cpffp = 1;
cm_ClearPrefetchFlag(0, scp, &biod.offset, &tlength);
}
! lock_ReleaseMutex(&scp->mx);
/* and adjust counters */
nbytes -= temp;
--- 1626,1632 ----
*cpffp = 1;
cm_ClearPrefetchFlag(0, scp, &biod.offset, &tlength);
}
! lock_ReleaseWrite(&scp->rw);
/* and adjust counters */
nbytes -= temp;
***************
*** 1671,1677 ****
fetchingcompleted:
code = cm_MapRPCError(code, reqp);
! lock_ObtainMutex(&scp->mx);
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_FETCHSTATUS);
--- 1694,1700 ----
fetchingcompleted:
code = cm_MapRPCError(code, reqp);
! lock_ObtainWrite(&scp->rw);
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_FETCHSTATUS);
***************
*** 1698,1706 ****
}
/* release scatter/gather I/O structure (buffers, locks) */
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseBIOD(&biod, 0, code);
! lock_ObtainMutex(&scp->mx);
if (code == 0)
cm_MergeStatus(NULL, scp, &afsStatus, &volSync, userp, 0);
--- 1721,1729 ----
}
/* release scatter/gather I/O structure (buffers, locks) */
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseBIOD(&biod, 0, code);
! lock_ObtainWrite(&scp->rw);
if (code == 0)
cm_MergeStatus(NULL, scp, &afsStatus, &volSync, userp, 0);
Index: openafs/src/WINNT/afsd/cm_dcache.h
diff -c openafs/src/WINNT/afsd/cm_dcache.h:1.4.4.5 openafs/src/WINNT/afsd/cm_dcache.h:1.4.4.6
*** openafs/src/WINNT/afsd/cm_dcache.h:1.4.4.5 Fri Feb 22 19:17:34 2008
--- openafs/src/WINNT/afsd/cm_dcache.h Thu Feb 28 12:17:15 2008
***************
*** 57,60 ****
--- 57,63 ----
extern long cm_ShutdownDCache(void);
+ extern long cm_BufWrite(void *vscp, osi_hyper_t *offsetp, long length, long flags,
+ cm_user_t *userp, cm_req_t *reqp);
+
#endif /* __CM_DCACHE_ENV__ */
Index: openafs/src/WINNT/afsd/cm_dir.c
diff -c openafs/src/WINNT/afsd/cm_dir.c:1.4.4.11 openafs/src/WINNT/afsd/cm_dir.c:1.4.4.14
*** openafs/src/WINNT/afsd/cm_dir.c:1.4.4.11 Fri Feb 22 19:17:34 2008
--- openafs/src/WINNT/afsd/cm_dir.c Sun Mar 2 23:25:40 2008
***************
*** 136,145 ****
entry is a string name.
On entry:
! op->scp->mx is unlocked
On exit:
! op->scp->mx is unlocked
None of the directory buffers for op->scp should be locked by the
calling thread.
--- 136,145 ----
entry is a string name.
On entry:
! op->scp->rw is unlocked
On exit:
! op->scp->rw is unlocked
None of the directory buffers for op->scp should be locked by the
calling thread.
***************
*** 234,243 ****
/* Return the length of a directory in pages
On entry:
! op->scp->mx is locked
On exit:
! op->scp->mx is locked
The first directory page for op->scp should not be locked by the
calling thread.
--- 234,243 ----
/* Return the length of a directory in pages
On entry:
! op->scp->rw is locked
On exit:
! op->scp->rw is locked
The first directory page for op->scp should not be locked by the
calling thread.
***************
*** 271,280 ****
/* Delete a directory entry.
On entry:
! op->scp->mx is unlocked
On exit:
! op->scp->mx is unlocked
None of the directory buffers for op->scp should be locked by the
calling thread.
--- 271,280 ----
/* Delete a directory entry.
On entry:
! op->scp->rw is unlocked
On exit:
! op->scp->rw is unlocked
None of the directory buffers for op->scp should be locked by the
calling thread.
***************
*** 340,346 ****
/* Find a bunch of contiguous entries; at least nblobs in a row.
! Called with op->scp->mx */
static long
cm_DirFindBlobs(cm_dirOp_t * op, int nblobs)
{
--- 340,346 ----
/* Find a bunch of contiguous entries; at least nblobs in a row.
! Called with op->scp->rw */
static long
cm_DirFindBlobs(cm_dirOp_t * op, int nblobs)
{
***************
*** 444,450 ****
/* Add a page to a directory.
! Called with op->scp->mx
*/
static long
cm_DirAddPage(cm_dirOp_t * op, int pageno)
--- 444,450 ----
/* Add a page to a directory.
! Called with op->scp->rw
*/
static long
cm_DirAddPage(cm_dirOp_t * op, int pageno)
***************
*** 477,483 ****
/* Free a whole bunch of directory entries.
! Called with op->scp->mx
*/
static long
cm_DirFreeBlobs(cm_dirOp_t * op, int firstblob, int nblobs)
--- 477,483 ----
/* Free a whole bunch of directory entries.
! Called with op->scp->rw
*/
static long
cm_DirFreeBlobs(cm_dirOp_t * op, int firstblob, int nblobs)
***************
*** 528,534 ****
* directory header page are allocated, 1 to the page header, 4 to the
* allocation map and 8 to the hash table.
*
! * Called with op->scp->mx unlocked
*/
int
cm_DirMakeDir(cm_dirOp_t * op, cm_fid_t * me, cm_fid_t * parent)
--- 528,534 ----
* directory header page are allocated, 1 to the page header, 4 to the
* allocation map and 8 to the hash table.
*
! * Called with op->scp->rw unlocked
*/
int
cm_DirMakeDir(cm_dirOp_t * op, cm_fid_t * me, cm_fid_t * parent)
***************
*** 577,586 ****
/* Look up a file name in directory.
On entry:
! op->scp->mx is unlocked
On exit:
! op->scp->mx is unlocked
None of the directory buffers for op->scp should be locked by the
calling thread.
--- 577,586 ----
/* Look up a file name in directory.
On entry:
! op->scp->rw is unlocked
On exit:
! op->scp->rw is unlocked
None of the directory buffers for op->scp should be locked by the
calling thread.
***************
*** 636,645 ****
/* Look up a file name in directory.
On entry:
! op->scp->mx is locked
On exit:
! op->scp->mx is locked
None of the directory buffers for op->scp should be locked by the
calling thread.
--- 636,645 ----
/* Look up a file name in directory.
On entry:
! op->scp->rw is locked
On exit:
! op->scp->rw is locked
None of the directory buffers for op->scp should be locked by the
calling thread.
***************
*** 694,703 ****
/* Apply a function to every directory entry in a directory.
On entry:
! op->scp->mx is locked
On exit:
! op->scp->mx is locked
None of the directory buffers for op->scp should be locked by the
calling thread.
--- 694,703 ----
/* Apply a function to every directory entry in a directory.
On entry:
! op->scp->rw is locked
On exit:
! op->scp->rw is locked
None of the directory buffers for op->scp should be locked by the
calling thread.
***************
*** 749,758 ****
/* Check if a directory is empty
On entry:
! op->scp->mx is locked
On exit:
! op->scp->mx is locked
None of the directory buffers for op->scp should be locked by the
calling thread.
--- 749,758 ----
/* Check if a directory is empty
On entry:
! op->scp->rw is locked
On exit:
! op->scp->rw is locked
None of the directory buffers for op->scp should be locked by the
calling thread.
***************
*** 802,816 ****
/* Return a pointer to an entry, given its number.
On entry:
! scp->mx locked
if *bufferpp != NULL, then *bufferpp->mx is locked
During:
! scp->mx may be unlocked
*bufferpp may be released
On exit:
! scp->mx locked
if *bufferpp != NULL, then *bufferpp->mx is locked
*bufferpp should be released via cm_DirReleasePage() or any other
--- 802,816 ----
/* Return a pointer to an entry, given its number.
On entry:
! scp->rw locked
if *bufferpp != NULL, then *bufferpp->mx is locked
During:
! scp->rw may be unlocked
*bufferpp may be released
On exit:
! scp->rw locked
if *bufferpp != NULL, then *bufferpp->mx is locked
*bufferpp should be released via cm_DirReleasePage() or any other
***************
*** 863,872 ****
* pointer is returned instead.
*
* On entry:
! * scp->mx locked
*
* On exit:
! * scp->mx locked
*/
static long
cm_DirFindItem(cm_dirOp_t * op,
--- 863,872 ----
* pointer is returned instead.
*
* On entry:
! * scp->rw locked
*
* On exit:
! * scp->rw locked
*/
static long
cm_DirFindItem(cm_dirOp_t * op,
***************
*** 959,965 ****
}
/* Begin a sequence of directory operations.
! * Called with scp->mx unlocked.
*/
long
cm_BeginDirOp(cm_scache_t * scp, cm_user_t * userp, cm_req_t * reqp,
--- 959,965 ----
}
/* Begin a sequence of directory operations.
! * Called with scp->rw unlocked.
*/
long
cm_BeginDirOp(cm_scache_t * scp, cm_user_t * userp, cm_req_t * reqp,
***************
*** 993,999 ****
lock_ObtainRead(&scp->dirlock);
haveWrite = 0;
}
! lock_ObtainMutex(&scp->mx);
mxheld = 1;
code = cm_DirCheckStatus(op, 1);
if (code == 0) {
--- 993,999 ----
lock_ObtainRead(&scp->dirlock);
haveWrite = 0;
}
! lock_ObtainWrite(&scp->rw);
mxheld = 1;
code = cm_DirCheckStatus(op, 1);
if (code == 0) {
***************
*** 1029,1043 ****
repeat:
if (!haveWrite) {
if (mxheld) {
! lock_ReleaseMutex(&scp->mx);
mxheld = 0;
}
! lock_ReleaseRead(&scp->dirlock);
! lock_ObtainWrite(&scp->dirlock);
haveWrite = 1;
}
if (!mxheld) {
! lock_ObtainMutex(&scp->mx);
mxheld = 1;
}
if (scp->dirBplus &&
--- 1029,1042 ----
repeat:
if (!haveWrite) {
if (mxheld) {
! lock_ReleaseWrite(&scp->rw);
mxheld = 0;
}
! lock_ConvertRToW(&scp->dirlock);
haveWrite = 1;
}
if (!mxheld) {
! lock_ObtainWrite(&scp->rw);
mxheld = 1;
}
if (scp->dirBplus &&
***************
*** 1052,1063 ****
if (!scp->dirBplus) {
if (mxheld) {
! lock_ReleaseMutex(&scp->mx);
mxheld = 0;
}
cm_BPlusDirBuildTree(scp, userp, reqp);
if (!mxheld) {
! lock_ObtainMutex(&scp->mx);
mxheld = 1;
}
if (op->dataVersion != scp->dataVersion) {
--- 1051,1062 ----
if (!scp->dirBplus) {
if (mxheld) {
! lock_ReleaseWrite(&scp->rw);
mxheld = 0;
}
cm_BPlusDirBuildTree(scp, userp, reqp);
if (!mxheld) {
! lock_ObtainWrite(&scp->rw);
mxheld = 1;
}
if (op->dataVersion != scp->dataVersion) {
***************
*** 1108,1121 ****
#endif
op->lockType = lockType;
if (mxheld)
! lock_ReleaseMutex(&scp->mx);
} else {
if (haveWrite)
lock_ReleaseWrite(&scp->dirlock);
else
lock_ReleaseRead(&scp->dirlock);
if (mxheld)
! lock_ReleaseMutex(&scp->mx);
cm_EndDirOp(op);
}
--- 1107,1120 ----
#endif
op->lockType = lockType;
if (mxheld)
! lock_ReleaseWrite(&scp->rw);
} else {
if (haveWrite)
lock_ReleaseWrite(&scp->dirlock);
else
lock_ReleaseRead(&scp->dirlock);
if (mxheld)
! lock_ReleaseWrite(&scp->rw);
cm_EndDirOp(op);
}
***************
*** 1123,1129 ****
}
/* Check if it is safe for us to perform local directory updates.
! Called with scp->mx unlocked. */
int
cm_CheckDirOpForSingleChange(cm_dirOp_t * op)
{
--- 1122,1128 ----
}
/* Check if it is safe for us to perform local directory updates.
! Called with scp->rw unlocked. */
int
cm_CheckDirOpForSingleChange(cm_dirOp_t * op)
{
***************
*** 1133,1139 ****
if (op->scp == NULL)
return 0;
! lock_ObtainMutex(&op->scp->mx);
code = cm_DirCheckStatus(op, 1);
if (code == 0 &&
--- 1132,1138 ----
if (op->scp == NULL)
return 0;
! lock_ObtainWrite(&op->scp->rw);
code = cm_DirCheckStatus(op, 1);
if (code == 0 &&
***************
*** 1146,1164 ****
rc = 1;
}
! lock_ReleaseMutex(&op->scp->mx);
if (rc)
osi_Log0(afsd_logp, "cm_CheckDirOpForSingleChange succeeded");
else
osi_Log3(afsd_logp,
! "cm_CheckDirOpForSingleChange failed. code=0x%x, old dv=%I64d, new dv=%I64d",
code, op->dataVersion, op->scp->dataVersion);
return rc;
}
/* End a sequence of directory operations.
! * Called with op->scp->mx unlocked.*/
long
cm_EndDirOp(cm_dirOp_t * op)
{
--- 1145,1163 ----
rc = 1;
}
! lock_ReleaseWrite(&op->scp->rw);
if (rc)
osi_Log0(afsd_logp, "cm_CheckDirOpForSingleChange succeeded");
else
osi_Log3(afsd_logp,
! "cm_CheckDirOpForSingleChange failed. code=0x%x, old dv=%d, new dv=%d",
code, op->dataVersion, op->scp->dataVersion);
return rc;
}
/* End a sequence of directory operations.
! * Called with op->scp->rw unlocked.*/
long
cm_EndDirOp(cm_dirOp_t * op)
{
***************
*** 1194,1202 ****
/* we made changes. We should go through the list of buffers
* and update the dataVersion for each. */
! lock_ObtainMutex(&op->scp->mx);
code = buf_ForceDataVersion(op->scp, op->dataVersion, op->newDataVersion);
! lock_ReleaseMutex(&op->scp->mx);
}
switch (op->lockType) {
--- 1193,1201 ----
/* we made changes. We should go through the list of buffers
* and update the dataVersion for each. */
! lock_ObtainWrite(&op->scp->rw);
code = buf_ForceDataVersion(op->scp, op->dataVersion, op->newDataVersion);
! lock_ReleaseWrite(&op->scp->rw);
}
switch (op->lockType) {
***************
*** 1223,1229 ****
return code;
}
! /* NOTE: Called without scp->mx and without bufferp->mx */
static long
cm_DirOpAddBuffer(cm_dirOp_t * op, cm_buf_t * bufferp)
{
--- 1222,1228 ----
return code;
}
! /* NOTE: Called without scp->rw and without bufferp->mx */
static long
cm_DirOpAddBuffer(cm_dirOp_t * op, cm_buf_t * bufferp)
{
***************
*** 1262,1268 ****
osi_assert(i < CM_DIROP_MAXBUFFERS);
lock_ObtainMutex(&bufferp->mx);
! lock_ObtainMutex(&op->scp->mx);
/* Make sure we are synchronized. */
osi_assert(op->lockType != CM_DIRLOCK_NONE);
--- 1261,1267 ----
osi_assert(i < CM_DIROP_MAXBUFFERS);
lock_ObtainMutex(&bufferp->mx);
! lock_ObtainWrite(&op->scp->rw);
/* Make sure we are synchronized. */
osi_assert(op->lockType != CM_DIRLOCK_NONE);
***************
*** 1273,1279 ****
CM_SCACHESYNC_BUFLOCKED);
if (code == 0 && bufferp->dataVersion != op->dataVersion) {
! osi_Log2(afsd_logp, "cm_DirOpAddBuffer: buffer data version mismatch. buf dv = %I64d. needs %I64d",
bufferp->dataVersion, op->dataVersion);
cm_SyncOpDone(op->scp, bufferp,
--- 1272,1278 ----
CM_SCACHESYNC_BUFLOCKED);
if (code == 0 && bufferp->dataVersion != op->dataVersion) {
! osi_Log2(afsd_logp, "cm_DirOpAddBuffer: buffer data version mismatch. buf dv = %d. needs %d",
bufferp->dataVersion, op->dataVersion);
cm_SyncOpDone(op->scp, bufferp,
***************
*** 1284,1290 ****
code = CM_ERROR_INVAL;
}
! lock_ReleaseMutex(&op->scp->mx);
lock_ReleaseMutex(&bufferp->mx);
if (code) {
--- 1283,1289 ----
code = CM_ERROR_INVAL;
}
! lock_ReleaseWrite(&op->scp->rw);
lock_ReleaseMutex(&bufferp->mx);
if (code) {
***************
*** 1306,1312 ****
}
}
! /* Note: Called without op->scp->mx */
static int
cm_DirOpFindBuffer(cm_dirOp_t * op, osi_hyper_t offset, cm_buf_t ** bufferpp)
{
--- 1305,1311 ----
}
}
! /* Note: Called without op->scp->rw */
static int
cm_DirOpFindBuffer(cm_dirOp_t * op, osi_hyper_t offset, cm_buf_t ** bufferpp)
{
***************
*** 1335,1341 ****
}
! /* NOTE: called with scp->mx held or not depending on the flags */
static int
cm_DirOpDelBuffer(cm_dirOp_t * op, cm_buf_t * bufferp, int flags)
{
--- 1334,1340 ----
}
! /* NOTE: called with scp->rw held or not depending on the flags */
static int
cm_DirOpDelBuffer(cm_dirOp_t * op, cm_buf_t * bufferp, int flags)
{
***************
*** 1367,1373 ****
version of the buffer with the data version of the
scp. */
if (!(flags & DIROP_SCPLOCKED)) {
! lock_ObtainMutex(&op->scp->mx);
}
/* first make sure that the buffer is idle. It should
--- 1366,1372 ----
version of the buffer with the data version of the
scp. */
if (!(flags & DIROP_SCPLOCKED)) {
! lock_ObtainWrite(&op->scp->rw);
}
/* first make sure that the buffer is idle. It should
***************
*** 1384,1395 ****
osi_assert(bufferp->dataVersion == op->dataVersion);
#endif
! lock_ReleaseMutex(&op->scp->mx);
lock_ObtainMutex(&bufferp->mx);
if (flags & DIROP_SCPLOCKED) {
! lock_ObtainMutex(&op->scp->mx);
}
if (flags & DIROP_MODIFIED) {
--- 1383,1394 ----
osi_assert(bufferp->dataVersion == op->dataVersion);
#endif
! lock_ReleaseWrite(&op->scp->rw);
lock_ObtainMutex(&bufferp->mx);
if (flags & DIROP_SCPLOCKED) {
! lock_ObtainWrite(&op->scp->rw);
}
if (flags & DIROP_MODIFIED) {
***************
*** 1434,1446 ****
This should be called before cm_DirGetPage() is called per scp.
On entry:
! scp->mx locked state indicated by parameter
On exit:
! scp->mx same state as upon entry
During:
! scp->mx may be released
*/
static long
cm_DirCheckStatus(cm_dirOp_t * op, afs_uint32 locked)
--- 1433,1445 ----
This should be called before cm_DirGetPage() is called per scp.
On entry:
! scp->rw locked state indicated by parameter
On exit:
! scp->rw same state as upon entry
During:
! scp->rw may be released
*/
static long
cm_DirCheckStatus(cm_dirOp_t * op, afs_uint32 locked)
***************
*** 1448,1458 ****
long code;
if (!locked)
! lock_ObtainMutex(&op->scp->mx);
code = cm_SyncOp(op->scp, NULL, op->userp, &op->req, PRSFS_LOOKUP,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (!locked)
! lock_ReleaseMutex(&op->scp->mx);
osi_Log2(afsd_logp, "cm_DirCheckStatus for op 0x%p returning code 0x%x",
op, code);
--- 1447,1457 ----
long code;
if (!locked)
! lock_ObtainWrite(&op->scp->rw);
code = cm_SyncOp(op->scp, NULL, op->userp, &op->req, PRSFS_LOOKUP,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (!locked)
! lock_ReleaseWrite(&op->scp->rw);
osi_Log2(afsd_logp, "cm_DirCheckStatus for op 0x%p returning code 0x%x",
op, code);
***************
*** 1464,1470 ****
cm_DirGetPage() or any other function that returns a locked, held,
directory page buffer.
! Called with scp->mx unlocked
*/
static long
cm_DirReleasePage(cm_dirOp_t * op, cm_buf_t ** bufferpp, int modified)
--- 1463,1469 ----
cm_DirGetPage() or any other function that returns a locked, held,
directory page buffer.
! Called with scp->rw unlocked
*/
static long
cm_DirReleasePage(cm_dirOp_t * op, cm_buf_t ** bufferpp, int modified)
***************
*** 1504,1518 ****
should be released via cm_DirReleasePage().
On entry:
! scp->mx unlocked.
If *bufferpp is non-NULL, then *bufferpp->mx is locked.
On exit:
! scp->mx unlocked
If *bufferpp is non-NULL, then *bufferpp->mx is locked.
During:
! scp->mx will be obtained and released
*/
static long
--- 1503,1517 ----
should be released via cm_DirReleasePage().
On entry:
! scp->rw unlocked.
If *bufferpp is non-NULL, then *bufferpp->mx is locked.
On exit:
! scp->rw unlocked
If *bufferpp is non-NULL, then *bufferpp->mx is locked.
During:
! scp->rw will be obtained and released
*/
static long
***************
*** 1586,1599 ****
doing directory updates locally is to avoid fetching all
the data from the server. */
while (1) {
! lock_ObtainMutex(&op->scp->mx);
code = cm_SyncOp(op->scp, bufferp, op->userp, &op->req, PRSFS_LOOKUP,
CM_SCACHESYNC_NEEDCALLBACK |
CM_SCACHESYNC_READ |
CM_SCACHESYNC_BUFLOCKED);
if (code) {
! lock_ReleaseMutex(&op->scp->mx);
break;
}
--- 1585,1598 ----
doing directory updates locally is to avoid fetching all
the data from the server. */
while (1) {
! lock_ObtainWrite(&op->scp->rw);
code = cm_SyncOp(op->scp, bufferp, op->userp, &op->req, PRSFS_LOOKUP,
CM_SCACHESYNC_NEEDCALLBACK |
CM_SCACHESYNC_READ |
CM_SCACHESYNC_BUFLOCKED);
if (code) {
! lock_ReleaseWrite(&op->scp->rw);
break;
}
***************
*** 1603,1615 ****
CM_SCACHESYNC_BUFLOCKED);
if (cm_HaveBuffer(op->scp, bufferp, 1)) {
! lock_ReleaseMutex(&op->scp->mx);
break;
}
lock_ReleaseMutex(&bufferp->mx);
code = cm_GetBuffer(op->scp, bufferp, NULL, op->userp, &op->req);
! lock_ReleaseMutex(&op->scp->mx);
lock_ObtainMutex(&bufferp->mx);
if (code)
--- 1602,1614 ----
CM_SCACHESYNC_BUFLOCKED);
if (cm_HaveBuffer(op->scp, bufferp, 1)) {
! lock_ReleaseWrite(&op->scp->rw);
break;
}
lock_ReleaseMutex(&bufferp->mx);
code = cm_GetBuffer(op->scp, bufferp, NULL, op->userp, &op->req);
! lock_ReleaseWrite(&op->scp->rw);
lock_ObtainMutex(&bufferp->mx);
if (code)
Index: openafs/src/WINNT/afsd/cm_dnlc.c
diff -c openafs/src/WINNT/afsd/cm_dnlc.c:1.10.4.3 openafs/src/WINNT/afsd/cm_dnlc.c:1.10.4.6
*** openafs/src/WINNT/afsd/cm_dnlc.c:1.10.4.3 Sat Oct 7 18:33:29 2006
--- openafs/src/WINNT/afsd/cm_dnlc.c Fri Feb 29 10:58:53 2008
***************
*** 26,31 ****
--- 26,32 ----
#include
#include
#include "afsd.h"
+ #include
osi_rwlock_t cm_dnlcLock;
***************
*** 113,118 ****
--- 114,120 ----
unsigned int key, skey, new=0;
char *ts = aname;
int safety;
+ int writeLocked = 0;
if (!cm_useDnlc)
return ;
***************
*** 129,137 ****
return ;
skey = key & (NHSIZE -1);
! lock_ObtainWrite(&cm_dnlcLock);
! dnlcstats.enters++;
!
for (tnc = cm_data.nameHash[skey], safety=0; tnc; tnc = tnc->next, safety++ )
if ((tnc->dirp == adp) && (!strcmp(tnc->name, aname)))
break; /* preexisting entry */
--- 131,139 ----
return ;
skey = key & (NHSIZE -1);
! InterlockedIncrement(&dnlcstats.enters);
! lock_ObtainRead(&cm_dnlcLock);
! retry:
for (tnc = cm_data.nameHash[skey], safety=0; tnc; tnc = tnc->next, safety++ )
if ((tnc->dirp == adp) && (!strcmp(tnc->name, aname)))
break; /* preexisting entry */
***************
*** 142,149 ****
}
else if (safety > NCSIZE)
{
! dnlcstats.cycles++;
! lock_ReleaseWrite(&cm_dnlcLock);
if ( cm_debugDnlc )
osi_Log0(afsd_logp, "DNLC cycle");
--- 144,154 ----
}
else if (safety > NCSIZE)
{
! InterlockedIncrement(&dnlcstats.cycles);
! if (writeLocked)
! lock_ReleaseWrite(&cm_dnlcLock);
! else
! lock_ReleaseRead(&cm_dnlcLock);
if ( cm_debugDnlc )
osi_Log0(afsd_logp, "DNLC cycle");
***************
*** 153,158 ****
--- 158,168 ----
if ( !tnc )
{
+ if ( !writeLocked ) {
+ lock_ConvertRToW(&cm_dnlcLock);
+ writeLocked = 1;
+ goto retry;
+ }
new = 1; /* entry does not exist, we are creating a new entry*/
tnc = GetMeAnEntry();
}
***************
*** 167,173 ****
InsertEntry(tnc);
}
! lock_ReleaseWrite(&cm_dnlcLock);
if ( !tnc)
cm_dnlcPurge();
--- 177,186 ----
InsertEntry(tnc);
}
! if (writeLocked)
! lock_ReleaseWrite(&cm_dnlcLock);
! else
! lock_ReleaseRead(&cm_dnlcLock);
if ( !tnc)
cm_dnlcPurge();
***************
*** 188,205 ****
if (!cm_useDnlc)
return NULL;
if ( cm_debugDnlc )
osi_Log2(afsd_logp, "cm_dnlcLookup dir %x name %s",
adp, osi_LogSaveString(afsd_logp,aname));
dnlcHash( ts, key ); /* leaves ts pointing at the NULL */
! if (ts - aname >= CM_AFSNCNAMESIZE)
return NULL;
skey = key & (NHSIZE -1);
lock_ObtainRead(&cm_dnlcLock);
! dnlcstats.lookups++; /* Is a dnlcread lock sufficient? */
ts = 0;
tnc_begin = cm_data.nameHash[skey];
--- 201,223 ----
if (!cm_useDnlc)
return NULL;
+
if ( cm_debugDnlc )
osi_Log2(afsd_logp, "cm_dnlcLookup dir %x name %s",
adp, osi_LogSaveString(afsd_logp,aname));
dnlcHash( ts, key ); /* leaves ts pointing at the NULL */
!
! if (ts - aname >= CM_AFSNCNAMESIZE) {
! InterlockedIncrement(&dnlcstats.lookups);
! InterlockedIncrement(&dnlcstats.misses);
return NULL;
+ }
skey = key & (NHSIZE -1);
lock_ObtainRead(&cm_dnlcLock);
! InterlockedIncrement(&dnlcstats.lookups);
ts = 0;
tnc_begin = cm_data.nameHash[skey];
***************
*** 258,264 ****
}
else if (tnc->next == tnc_begin || safety > NCSIZE)
{
! dnlcstats.cycles++;
lock_ReleaseRead(&cm_dnlcLock);
if ( cm_debugDnlc )
--- 276,282 ----
}
else if (tnc->next == tnc_begin || safety > NCSIZE)
{
! InterlockedIncrement(&dnlcstats.cycles);
lock_ReleaseRead(&cm_dnlcLock);
if ( cm_debugDnlc )
***************
*** 276,282 ****
}
if (!tvc)
! dnlcstats.misses++; /* Is a dnlcread lock sufficient? */
else
{
sp->found = 1;
--- 294,300 ----
}
if (!tvc)
! InterlockedIncrement(&dnlcstats.misses);
else
{
sp->found = 1;
***************
*** 341,347 ****
skey = key & (NHSIZE -1);
lock_ObtainWrite(&cm_dnlcLock);
! dnlcstats.removes++;
for (tnc = cm_data.nameHash[skey], safety=0; tnc; safety++)
{
--- 359,365 ----
skey = key & (NHSIZE -1);
lock_ObtainWrite(&cm_dnlcLock);
! InterlockedIncrement(&dnlcstats.removes);
for (tnc = cm_data.nameHash[skey], safety=0; tnc; safety++)
{
***************
*** 365,371 ****
tnc = tnc->next;
if ( safety > NCSIZE )
{
! dnlcstats.cycles++;
lock_ReleaseWrite(&cm_dnlcLock);
if ( cm_debugDnlc )
--- 383,389 ----
tnc = tnc->next;
if ( safety > NCSIZE )
{
! InterlockedIncrement(&dnlcstats.cycles);
lock_ReleaseWrite(&cm_dnlcLock);
if ( cm_debugDnlc )
***************
*** 397,403 ****
osi_Log1(afsd_logp, "cm_dnlcPurgedp dir %x", adp);
lock_ObtainWrite(&cm_dnlcLock);
! dnlcstats.purgeds++;
for (i=0; imx);
cm_DiscardSCache(scp);
! lock_ReleaseMutex(&scp->mx);
cm_CallbackNotifyChange(scp);
lock_ObtainWrite(&cm_scacheLock);
cm_ReleaseSCacheNoLock(scp);
--- 415,423 ----
// mark the scp to be reused
cm_HoldSCacheNoLock(scp);
lock_ReleaseWrite(&cm_scacheLock);
! lock_ObtainWrite(&scp->rw);
cm_DiscardSCache(scp);
! lock_ReleaseWrite(&scp->rw);
cm_CallbackNotifyChange(scp);
lock_ObtainWrite(&cm_scacheLock);
cm_ReleaseSCacheNoLock(scp);
***************
*** 423,431 ****
lscpp = &tscp->nextp, tscp = tscp->nextp) {
if (tscp == scp) {
*lscpp = scp->nextp;
! lock_ObtainMutex(&scp->mx);
scp->flags &= ~CM_SCACHEFLAG_INHASH;
! lock_ReleaseMutex(&scp->mx);
break;
}
}
--- 428,436 ----
lscpp = &tscp->nextp, tscp = tscp->nextp) {
if (tscp == scp) {
*lscpp = scp->nextp;
! lock_ObtainWrite(&scp->rw);
scp->flags &= ~CM_SCACHEFLAG_INHASH;
! lock_ReleaseWrite(&scp->rw);
break;
}
}
***************
*** 447,457 ****
cm_InitLocalMountPoints();
osi_Log0(afsd_logp,"\tcreated new set of localmountpoints!");
- // now we have to free the memory allocated in cm_initfakerootdir
- osi_Log0(afsd_logp,"Removing old fakedir... ");
- free(cm_FakeRootDir);
- osi_Log0(afsd_logp,"\t\told fakedir removed!");
-
// then we re-create that dir
osi_Log0(afsd_logp,"Creating new fakedir... ");
cm_InitFakeRootDir();
--- 452,457 ----
Index: openafs/src/WINNT/afsd/cm_ioctl.c
diff -c openafs/src/WINNT/afsd/cm_ioctl.c:1.73.2.36 openafs/src/WINNT/afsd/cm_ioctl.c:1.73.2.40
*** openafs/src/WINNT/afsd/cm_ioctl.c:1.73.2.36 Fri Feb 22 19:17:35 2008
--- openafs/src/WINNT/afsd/cm_ioctl.c Wed Mar 19 09:59:30 2008
***************
*** 44,50 ****
#include "cm_rpc.h"
#include
#include
- #include <..\afsrdr\kif.h>
#include
#ifdef _DEBUG
--- 44,49 ----
***************
*** 73,81 ****
code = buf_CleanVnode(scp, userp, reqp);
! lock_ObtainMutex(&scp->mx);
cm_DiscardSCache(scp);
! lock_ReleaseMutex(&scp->mx);
osi_Log2(afsd_logp,"cm_CleanFile scp 0x%x returns error: [%x]",scp, code);
return code;
--- 72,80 ----
code = buf_CleanVnode(scp, userp, reqp);
! lock_ObtainWrite(&scp->rw);
cm_DiscardSCache(scp);
! lock_ReleaseWrite(&scp->rw);
osi_Log2(afsd_logp,"cm_CleanFile scp 0x%x returns error: [%x]",scp, code);
return code;
***************
*** 94,103 ****
code = buf_FlushCleanPages(scp, userp, reqp);
! lock_ObtainMutex(&scp->mx);
cm_DiscardSCache(scp);
! lock_ReleaseMutex(&scp->mx);
osi_Log2(afsd_logp,"cm_FlushFile scp 0x%x returns error: [%x]",scp, code);
return code;
--- 93,102 ----
code = buf_FlushCleanPages(scp, userp, reqp);
! lock_ObtainWrite(&scp->rw);
cm_DiscardSCache(scp);
! lock_ReleaseWrite(&scp->rw);
osi_Log2(afsd_logp,"cm_FlushFile scp 0x%x returns error: [%x]",scp, code);
return code;
***************
*** 164,172 ****
for (scp=cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) {
cm_HoldSCacheNoLock(scp);
lock_ReleaseWrite(&cm_scacheLock);
! lock_ObtainMutex(&scp->mx);
cm_InvalidateACLUser(scp, userp);
! lock_ReleaseMutex(&scp->mx);
lock_ObtainWrite(&cm_scacheLock);
cm_ReleaseSCacheNoLock(scp);
}
--- 163,171 ----
for (scp=cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) {
cm_HoldSCacheNoLock(scp);
lock_ReleaseWrite(&cm_scacheLock);
! lock_ObtainWrite(&scp->rw);
cm_InvalidateACLUser(scp, userp);
! lock_ReleaseWrite(&scp->rw);
lock_ObtainWrite(&cm_scacheLock);
cm_ReleaseSCacheNoLock(scp);
}
***************
*** 213,222 ****
cm_scache_t **scpp, afs_uint32 flags)
{
long code;
- #ifndef AFSIFS
cm_scache_t *substRootp = NULL;
cm_scache_t *iscp = NULL;
- #endif
char * relativePath;
char * lastComponent = NULL;
afs_uint32 follow = (flags & CM_PARSE_FLAG_LITERAL ? CM_FLAG_NOMOUNTCHASE : CM_FLAG_FOLLOW);
--- 212,219 ----
***************
*** 245,265 ****
/* This is usually nothing, but for StatMountPoint it is the file name. */
// TranslateExtendedChars(ioctlp->inDatap);
- #ifdef AFSIFS
- /* we have passed the whole path, including the afs prefix.
- when the pioctl call is made, we perform an ioctl to afsrdr
- and it returns the correct (full) path. therefore, there is
- no drive letter, and the path is absolute. */
- code = cm_NameI(cm_data.rootSCachep, relativePath,
- CM_FLAG_CASEFOLD,
- userp, "", reqp, scpp);
-
- if (code) {
- osi_Log1(afsd_logp,"cm_ParseIoctlPath code 0x%x", code);
- return code;
- }
- #else /* AFSIFS */
-
if (relativePath[0] == relativePath[1] &&
relativePath[1] == '\\' &&
!_strnicmp(cm_NetbiosName,relativePath+2,strlen(cm_NetbiosName)))
--- 242,247 ----
***************
*** 397,403 ****
return code;
}
}
- #endif /* AFSIFS */
if (substRootp)
cm_ReleaseSCache(substRootp);
--- 379,384 ----
***************
*** 754,762 ****
code = cm_MapRPCError(code, &req);
/* invalidate cache info, since we just trashed the ACL cache */
! lock_ObtainMutex(&scp->mx);
cm_DiscardSCache(scp);
! lock_ReleaseMutex(&scp->mx);
}
cm_ReleaseSCache(scp);
--- 735,743 ----
code = cm_MapRPCError(code, &req);
/* invalidate cache info, since we just trashed the ACL cache */
! lock_ObtainWrite(&scp->rw);
cm_DiscardSCache(scp);
! lock_ReleaseWrite(&scp->rw);
}
cm_ReleaseSCache(scp);
***************
*** 904,910 ****
return CM_ERROR_READONLY;
}
! code = cm_GetVolumeByID(cellp, scp->fid.volume, userp, &req,
CM_GETVOL_FLAG_CREATE, &tvp);
if (code) {
cm_ReleaseSCache(scp);
--- 885,891 ----
return CM_ERROR_READONLY;
}
! code = cm_FindVolumeByID(cellp, scp->fid.volume, userp, &req,
CM_GETVOL_FLAG_CREATE, &tvp);
if (code) {
cm_ReleaseSCache(scp);
***************
*** 1230,1236 ****
} else
#endif
{
! code = cm_GetVolumeByID(cellp, volume, userp, &req, CM_GETVOL_FLAG_CREATE, &tvp);
if (code)
return code;
--- 1211,1217 ----
} else
#endif
{
! code = cm_FindVolumeByID(cellp, volume, userp, &req, CM_GETVOL_FLAG_CREATE, &tvp);
if (code)
return code;
***************
*** 1278,1288 ****
cm_ReleaseSCache(dscp);
if (code) return code;
! lock_ObtainMutex(&scp->mx);
/* now check that this is a real mount point */
if (scp->fileType != CM_SCACHETYPE_MOUNTPOINT) {
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
return CM_ERROR_INVAL;
}
--- 1259,1269 ----
cm_ReleaseSCache(dscp);
if (code) return code;
! lock_ObtainWrite(&scp->rw);
/* now check that this is a real mount point */
if (scp->fileType != CM_SCACHETYPE_MOUNTPOINT) {
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
return CM_ERROR_INVAL;
}
***************
*** 1294,1300 ****
cp += strlen(cp) + 1;
ioctlp->outDatap = cp;
}
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
return code;
--- 1275,1281 ----
cp += strlen(cp) + 1;
ioctlp->outDatap = cp;
}
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
return code;
***************
*** 1322,1346 ****
goto done2;
}
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
goto done2;
}
/* now check that this is a real mount point */
if (scp->fileType != CM_SCACHETYPE_MOUNTPOINT) {
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
code = CM_ERROR_INVAL;
goto done1;
}
/* time to make the RPC, so drop the lock */
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
/* easier to do it this way */
--- 1303,1327 ----
goto done2;
}
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
goto done2;
}
/* now check that this is a real mount point */
if (scp->fileType != CM_SCACHETYPE_MOUNTPOINT) {
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
code = CM_ERROR_INVAL;
goto done1;
}
/* time to make the RPC, so drop the lock */
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
/* easier to do it this way */
***************
*** 1351,1359 ****
dscp, cp, NULL, TRUE);
done1:
! lock_ObtainMutex(&scp->mx);
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
! lock_ReleaseMutex(&scp->mx);
done2:
cm_ReleaseSCache(dscp);
--- 1332,1340 ----
dscp, cp, NULL, TRUE);
done1:
! lock_ObtainWrite(&scp->rw);
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
! lock_ReleaseWrite(&scp->rw);
done2:
cm_ReleaseSCache(dscp);
***************
*** 2187,2193 ****
if (code)
goto done3;
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code)
--- 2168,2174 ----
if (code)
goto done3;
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code)
***************
*** 2202,2208 ****
}
/* time to make the RPC, so drop the lock */
! lock_ReleaseMutex(&scp->mx);
/* easier to do it this way */
code = cm_Unlink(dscp, cp, userp, &req);
--- 2183,2189 ----
}
/* time to make the RPC, so drop the lock */
! lock_ReleaseWrite(&scp->rw);
/* easier to do it this way */
code = cm_Unlink(dscp, cp, userp, &req);
***************
*** 2212,2223 ****
| FILE_NOTIFY_CHANGE_DIR_NAME,
dscp, cp, NULL, TRUE);
! lock_ObtainMutex(&scp->mx);
done1:
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
done2:
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
done3:
--- 2193,2204 ----
| FILE_NOTIFY_CHANGE_DIR_NAME,
dscp, cp, NULL, TRUE);
! lock_ObtainWrite(&scp->rw);
done1:
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
done2:
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
done3:
***************
*** 2316,2324 ****
afs_uuid_t uuid;
int flags;
char sessionKey[8];
- #ifndef AFSIFS
char *smbname;
- #endif
int release_userp = 0;
char * wdir = NULL;
--- 2297,2303 ----
***************
*** 2366,2372 ****
uname = tp;
tp += strlen(tp) + 1;
- #ifndef AFSIFS /* no SMB username, so we cannot logon based on this */
if (flags & PIOCTL_LOGON) {
/* SMB user name with which to associate tokens */
smbname = tp;
--- 2345,2350 ----
***************
*** 2378,2384 ****
osi_Log1(smb_logp,"cm_IoctlSetToken for user [%s]",
osi_LogSaveString(smb_logp, uname));
}
- #endif
#ifndef DJGPP /* for win95, session key is back in pioctl */
/* uuid */
--- 2356,2361 ----
***************
*** 2391,2403 ****
osi_Log0(smb_logp,"cm_IoctlSetToken - no name specified");
}
- #ifndef AFSIFS
if (flags & PIOCTL_LOGON) {
userp = smb_FindCMUserByName(smbname, ioctlp->fidp->vcp->rname,
SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
release_userp = 1;
}
- #endif /* AFSIFS */
/* store the token */
lock_ObtainMutex(&userp->mx);
--- 2368,2378 ----
***************
*** 3161,3167 ****
if (!cellp)
return CM_ERROR_NOSUCHCELL;
! code = cm_GetVolumeByID(cellp, volume, userp, &req, CM_GETVOL_FLAG_CREATE, &tvp);
if (code)
return code;
--- 3136,3142 ----
if (!cellp)
return CM_ERROR_NOSUCHCELL;
! code = cm_FindVolumeByID(cellp, volume, userp, &req, CM_GETVOL_FLAG_CREATE, &tvp);
if (code)
return code;
***************
*** 3257,3267 ****
if (n)
testp->fid.volume = n;
else
! code = cm_GetVolumeByName(cellp, testp->volname, userp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
}
if (testp->fid.volume > 0)
! code = cm_GetVolumeByID(cellp, testp->fid.volume, userp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
if (code)
return code;
--- 3232,3242 ----
if (n)
testp->fid.volume = n;
else
! code = cm_FindVolumeByName(cellp, testp->volname, userp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
}
if (testp->fid.volume > 0)
! code = cm_FindVolumeByID(cellp, testp->fid.volume, userp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
if (code)
return code;
Index: openafs/src/WINNT/afsd/cm_memmap.c
diff -c openafs/src/WINNT/afsd/cm_memmap.c:1.7.2.8 openafs/src/WINNT/afsd/cm_memmap.c:1.7.2.10
*** openafs/src/WINNT/afsd/cm_memmap.c:1.7.2.8 Wed Jan 2 10:55:00 2008
--- openafs/src/WINNT/afsd/cm_memmap.c Wed Mar 19 20:01:59 2008
***************
*** 622,636 ****
}
int
! cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD chunkSize,
! afs_uint64 cacheBlocks, afs_uint32 blockSize)
{
HANDLE hf = INVALID_HANDLE_VALUE, hm;
PSECURITY_ATTRIBUTES psa;
int newFile = 1;
afs_uint64 mappingSize;
- DWORD maxVols = stats/2;
- DWORD maxCells = stats/4;
DWORD volumeSerialNumber = 0;
DWORD sidStringSize = 0;
DWORD rc;
--- 622,634 ----
}
int
! cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD maxVols, DWORD maxCells,
! DWORD chunkSize, afs_uint64 cacheBlocks, afs_uint32 blockSize)
{
HANDLE hf = INVALID_HANDLE_VALUE, hm;
PSECURITY_ATTRIBUTES psa;
int newFile = 1;
afs_uint64 mappingSize;
DWORD volumeSerialNumber = 0;
DWORD sidStringSize = 0;
DWORD rc;
Index: openafs/src/WINNT/afsd/cm_memmap.h
diff -c openafs/src/WINNT/afsd/cm_memmap.h:1.3.4.7 openafs/src/WINNT/afsd/cm_memmap.h:1.3.4.10
*** openafs/src/WINNT/afsd/cm_memmap.h:1.3.4.7 Fri Feb 22 19:17:35 2008
--- openafs/src/WINNT/afsd/cm_memmap.h Wed Mar 19 20:01:59 2008
***************
*** 10,16 ****
#ifndef CM_MEMMAP_H
#define CM_MEMMAP_H 1
! #define CM_CONFIG_DATA_VERSION 1
#define CM_CONFIG_DATA_MAGIC ('A' | 'F'<<8 | 'S'<<16 | CM_CONFIG_DATA_VERSION<<24)
typedef struct cm_config_data {
--- 10,16 ----
#ifndef CM_MEMMAP_H
#define CM_MEMMAP_H 1
! #define CM_CONFIG_DATA_VERSION 2
#define CM_CONFIG_DATA_MAGIC ('A' | 'F'<<8 | 'S'<<16 | CM_CONFIG_DATA_VERSION<<24)
typedef struct cm_config_data {
***************
*** 116,120 ****
VOID FreeCacheFileSA(PSECURITY_ATTRIBUTES psa);
int cm_ShutdownMappedMemory(void);
int cm_ValidateMappedMemory(char * cachePath);
! int cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD chunkSize, afs_uint64 cacheBlocks, afs_uint32 blockSize);
#endif /* CM_MEMMAP_H */
\ No newline at end of file
--- 116,120 ----
VOID FreeCacheFileSA(PSECURITY_ATTRIBUTES psa);
int cm_ShutdownMappedMemory(void);
int cm_ValidateMappedMemory(char * cachePath);
! int cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD maxVols, DWORD maxCells, DWORD chunkSize, afs_uint64 cacheBlocks, afs_uint32 blockSize);
#endif /* CM_MEMMAP_H */
\ No newline at end of file
Index: openafs/src/WINNT/afsd/cm_performance.c
diff -c /dev/null openafs/src/WINNT/afsd/cm_performance.c:1.1.2.4
*** /dev/null Sat Mar 22 21:01:33 2008
--- openafs/src/WINNT/afsd/cm_performance.c Thu Mar 13 00:39:17 2008
***************
*** 0 ****
--- 1,549 ----
+ /*
+ * Copyright (c) 2008 - Secure Endpoints Inc.
+ */
+
+ #include
+ #include
+
+ #include
+ #include
+ #include
+ #include
+ #include
+ #include
+
+ #include "afsd.h"
+
+ static cm_fid_stats_t ** fidStatsHashTablep = NULL;
+ static afs_uint32 fidStatsHashTableSize = 0;
+
+ /*
+ * algorithm and implementation adapted from code written by
+ * Frank Pilhofer
+ */
+ afs_uint32 nearest_prime(afs_uint32 s)
+ {
+ #define TEST(f,x) (*(f+(x)/16)&(1<<(((x)%16L)/2)))
+ #define SET(f,x) *(f+(x)/16)|=1<<(((x)%16L)/2)
+ unsigned char *feld=NULL, *zzz;
+ afs_uint32 teste=1, mom, hits=1, count, max, alloc, largest_prime = 0;
+
+ max = s + 10000L;
+
+ while (feld==NULL)
+ zzz = feld = malloc (alloc=((max>>4)+1L));
+
+ for (count=0; countfid.hash % fidStatsHashTableSize;
+
+ statp->nextp = fidStatsHashTablep[hash];
+ fidStatsHashTablep[hash] = statp;
+ }
+
+ void cm_PerformanceAddSCache(cm_scache_t *scp)
+ {
+ cm_fid_stats_t * statp = cm_PerformanceGetNew();
+
+ if (!statp)
+ return;
+
+ lock_ObtainRead(&scp->rw);
+ if (!(scp->flags & CM_SCACHEFLAG_DELETED)) {
+ statp->fid = scp->fid;
+ statp->fileLength = scp->length;
+ statp->fileType = scp->fileType;
+ statp->flags = CM_FIDSTATS_FLAG_HAVE_SCACHE;
+ lock_ConvertRToW(&scp->rw);
+ if (cm_HaveCallback(scp))
+ statp->flags |= CM_FIDSTATS_FLAG_CALLBACK;
+ lock_ConvertWToR(&scp->rw);
+ if (scp->flags & CM_SCACHEFLAG_RO)
+ statp->flags |= CM_FIDSTATS_FLAG_RO;
+ if (scp->flags & CM_SCACHEFLAG_PURERO)
+ statp->flags |= CM_FIDSTATS_FLAG_PURERO;
+ }
+ lock_ReleaseRead(&scp->rw);
+
+ #if 0
+ if (statp->fid.vnode == 1) {
+ cm_volume_t *volp = NULL;
+ cm_cell_t *cellp = NULL;
+ cm_req_t req;
+
+ cm_InitReq(&req);
+
+ cellp = cm_FindCellByID(statp->fid.cell, 0);
+ if (cellp) {
+ if (!cm_FindVolumeByID(cellp, statp->fid.volume, cm_rootUserp, &req, 0, &volp)) {
+ statp->flags |= CM_FIDSTATS_HAVE_VOLUME;
+ cm_PutVolume(volp);
+ }
+ }
+ }
+ #endif
+
+ cm_PerformanceInsertToHashTable(statp);
+ }
+
+
+ void cm_PerformanceTuningInit(void)
+ {
+ afs_uint32 i;
+ cm_scache_t *scp;
+ cm_volume_t *volp;
+ cm_buf_t *bp;
+ cm_fid_t fid;
+ afs_uint32 hash;
+ cm_fid_stats_t * statp;
+
+ fidStatsHashTableSize = nearest_prime(cm_data.stats/3);
+ if (fidStatsHashTableSize == 0)
+ fidStatsHashTableSize = cm_data.stats/3;
+ fidStatsHashTablep = (cm_fid_stats_t **)malloc(fidStatsHashTableSize * sizeof(cm_fid_stats_t *));
+ if (fidStatsHashTablep == NULL) {
+ fidStatsHashTableSize = 0;
+ return;
+ }
+
+ memset(fidStatsHashTablep, 0, fidStatsHashTableSize * sizeof(cm_fid_stats_t *));
+
+ lock_ObtainRead(&cm_scacheLock);
+ for (i=0; inextp) {
+ if (scp->fid.cell == 0)
+ continue;
+ lock_ReleaseRead(&cm_scacheLock);
+ cm_PerformanceAddSCache(scp);
+ lock_ObtainRead(&cm_scacheLock);
+ }
+ }
+ lock_ReleaseRead(&cm_scacheLock);
+
+ lock_ObtainRead(&cm_volumeLock);
+ for(volp = cm_data.allVolumesp; volp; volp=volp->allNextp) {
+ if (volp->rw.ID) {
+ cm_SetFid(&fid, volp->cellp->cellID, volp->rw.ID, 1, 1);
+ hash = fid.hash % fidStatsHashTableSize;
+
+ for (statp = fidStatsHashTablep[hash]; statp; statp = statp->nextp) {
+ if (!cm_FidCmp(&fid, &statp->fid)) {
+ statp->flags |= CM_FIDSTATS_FLAG_HAVE_VOLUME;
+ break;
+ }
+ }
+ if (!statp) {
+ statp = cm_PerformanceGetNew();
+ statp->fid = fid;
+ statp->fileType = CM_SCACHETYPE_DIRECTORY;
+ statp->flags = CM_FIDSTATS_FLAG_HAVE_VOLUME;
+ cm_PerformanceInsertToHashTable(statp);
+ }
+ }
+ if (volp->ro.ID) {
+ cm_SetFid(&fid, volp->cellp->cellID, volp->ro.ID, 1, 1);
+ hash = fid.hash % fidStatsHashTableSize;
+
+ for (statp = fidStatsHashTablep[hash]; statp; statp = statp->nextp) {
+ if (!cm_FidCmp(&fid, &statp->fid)) {
+ statp->flags |= CM_FIDSTATS_FLAG_HAVE_VOLUME;
+ break;
+ }
+ }
+ if (!statp) {
+ statp = cm_PerformanceGetNew();
+ statp->fid = fid;
+ statp->fileType = CM_SCACHETYPE_DIRECTORY;
+ statp->flags = CM_FIDSTATS_FLAG_HAVE_VOLUME | CM_FIDSTATS_FLAG_RO | CM_FIDSTATS_FLAG_PURERO;
+ cm_PerformanceInsertToHashTable(statp);
+ }
+ }
+ if (volp->bk.ID) {
+ cm_SetFid(&fid, volp->cellp->cellID, volp->bk.ID, 1, 1);
+ hash = fid.hash % fidStatsHashTableSize;
+
+ for (statp = fidStatsHashTablep[hash]; statp; statp = statp->nextp) {
+ if (!cm_FidCmp(&fid, &statp->fid)) {
+ statp->flags |= CM_FIDSTATS_FLAG_HAVE_VOLUME;
+ break;
+ }
+ }
+ if (!statp) {
+ statp = cm_PerformanceGetNew();
+ statp->fid = fid;
+ statp->fileType = CM_SCACHETYPE_DIRECTORY;
+ statp->flags = CM_FIDSTATS_FLAG_HAVE_VOLUME | CM_FIDSTATS_FLAG_RO;
+ cm_PerformanceInsertToHashTable(statp);
+ }
+ }
+ }
+ lock_ReleaseRead(&cm_volumeLock);
+
+ lock_ObtainRead(&buf_globalLock);
+ for (bp = cm_data.buf_allp; bp; bp=bp->allp) {
+ int valid = 0;
+
+ if (bp->fid.cell == 0)
+ continue;
+
+ lock_ReleaseRead(&buf_globalLock);
+ scp = cm_FindSCache(&bp->fid);
+ if (scp) {
+ lock_ObtainMutex(&bp->mx);
+ lock_ObtainRead(&scp->rw);
+ valid = cm_HaveBuffer(scp, bp, TRUE);
+ lock_ReleaseRead(&scp->rw);
+ lock_ReleaseMutex(&bp->mx);
+ cm_ReleaseSCache(scp);
+
+ if (valid) {
+ hash = bp->fid.hash % fidStatsHashTableSize;
+ for (statp = fidStatsHashTablep[hash]; statp; statp = statp->nextp) {
+ if (!cm_FidCmp(&bp->fid, &statp->fid)) {
+ statp->buffers++;
+ break;
+ }
+ }
+ }
+ }
+ lock_ObtainRead(&buf_globalLock);
+ }
+ lock_ReleaseRead(&buf_globalLock);
+
+ cm_PerformancePrintReport();
+ }
+
+ void cm_PerformanceTuningCheck(void)
+ {
+ afs_uint32 i;
+ cm_scache_t *scp;
+ cm_volume_t *volp;
+ cm_buf_t *bp;
+ cm_fid_t fid;
+ afs_uint32 hash;
+ cm_fid_stats_t * statp;
+
+ if (fidStatsHashTablep == NULL)
+ return;
+
+ /* Clean all cm_fid_stat_t objects first */
+ for (i = 0; i < fidStatsHashTableSize; i++) {
+ for (statp = fidStatsHashTablep[i]; statp; statp = statp->nextp) {
+ statp->flags &= (CM_FIDSTATS_FLAG_RO | CM_FIDSTATS_FLAG_PURERO);
+ statp->buffers = 0;
+ statp->fileLength.QuadPart = 0;
+ }
+ }
+
+ lock_ObtainRead(&cm_scacheLock);
+ for (i=0; inextp) {
+ if (scp->fid.cell == 0)
+ continue;
+ hash = scp->fid.hash % fidStatsHashTableSize;
+
+ for (statp = fidStatsHashTablep[hash]; statp; statp = statp->nextp) {
+ if (!cm_FidCmp(&fid, &statp->fid)) {
+ statp->fileType = scp->fileType;
+ if (cm_HaveCallback(scp))
+ statp->flags |= CM_FIDSTATS_FLAG_CALLBACK;
+ statp->flags |= CM_FIDSTATS_FLAG_HAVE_SCACHE;
+ break;
+ }
+ }
+ if (!statp) {
+ lock_ReleaseRead(&cm_scacheLock);
+ cm_PerformanceAddSCache(scp);
+ lock_ObtainRead(&cm_scacheLock);
+ }
+ }
+ }
+ lock_ReleaseRead(&cm_scacheLock);
+
+ lock_ObtainRead(&cm_volumeLock);
+ for(volp = cm_data.allVolumesp; volp; volp=volp->allNextp) {
+ if (volp->rw.ID) {
+ cm_SetFid(&fid, volp->cellp->cellID, volp->rw.ID, 1, 1);
+ hash = fid.hash % fidStatsHashTableSize;
+
+ for (statp = fidStatsHashTablep[hash]; statp; statp = statp->nextp) {
+ if (!cm_FidCmp(&fid, &statp->fid)) {
+ statp->flags |= CM_FIDSTATS_FLAG_HAVE_VOLUME;
+ break;
+ }
+ }
+ if (!statp) {
+ statp = cm_PerformanceGetNew();
+ statp->fid = fid;
+ statp->fileType = CM_SCACHETYPE_DIRECTORY;
+ statp->flags = CM_FIDSTATS_FLAG_HAVE_VOLUME;
+ cm_PerformanceInsertToHashTable(statp);
+ }
+ }
+ if (volp->ro.ID) {
+ cm_SetFid(&fid, volp->cellp->cellID, volp->ro.ID, 1, 1);
+ hash = fid.hash % fidStatsHashTableSize;
+
+ for (statp = fidStatsHashTablep[hash]; statp; statp = statp->nextp) {
+ if (!cm_FidCmp(&fid, &statp->fid)) {
+ statp->flags |= CM_FIDSTATS_FLAG_HAVE_VOLUME;
+ break;
+ }
+ }
+ if (!statp) {
+ statp = cm_PerformanceGetNew();
+ statp->fid = fid;
+ statp->fileType = CM_SCACHETYPE_DIRECTORY;
+ statp->flags = CM_FIDSTATS_FLAG_HAVE_VOLUME | CM_FIDSTATS_FLAG_RO | CM_FIDSTATS_FLAG_PURERO;
+ cm_PerformanceInsertToHashTable(statp);
+ }
+ }
+ if (volp->bk.ID) {
+ cm_SetFid(&fid, volp->cellp->cellID, volp->bk.ID, 1, 1);
+ hash = fid.hash % fidStatsHashTableSize;
+
+ for (statp = fidStatsHashTablep[hash]; statp; statp = statp->nextp) {
+ if (!cm_FidCmp(&fid, &statp->fid)) {
+ statp->flags |= CM_FIDSTATS_FLAG_HAVE_VOLUME;
+ break;
+ }
+ }
+ if (!statp) {
+ statp = cm_PerformanceGetNew();
+ statp->fid = fid;
+ statp->fileType = CM_SCACHETYPE_DIRECTORY;
+ statp->flags = CM_FIDSTATS_FLAG_HAVE_VOLUME | CM_FIDSTATS_FLAG_RO;
+ cm_PerformanceInsertToHashTable(statp);
+ }
+ }
+ }
+ lock_ReleaseRead(&cm_volumeLock);
+
+ lock_ObtainRead(&buf_globalLock);
+ for (bp = cm_data.buf_allp; bp; bp=bp->allp) {
+ int valid = 0;
+
+ if (bp->fid.cell == 0)
+ continue;
+
+ lock_ReleaseRead(&buf_globalLock);
+ scp = cm_FindSCache(&bp->fid);
+ if (scp) {
+ lock_ObtainMutex(&bp->mx);
+ lock_ObtainRead(&scp->rw);
+ valid = cm_HaveBuffer(scp, bp, TRUE);
+ lock_ReleaseRead(&scp->rw);
+ lock_ReleaseMutex(&bp->mx);
+ cm_ReleaseSCache(scp);
+
+ if (valid) {
+ hash = bp->fid.hash % fidStatsHashTableSize;
+ for (statp = fidStatsHashTablep[hash]; statp; statp = statp->nextp) {
+ if (!cm_FidCmp(&bp->fid, &statp->fid)) {
+ statp->buffers++;
+ break;
+ }
+ }
+ }
+ }
+ lock_ObtainRead(&buf_globalLock);
+ }
+ lock_ReleaseRead(&buf_globalLock);
+
+ cm_PerformancePrintReport();
+ }
+
+ void cm_PerformancePrintReport(void)
+ {
+ afs_uint32 i;
+ cm_fid_stats_t *statp;
+
+ afs_uint32 rw_vols = 0, ro_vols = 0, bk_vols = 0;
+ afs_uint32 fid_cnt = 0, fid_w_vol = 0, fid_w_scache = 0, fid_w_buffers = 0, fid_w_callbacks = 0;
+ afs_uint32 fid_w_scache_no_vol = 0, fid_w_scache_no_buf = 0, fid_w_vol_no_scache = 0, fid_w_buf_no_scache = 0;
+ afs_uint32 fid_file = 0, fid_dir = 0, fid_mp = 0, fid_sym = 0, fid_other = 0;
+ afs_uint32 fid_0k = 0, fid_1k = 0, fid_4k = 0, fid_64k = 0, fid_1m = 0, fid_20m = 0, fid_100m = 0, fid_1g = 0, fid_2g = 0, fid_large = 0;
+
+ HANDLE hLogFile;
+ char logfileName[MAX_PATH+1];
+ DWORD dwSize;
+
+ if (fidStatsHashTablep == NULL)
+ return;
+
+ /* Clean all cm_fid_stat_t objects first */
+ for (i = 0; i < fidStatsHashTableSize; i++) {
+ for (statp = fidStatsHashTablep[i]; statp; statp = statp->nextp) {
+ /* summarize the data */
+ fid_cnt++;
+
+ if ((statp->flags & (CM_FIDSTATS_FLAG_RO | CM_FIDSTATS_FLAG_PURERO)) == (CM_FIDSTATS_FLAG_RO | CM_FIDSTATS_FLAG_PURERO))
+ ro_vols++;
+ else if (statp->flags & CM_FIDSTATS_FLAG_RO)
+ bk_vols++;
+ else
+ rw_vols++;
+
+ if (statp->flags & CM_FIDSTATS_FLAG_HAVE_VOLUME)
+ fid_w_vol++;
+
+ if (statp->flags & CM_FIDSTATS_FLAG_HAVE_SCACHE)
+ fid_w_scache++;
+
+ if (statp->flags & CM_FIDSTATS_FLAG_CALLBACK)
+ fid_w_callbacks++;
+
+ if (statp->buffers > 0)
+ fid_w_buffers++;
+
+ if ((statp->flags & CM_FIDSTATS_FLAG_HAVE_SCACHE) &&
+ !(statp->flags & CM_FIDSTATS_FLAG_HAVE_VOLUME))
+ fid_w_scache_no_vol++;
+
+ if ((statp->flags & CM_FIDSTATS_FLAG_HAVE_SCACHE) &&
+ statp->buffers == 0)
+ fid_w_scache_no_buf++;
+
+ if ((statp->flags & CM_FIDSTATS_FLAG_HAVE_VOLUME) &&
+ !(statp->flags & CM_FIDSTATS_FLAG_HAVE_SCACHE))
+ fid_w_vol_no_scache++;
+
+ if (!(statp->flags & CM_FIDSTATS_FLAG_HAVE_SCACHE) &&
+ statp->buffers > 0)
+ fid_w_buf_no_scache++;
+
+ switch (statp->fileType) {
+ case CM_SCACHETYPE_FILE :
+ fid_file++;
+ break;
+ case CM_SCACHETYPE_DIRECTORY :
+ fid_dir++;
+ break;
+ case CM_SCACHETYPE_SYMLINK :
+ fid_sym++;
+ break;
+ case CM_SCACHETYPE_MOUNTPOINT :
+ fid_mp++;
+ break;
+ case CM_SCACHETYPE_DFSLINK :
+ case CM_SCACHETYPE_INVALID :
+ default:
+ fid_other++;
+ }
+
+ if (statp->fileType == CM_SCACHETYPE_FILE) {
+ if (statp->fileLength.HighPart == 0) {
+ if (statp->fileLength.LowPart == 0)
+ fid_0k++;
+ else if (statp->fileLength.LowPart <= 1024)
+ fid_1k++;
+ else if (statp->fileLength.LowPart <= 4096)
+ fid_4k++;
+ else if (statp->fileLength.LowPart <= 65536)
+ fid_64k++;
+ else if (statp->fileLength.LowPart <= 1024*1024)
+ fid_1m++;
+ else if (statp->fileLength.LowPart <= 20*1024*1024)
+ fid_20m++;
+ else if (statp->fileLength.LowPart <= 100*1024*1024)
+ fid_100m++;
+ else if (statp->fileLength.LowPart <= 1024*1024*1024)
+ fid_1g++;
+ else
+ fid_2g++;
+ } else {
+ fid_large++;
+ }
+ }
+ }
+ }
+
+ dwSize = GetEnvironmentVariable("TEMP", logfileName, sizeof(logfileName));
+ if ( dwSize == 0 || dwSize > sizeof(logfileName) )
+ {
+ GetWindowsDirectory(logfileName, sizeof(logfileName));
+ }
+ strncat(logfileName, "\\afsd_performance.log", sizeof(logfileName));
+
+ hLogFile = CreateFile(logfileName, FILE_APPEND_DATA, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (hLogFile) {
+ char output[1024];
+ char t[100];
+ int zilch;
+
+ GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, t, sizeof(t));
+
+ StringCbPrintfA(output, sizeof(output),
+ "TIME - %s\r\n"
+ "INUSE- stats=(%u of %u) vols=(%u of %u) bufs=(%I64u of %I64u)\r\n"
+ "FIDs - total=%u haveVol=%u haveStat=%u haveCB=%u haveBuf=%u haveStatNoVol=%u haveVolNoStat=%u haveStatNoBuf=%u haveBufNoStat=%u\r\n"
+ "VOLs - rw=%u ro=%u bk=%u\r\n"
+ "TYPEs- file=%u dir=%u mp=%u sym=%u unk=%u\r\n"
+ "SIZEs- 0kb=%u 1kb=%u 4kb=%u 64kb=%u 1mb=%u 20m=%u 100mb=%u 1gb=%u 2gb=%u larger=%u\r\n\r\n",
+ t,
+ cm_data.currentSCaches, cm_data.maxSCaches, cm_data.currentVolumes, cm_data.maxVolumes,
+ cm_data.buf_nbuffers - buf_CountFreeList(), cm_data.buf_nbuffers,
+ fid_cnt, fid_w_vol, fid_w_scache, fid_w_callbacks, fid_w_buffers,
+ fid_w_scache_no_vol, fid_w_vol_no_scache, fid_w_scache_no_buf, fid_w_buf_no_scache,
+ rw_vols, ro_vols, bk_vols,
+ fid_file, fid_dir, fid_mp, fid_sym, fid_other,
+ fid_0k, fid_1k, fid_4k, fid_64k, fid_1m, fid_20m, fid_100m, fid_1g, fid_2g, fid_large
+ );
+ WriteFile(hLogFile, output, (DWORD)strlen(output), &zilch, NULL);
+
+ CloseHandle(hLogFile);
+ }
+
+
+ }
Index: openafs/src/WINNT/afsd/cm_performance.h
diff -c /dev/null openafs/src/WINNT/afsd/cm_performance.h:1.1.2.2
*** /dev/null Sat Mar 22 21:01:33 2008
--- openafs/src/WINNT/afsd/cm_performance.h Fri Mar 7 17:24:04 2008
***************
*** 0 ****
--- 1,37 ----
+ /*
+ * Copyright (c) 2008 - Secure Endpoints Inc.
+ */
+
+ /*
+ * The performance module when activated collects
+ * data necessary to analyze the usage of the cache
+ * manager and establish recommendations for future
+ * cache manager configuration changes.
+ *
+ * As a starting point, the package will collect
+ * a list of all FIDs accessed during the session
+ * which will be used to periodically analyzed the
+ * contents of the cm_buf_t, cm_scache_t, cm_volume_t
+ * and cm_cell_t pools.
+
+ */
+
+ typedef struct cm_fid_stats {
+ cm_fid_t fid;
+ afs_uint32 fileType;
+ osi_hyper_t fileLength;
+ afs_uint32 flags;
+ afs_uint32 buffers;
+ struct cm_fid_stats * nextp;
+ } cm_fid_stats_t;
+
+ #define CM_FIDSTATS_FLAG_HAVE_SCACHE 0x01 /* set if cm_scache_t present */
+ #define CM_FIDSTATS_FLAG_HAVE_VOLUME 0x02 /* set on (vnode = 1) if cm_vol_t present */
+ #define CM_FIDSTATS_FLAG_RO 0x04
+ #define CM_FIDSTATS_FLAG_PURERO 0x08
+ #define CM_FIDSTATS_FLAG_CALLBACK 0x10
+
+ extern void cm_PerformanceTuningCheck(void);
+
+ extern void cm_PerformancePrintReport(void);
+
Index: openafs/src/WINNT/afsd/cm_scache.c
diff -c openafs/src/WINNT/afsd/cm_scache.c:1.35.2.62 openafs/src/WINNT/afsd/cm_scache.c:1.35.2.70
*** openafs/src/WINNT/afsd/cm_scache.c:1.35.2.62 Sun Feb 24 10:35:34 2008
--- openafs/src/WINNT/afsd/cm_scache.c Wed Mar 19 16:18:37 2008
***************
*** 191,202 ****
* tried to store this to server but failed */
scp->mask = 0;
- /* drop held volume ref */
- if (scp->volp) {
- cm_PutVolume(scp->volp);
- scp->volp = NULL;
- }
-
/* discard symlink info */
scp->mountPointStringp[0] = '\0';
memset(&scp->mountRootFid, 0, sizeof(cm_fid_t));
--- 191,196 ----
***************
*** 320,326 ****
"invalid cm_scache_t address");
memset(scp, 0, sizeof(cm_scache_t));
scp->magic = CM_SCACHE_MAGIC;
! lock_InitializeMutex(&scp->mx, "cm_scache_t mutex");
lock_InitializeRWLock(&scp->bufCreateLock, "cm_scache_t bufCreateLock");
#ifdef USE_BPLUS
lock_InitializeRWLock(&scp->dirlock, "cm_scache_t dirlock");
--- 314,320 ----
"invalid cm_scache_t address");
memset(scp, 0, sizeof(cm_scache_t));
scp->magic = CM_SCACHE_MAGIC;
! lock_InitializeRWLock(&scp->rw, "cm_scache_t rw");
lock_InitializeRWLock(&scp->bufCreateLock, "cm_scache_t bufCreateLock");
#ifdef USE_BPLUS
lock_InitializeRWLock(&scp->dirlock, "cm_scache_t dirlock");
***************
*** 376,382 ****
cm_data.fakeSCache.linkCount = 1;
cm_data.fakeSCache.refCount = 1;
}
! lock_InitializeMutex(&cm_data.fakeSCache.mx, "cm_scache_t mutex");
}
long
--- 370,376 ----
cm_data.fakeSCache.linkCount = 1;
cm_data.fakeSCache.refCount = 1;
}
! lock_InitializeRWLock(&cm_data.fakeSCache.rw, "cm_scache_t rw");
}
long
***************
*** 410,420 ****
fprintf(stderr, "cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC\n");
return -3;
}
- if (scp->volp && scp->volp->magic != CM_VOLUME_MAGIC) {
- afsi_log("cm_ValidateSCache failure: scp->volp->magic != CM_VOLUME_MAGIC");
- fprintf(stderr, "cm_ValidateSCache failure: scp->volp->magic != CM_VOLUME_MAGIC\n");
- return -4;
- }
if (i > cm_data.currentSCaches ) {
afsi_log("cm_ValidateSCache failure: LRU First queue loops");
fprintf(stderr, "cm_ValidateSCache failure: LUR First queue loops\n");
--- 404,409 ----
***************
*** 444,454 ****
fprintf(stderr, "cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC\n");
return -7;
}
- if (scp->volp && scp->volp->magic != CM_VOLUME_MAGIC) {
- afsi_log("cm_ValidateSCache failure: scp->volp->magic != CM_VOLUME_MAGIC");
- fprintf(stderr, "cm_ValidateSCache failure: scp->volp->magic != CM_VOLUME_MAGIC\n");
- return -8;
- }
if (i > cm_data.currentSCaches ) {
afsi_log("cm_ValidateSCache failure: LRU Last queue loops");
fprintf(stderr, "cm_ValidateSCache failure: LUR Last queue loops\n");
--- 433,438 ----
***************
*** 463,468 ****
--- 447,454 ----
for ( i=0; i < cm_data.scacheHashTableSize; i++ ) {
for ( scp = cm_data.scacheHashTablep[i]; scp; scp = scp->nextp ) {
+ afs_uint32 hash;
+ hash = CM_SCACHE_HASH(&scp->fid);
if (scp->magic != CM_SCACHE_MAGIC) {
afsi_log("cm_ValidateSCache failure: scp->magic != CM_SCACHE_MAGIC");
fprintf(stderr, "cm_ValidateSCache failure: scp->magic != CM_SCACHE_MAGIC\n");
***************
*** 478,487 ****
fprintf(stderr, "cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC\n");
return -11;
}
! if (scp->volp && scp->volp->magic != CM_VOLUME_MAGIC) {
! afsi_log("cm_ValidateSCache failure: scp->volp->magic != CM_VOLUME_MAGIC");
! fprintf(stderr, "cm_ValidateSCache failure: scp->volp->magic != CM_VOLUME_MAGIC\n");
! return -12;
}
}
}
--- 464,473 ----
fprintf(stderr, "cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC\n");
return -11;
}
! if (hash != i) {
! afsi_log("cm_ValidateSCache failure: scp hash != hash index");
! fprintf(stderr, "cm_ValidateSCache failure: scp hash != hash index\n");
! return -13;
}
}
}
***************
*** 512,520 ****
lock_ObtainWrite(&cm_scacheLock);
for ( scp = cm_data.allSCachesp; scp; scp = scp->allNextp ) {
if (scp->cbServerp) {
! if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp) {
! if (scp->volp->cbExpiresRO == scp->cbExpires) {
! scp->volp->cbExpiresRO = now+1;
}
}
scp->cbExpires = now+1;
--- 498,509 ----
lock_ObtainWrite(&cm_scacheLock);
for ( scp = cm_data.allSCachesp; scp; scp = scp->allNextp ) {
if (scp->cbServerp) {
! if (scp->flags & CM_SCACHEFLAG_PURERO) {
! cm_volume_t *volp = cm_GetVolumeByFID(&scp->fid);
! if (volp) {
! if (volp->cbExpiresRO == scp->cbExpires)
! volp->cbExpiresRO = now+1;
! cm_PutVolume(volp);
}
}
scp->cbExpires = now+1;
***************
*** 533,541 ****
for ( scp = cm_data.allSCachesp; scp;
scp = scp->allNextp ) {
if (scp->randomACLp) {
! lock_ObtainMutex(&scp->mx);
cm_FreeAllACLEnts(scp);
! lock_ReleaseMutex(&scp->mx);
}
if (scp->cbServerp) {
--- 522,530 ----
for ( scp = cm_data.allSCachesp; scp;
scp = scp->allNextp ) {
if (scp->randomACLp) {
! lock_ObtainWrite(&scp->rw);
cm_FreeAllACLEnts(scp);
! lock_ReleaseWrite(&scp->rw);
}
if (scp->cbServerp) {
***************
*** 552,558 ****
scp->dirDataVersion = -1;
lock_FinalizeRWLock(&scp->dirlock);
#endif
! lock_FinalizeMutex(&scp->mx);
lock_FinalizeRWLock(&scp->bufCreateLock);
}
lock_ReleaseWrite(&cm_scacheLock);
--- 541,547 ----
scp->dirDataVersion = -1;
lock_FinalizeRWLock(&scp->dirlock);
#endif
! lock_FinalizeRWLock(&scp->rw);
lock_FinalizeRWLock(&scp->bufCreateLock);
}
lock_ReleaseWrite(&cm_scacheLock);
***************
*** 579,585 ****
for ( scp = cm_data.allSCachesp; scp;
scp = scp->allNextp ) {
! lock_InitializeMutex(&scp->mx, "cm_scache_t mutex");
lock_InitializeRWLock(&scp->bufCreateLock, "cm_scache_t bufCreateLock");
#ifdef USE_BPLUS
lock_InitializeRWLock(&scp->dirlock, "cm_scache_t dirlock");
--- 568,574 ----
for ( scp = cm_data.allSCachesp; scp;
scp = scp->allNextp ) {
! lock_InitializeRWLock(&scp->rw, "cm_scache_t rw");
lock_InitializeRWLock(&scp->bufCreateLock, "cm_scache_t bufCreateLock");
#ifdef USE_BPLUS
lock_InitializeRWLock(&scp->dirlock, "cm_scache_t dirlock");
***************
*** 627,642 ****
return NULL;
}
! lock_ObtainWrite(&cm_scacheLock);
for (scp=cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) {
if (cm_FidCmp(fidp, &scp->fid) == 0) {
cm_HoldSCacheNoLock(scp);
cm_AdjustScacheLRU(scp);
lock_ReleaseWrite(&cm_scacheLock);
return scp;
}
}
! lock_ReleaseWrite(&cm_scacheLock);
return NULL;
}
--- 616,632 ----
return NULL;
}
! lock_ObtainRead(&cm_scacheLock);
for (scp=cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) {
if (cm_FidCmp(fidp, &scp->fid) == 0) {
cm_HoldSCacheNoLock(scp);
+ lock_ConvertRToW(&cm_scacheLock);
cm_AdjustScacheLRU(scp);
lock_ReleaseWrite(&cm_scacheLock);
return scp;
}
}
! lock_ReleaseRead(&cm_scacheLock);
return NULL;
}
***************
*** 741,752 ****
* assume that no one else is using the one this is returned.
*/
lock_ReleaseWrite(&cm_scacheLock);
! lock_ObtainMutex(&scp->mx);
lock_ObtainWrite(&cm_scacheLock);
#endif
scp->fid = *fidp;
- scp->volp = cm_data.rootSCachep->volp;
- cm_GetVolume(scp->volp); /* grab an additional reference */
scp->dotdotFid.cell=AFS_FAKE_ROOT_CELL_ID;
scp->dotdotFid.volume=AFS_FAKE_ROOT_VOL_ID;
scp->dotdotFid.unique=1;
--- 731,740 ----
* assume that no one else is using the one this is returned.
*/
lock_ReleaseWrite(&cm_scacheLock);
! lock_ObtainWrite(&scp->rw);
lock_ObtainWrite(&cm_scacheLock);
#endif
scp->fid = *fidp;
scp->dotdotFid.cell=AFS_FAKE_ROOT_CELL_ID;
scp->dotdotFid.volume=AFS_FAKE_ROOT_VOL_ID;
scp->dotdotFid.unique=1;
***************
*** 772,778 ****
scp->bufDataVersionLow=cm_data.fakeDirVersion;
scp->lockDataVersion=-1; /* no lock yet */
#if not_too_dangerous
! lock_ReleaseMutex(&scp->mx);
#endif
*outScpp = scp;
lock_ReleaseWrite(&cm_scacheLock);
--- 760,766 ----
scp->bufDataVersionLow=cm_data.fakeDirVersion;
scp->lockDataVersion=-1; /* no lock yet */
#if not_too_dangerous
! lock_ReleaseWrite(&scp->rw);
#endif
*outScpp = scp;
lock_ReleaseWrite(&cm_scacheLock);
***************
*** 792,798 ****
if (!cellp)
return CM_ERROR_NOSUCHCELL;
! code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, CM_GETVOL_FLAG_CREATE, &volp);
if (code)
return code;
lock_ObtainWrite(&cm_scacheLock);
--- 780,786 ----
if (!cellp)
return CM_ERROR_NOSUCHCELL;
! code = cm_FindVolumeByID(cellp, fidp->volume, userp, reqp, CM_GETVOL_FLAG_CREATE, &volp);
if (code)
return code;
lock_ObtainWrite(&cm_scacheLock);
***************
*** 808,814 ****
osi_Log1(afsd_logp,"cm_GetSCache (3) outScpp 0x%p", scp);
#endif
cm_HoldSCacheNoLock(scp);
- osi_assertx(scp->volp == volp, "cm_scache_t volume has unexpected value");
cm_AdjustScacheLRU(scp);
lock_ReleaseWrite(&cm_scacheLock);
if (volp)
--- 796,801 ----
***************
*** 838,870 ****
* assume that no one else is using the one this is returned.
*/
lock_ReleaseWrite(&cm_scacheLock);
! lock_ObtainMutex(&scp->mx);
lock_ObtainWrite(&cm_scacheLock);
#endif
scp->fid = *fidp;
- scp->volp = volp; /* a held reference */
-
if (!cm_freelanceEnabled || !isRoot) {
/* if this scache entry represents a volume root then we need
* to copy the dotdotFipd from the volume structure where the
* "master" copy is stored (defect 11489)
*/
! if (scp->fid.vnode == 1 && scp->fid.unique == 1) {
! scp->dotdotFid = volp->dotdotFid;
! }
!
! if (volp->ro.ID == fidp->volume)
scp->flags |= (CM_SCACHEFLAG_PURERO | CM_SCACHEFLAG_RO);
! else if (volp->bk.ID == fidp->volume)
scp->flags |= CM_SCACHEFLAG_RO;
}
scp->nextp = cm_data.scacheHashTablep[hash];
cm_data.scacheHashTablep[hash] = scp;
scp->flags |= CM_SCACHEFLAG_INHASH;
scp->refCount = 1;
osi_Log1(afsd_logp,"cm_GetSCache sets refCount to 1 scp 0x%x", scp);
#if not_too_dangerous
! lock_ReleaseMutex(&scp->mx);
#endif
/* XXX - The following fields in the cm_scache are
--- 825,861 ----
* assume that no one else is using the one this is returned.
*/
lock_ReleaseWrite(&cm_scacheLock);
! lock_ObtainWrite(&scp->rw);
lock_ObtainWrite(&cm_scacheLock);
#endif
scp->fid = *fidp;
if (!cm_freelanceEnabled || !isRoot) {
/* if this scache entry represents a volume root then we need
* to copy the dotdotFipd from the volume structure where the
* "master" copy is stored (defect 11489)
*/
! if (volp->ro.ID == fidp->volume) {
scp->flags |= (CM_SCACHEFLAG_PURERO | CM_SCACHEFLAG_RO);
! if (scp->fid.vnode == 1 && scp->fid.unique == 1)
! scp->dotdotFid = volp->ro.dotdotFid;
! } else if (volp->bk.ID == fidp->volume) {
scp->flags |= CM_SCACHEFLAG_RO;
+ if (scp->fid.vnode == 1 && scp->fid.unique == 1)
+ scp->dotdotFid = volp->bk.dotdotFid;
+ } else {
+ if (scp->fid.vnode == 1 && scp->fid.unique == 1)
+ scp->dotdotFid = volp->rw.dotdotFid;
+ }
}
+ if (volp)
+ cm_PutVolume(volp);
scp->nextp = cm_data.scacheHashTablep[hash];
cm_data.scacheHashTablep[hash] = scp;
scp->flags |= CM_SCACHEFLAG_INHASH;
scp->refCount = 1;
osi_Log1(afsd_logp,"cm_GetSCache sets refCount to 1 scp 0x%x", scp);
#if not_too_dangerous
! lock_ReleaseWrite(&scp->rw);
#endif
/* XXX - The following fields in the cm_scache are
***************
*** 1233,1241 ****
lock_ReleaseMutex(&bufp->mx);
code = cm_GetCallback(scp, userp, reqp, (flags & CM_SCACHESYNC_FORCECB)?1:0);
if (bufLocked) {
! lock_ReleaseMutex(&scp->mx);
lock_ObtainMutex(&bufp->mx);
! lock_ObtainMutex(&scp->mx);
}
if (code)
return code;
--- 1224,1232 ----
lock_ReleaseMutex(&bufp->mx);
code = cm_GetCallback(scp, userp, reqp, (flags & CM_SCACHESYNC_FORCECB)?1:0);
if (bufLocked) {
! lock_ReleaseWrite(&scp->rw);
lock_ObtainMutex(&bufp->mx);
! lock_ObtainWrite(&scp->rw);
}
if (code)
return code;
***************
*** 1260,1268 ****
if (bufLocked) lock_ReleaseMutex(&bufp->mx);
code = cm_GetAccessRights(scp, userp, reqp);
if (bufLocked) {
! lock_ReleaseMutex(&scp->mx);
lock_ObtainMutex(&bufp->mx);
! lock_ObtainMutex(&scp->mx);
}
if (code)
return code;
--- 1251,1259 ----
if (bufLocked) lock_ReleaseMutex(&bufp->mx);
code = cm_GetAccessRights(scp, userp, reqp);
if (bufLocked) {
! lock_ReleaseWrite(&scp->rw);
lock_ObtainMutex(&bufp->mx);
! lock_ObtainWrite(&scp->rw);
}
if (code)
return code;
***************
*** 1303,1312 ****
do {
if (bufLocked)
lock_ReleaseMutex(&bufp->mx);
! osi_SleepM((LONG_PTR) &scp->flags, &scp->mx);
if (bufLocked)
lock_ObtainMutex(&bufp->mx);
! lock_ObtainMutex(&scp->mx);
} while (!cm_SyncOpCheckContinue(scp, flags, bufp));
smb_UpdateServerPriority();
--- 1294,1303 ----
do {
if (bufLocked)
lock_ReleaseMutex(&bufp->mx);
! osi_SleepW((LONG_PTR) &scp->flags, &scp->rw);
if (bufLocked)
lock_ObtainMutex(&bufp->mx);
! lock_ObtainWrite(&scp->rw);
} while (!cm_SyncOpCheckContinue(scp, flags, bufp));
smb_UpdateServerPriority();
***************
*** 1394,1400 ****
osi_queueData_t *qdp;
cm_buf_t *tbufp;
! lock_AssertMutex(&scp->mx);
/* now, update the recorded state for RPC-type calls */
if (flags & CM_SCACHESYNC_FETCHSTATUS)
--- 1385,1391 ----
osi_queueData_t *qdp;
cm_buf_t *tbufp;
! lock_AssertWrite(&scp->rw);
/* now, update the recorded state for RPC-type calls */
if (flags & CM_SCACHESYNC_FETCHSTATUS)
***************
*** 1523,1530 ****
statusp->SyncCounter = 0;
statusp->dataVersionHigh = (afs_uint32)(cm_data.fakeDirVersion >> 32);
statusp->errorCode = 0;
-
- buf_ForceDataVersion(scp, scp->dataVersion, cm_data.fakeDirVersion);
}
#endif /* AFS_FREELANCE_CLIENT */
--- 1514,1519 ----
***************
*** 1571,1577 ****
if (scp->cbServerp) {
struct cm_volume *volp = NULL;
! cm_GetVolumeByID(cellp, scp->fid.volume, userp,
(cm_req_t *) NULL, CM_GETVOL_FLAG_CREATE, &volp);
osi_Log2(afsd_logp, "old data from server %x volume %s",
scp->cbServerp->addr.sin_addr.s_addr,
--- 1560,1566 ----
if (scp->cbServerp) {
struct cm_volume *volp = NULL;
! cm_FindVolumeByID(cellp, scp->fid.volume, userp,
(cm_req_t *) NULL, CM_GETVOL_FLAG_CREATE, &volp);
osi_Log2(afsd_logp, "old data from server %x volume %s",
scp->cbServerp->addr.sin_addr.s_addr,
***************
*** 1579,1585 ****
if (volp)
cm_PutVolume(volp);
}
! osi_Log3(afsd_logp, "Bad merge, scp %x, scp dv %I64d, RPC dv %I64d",
scp, scp->dataVersion, dataVersion);
/* we have a number of data fetch/store operations running
* concurrently, and we can tell which one executed last at the
--- 1568,1574 ----
if (volp)
cm_PutVolume(volp);
}
! osi_Log3(afsd_logp, "Bad merge, scp %x, scp dv %d, RPC dv %d",
scp, scp->dataVersion, dataVersion);
/* we have a number of data fetch/store operations running
* concurrently, and we can tell which one executed last at the
***************
*** 1658,1665 ****
}
if (scp->dataVersion != 0 &&
! (!(flags & CM_MERGEFLAG_DIROP) && dataVersion != scp->dataVersion ||
! (flags & CM_MERGEFLAG_DIROP) && dataVersion - scp->dataVersion > 1)) {
/*
* We now know that all of the data buffers that we have associated
* with this scp are invalid. Subsequent operations will go faster
--- 1647,1654 ----
}
if (scp->dataVersion != 0 &&
! (!(flags & (CM_MERGEFLAG_DIROP|CM_MERGEFLAG_STOREDATA)) && dataVersion != scp->dataVersion ||
! (flags & (CM_MERGEFLAG_DIROP|CM_MERGEFLAG_STOREDATA)) && dataVersion - scp->dataVersion > 1)) {
/*
* We now know that all of the data buffers that we have associated
* with this scp are invalid. Subsequent operations will go faster
***************
*** 1667,1672 ****
--- 1656,1663 ----
*
* We do not remove directory buffers if the dataVersion delta is 1 because
* those version numbers will be updated as part of the directory operation.
+ *
+ * We do not remove storedata buffers because they will still be valid.
*/
int i, j;
cm_buf_t **lbpp;
***************
*** 1724,1730 ****
* the size of the file.
*/
if (((flags & CM_MERGEFLAG_STOREDATA) && dataVersion - scp->dataVersion > 1) ||
! (!(flags & CM_MERGEFLAG_STOREDATA) && scp->dataVersion != dataVersion))
scp->bufDataVersionLow = dataVersion;
scp->dataVersion = dataVersion;
--- 1715,1722 ----
* the size of the file.
*/
if (((flags & CM_MERGEFLAG_STOREDATA) && dataVersion - scp->dataVersion > 1) ||
! (!(flags & CM_MERGEFLAG_STOREDATA) && scp->dataVersion != dataVersion) ||
! scp->bufDataVersionLow == 0)
scp->bufDataVersionLow = dataVersion;
scp->dataVersion = dataVersion;
***************
*** 1740,1746 ****
*/
void cm_DiscardSCache(cm_scache_t *scp)
{
! lock_AssertMutex(&scp->mx);
if (scp->cbServerp) {
cm_PutServer(scp->cbServerp);
scp->cbServerp = NULL;
--- 1732,1738 ----
*/
void cm_DiscardSCache(cm_scache_t *scp)
{
! lock_AssertWrite(&scp->rw);
if (scp->cbServerp) {
cm_PutServer(scp->cbServerp);
scp->cbServerp = NULL;
***************
*** 1885,1893 ****
for (scp = cm_data.allSCachesp; scp; scp = scp->allNextp)
{
! sprintf(output, "%s scp=0x%p, fid (cell=%d, volume=%d, vnode=%d, unique=%d) volp=0x%p type=%d dv=%I64d len=0x%I64x mp='%s' flags=0x%x cb=0x%x refCount=%u\r\n",
cookie, scp, scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
! scp->volp, scp->fileType, scp->dataVersion, scp->length.QuadPart, scp->mountPointStringp, scp->flags,
(unsigned long)scp->cbExpires, scp->refCount);
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
}
--- 1877,1885 ----
for (scp = cm_data.allSCachesp; scp; scp = scp->allNextp)
{
! sprintf(output, "%s scp=0x%p, fid (cell=%d, volume=%d, vnode=%d, unique=%d) type=%d dv=%I64d len=0x%I64x mp='%s' flags=0x%x cb=0x%x refCount=%u\r\n",
cookie, scp, scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
! scp->fileType, scp->dataVersion, scp->length.QuadPart, scp->mountPointStringp, scp->flags,
(unsigned long)scp->cbExpires, scp->refCount);
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
}
Index: openafs/src/WINNT/afsd/cm_scache.h
diff -c openafs/src/WINNT/afsd/cm_scache.h:1.21.2.22 openafs/src/WINNT/afsd/cm_scache.h:1.21.2.24
*** openafs/src/WINNT/afsd/cm_scache.h:1.21.2.22 Sun Feb 24 01:33:21 2008
--- openafs/src/WINNT/afsd/cm_scache.h Thu Mar 13 00:39:17 2008
***************
*** 42,48 ****
osi_queue_t q; /* list of all locks [protected by
cm_scacheLock] */
osi_queue_t fileq; /* per-file list of locks [protected
! by scp->mx]*/
cm_user_t *userp; /* The user to which this lock belongs
to [immutable; held] */
--- 42,48 ----
osi_queue_t q; /* list of all locks [protected by
cm_scacheLock] */
osi_queue_t fileq; /* per-file list of locks [protected
! by scp->rw]*/
cm_user_t *userp; /* The user to which this lock belongs
to [immutable; held] */
***************
*** 93,102 ****
struct cm_scache *nextp; /* next in hash; cm_scacheLock */
struct cm_scache *allNextp; /* next in all scache list; cm_scacheLock */
cm_fid_t fid;
! afs_uint32 flags; /* flags; locked by mx */
/* synchronization stuff */
! osi_mutex_t mx; /* mutex for this structure */
osi_rwlock_t bufCreateLock; /* read-locked during buffer creation;
* write-locked to prevent buffers from
* being created during a truncate op, etc.
--- 93,102 ----
struct cm_scache *nextp; /* next in hash; cm_scacheLock */
struct cm_scache *allNextp; /* next in all scache list; cm_scacheLock */
cm_fid_t fid;
! afs_uint32 flags; /* flags; locked by rw */
/* synchronization stuff */
! osi_rwlock_t rw; /* rwlock for this structure */
osi_rwlock_t bufCreateLock; /* read-locked during buffer creation;
* write-locked to prevent buffers from
* being created during a truncate op, etc.
***************
*** 157,163 ****
afs_int32 serverLock; /* current lock we have acquired on
* this file. One of (-1), LockRead
* or LockWrite. [protected by
! * scp->mx]. In the future, this
* should be replaced by a queue of
* cm_server_lock_t objects which keep
* track of lock type, the user for
--- 157,163 ----
afs_int32 serverLock; /* current lock we have acquired on
* this file. One of (-1), LockRead
* or LockWrite. [protected by
! * scp->rw]. In the future, this
* should be replaced by a queue of
* cm_server_lock_t objects which keep
* track of lock type, the user for
***************
*** 190,198 ****
have CM_FILELOCK_FLAG_CLIENTONLY
set. */
- /* volume info */
- struct cm_volume *volp; /* volume info; held reference */
-
/* bulk stat progress */
osi_hyper_t bulkStatProgress; /* track bulk stats of large dirs */
--- 190,195 ----
Index: openafs/src/WINNT/afsd/cm_server.c
diff -c openafs/src/WINNT/afsd/cm_server.c:1.25.2.25 openafs/src/WINNT/afsd/cm_server.c:1.25.2.28
*** openafs/src/WINNT/afsd/cm_server.c:1.25.2.25 Fri Feb 22 19:17:35 2008
--- openafs/src/WINNT/afsd/cm_server.c Thu Mar 13 00:39:17 2008
***************
*** 27,32 ****
--- 27,33 ----
#include
osi_rwlock_t cm_serverLock;
+ osi_rwlock_t cm_syscfgLock;
cm_server_t *cm_allServersp;
afs_uint32 cm_numFileServers = 0;
***************
*** 37,49 ****
{
cm_server_t *tsp;
! lock_ObtainWrite(&cm_serverLock);
for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
cm_GetServerNoLock(tsp);
cm_ForceNewConnections(tsp);
cm_PutServerNoLock(tsp);
}
! lock_ReleaseWrite(&cm_serverLock);
}
void
--- 38,50 ----
{
cm_server_t *tsp;
! lock_ObtainRead(&cm_serverLock);
for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
cm_GetServerNoLock(tsp);
cm_ForceNewConnections(tsp);
cm_PutServerNoLock(tsp);
}
! lock_ReleaseRead(&cm_serverLock);
}
void
***************
*** 141,147 ****
cm_InitReq(&req);
lock_ReleaseMutex(&tsp->mx);
! code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
&req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
lock_ObtainMutex(&tsp->mx);
if (code == 0) {
--- 142,148 ----
cm_InitReq(&req);
lock_ReleaseMutex(&tsp->mx);
! code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
&req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
lock_ObtainMutex(&tsp->mx);
if (code == 0) {
***************
*** 178,184 ****
cm_InitReq(&req);
lock_ReleaseMutex(&tsp->mx);
! code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
&req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
lock_ObtainMutex(&tsp->mx);
if (code == 0) {
--- 179,185 ----
cm_InitReq(&req);
lock_ReleaseMutex(&tsp->mx);
! code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
&req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
lock_ObtainMutex(&tsp->mx);
if (code == 0) {
***************
*** 211,220 ****
int isDown;
int isFS;
! lock_ObtainWrite(&cm_serverLock);
for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
cm_GetServerNoLock(tsp);
! lock_ReleaseWrite(&cm_serverLock);
/* now process the server */
lock_ObtainMutex(&tsp->mx);
--- 212,221 ----
int isDown;
int isFS;
! lock_ObtainRead(&cm_serverLock);
for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
cm_GetServerNoLock(tsp);
! lock_ReleaseRead(&cm_serverLock);
/* now process the server */
lock_ObtainMutex(&tsp->mx);
***************
*** 249,258 ****
*/
cm_GCConnections(tsp);
! lock_ObtainWrite(&cm_serverLock);
cm_PutServerNoLock(tsp);
}
! lock_ReleaseWrite(&cm_serverLock);
}
#else /* MULTI_CHECKSERVERS */
void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp)
--- 250,259 ----
*/
cm_GCConnections(tsp);
! lock_ObtainRead(&cm_serverLock);
cm_PutServerNoLock(tsp);
}
! lock_ReleaseRead(&cm_serverLock);
}
#else /* MULTI_CHECKSERVERS */
void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp)
***************
*** 302,308 ****
if ((flags & CM_FLAG_CHECKFILESERVERS) ||
!(flags & (CM_FLAG_CHECKFILESERVERS|CM_FLAG_CHECKVLDBSERVERS)))
{
! lock_ObtainWrite(&cm_serverLock);
nconns = 0;
for (nconns=0, tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
if (tsp->type != CM_SERVER_FILE ||
--- 303,309 ----
if ((flags & CM_FLAG_CHECKFILESERVERS) ||
!(flags & (CM_FLAG_CHECKFILESERVERS|CM_FLAG_CHECKVLDBSERVERS)))
{
! lock_ObtainRead(&cm_serverLock);
nconns = 0;
for (nconns=0, tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
if (tsp->type != CM_SERVER_FILE ||
***************
*** 311,317 ****
continue;
cm_GetServerNoLock(tsp);
! lock_ReleaseWrite(&cm_serverLock);
lock_ObtainMutex(&tsp->mx);
isDown = tsp->flags & CM_SERVERFLAG_DOWN;
--- 312,318 ----
continue;
cm_GetServerNoLock(tsp);
! lock_ReleaseRead(&cm_serverLock);
lock_ObtainMutex(&tsp->mx);
isDown = tsp->flags & CM_SERVERFLAG_DOWN;
***************
*** 320,326 ****
!((isDown && (flags & CM_FLAG_CHECKDOWNSERVERS)) ||
(!isDown && (flags & CM_FLAG_CHECKUPSERVERS)))) {
lock_ReleaseMutex(&tsp->mx);
! lock_ObtainWrite(&cm_serverLock);
continue;
}
--- 321,328 ----
!((isDown && (flags & CM_FLAG_CHECKDOWNSERVERS)) ||
(!isDown && (flags & CM_FLAG_CHECKUPSERVERS)))) {
lock_ReleaseMutex(&tsp->mx);
! lock_ObtainRead(&cm_serverLock);
! cm_PutServerNoLock(tsp);
continue;
}
***************
*** 330,347 ****
serversp[nconns] = tsp;
code = cm_ConnByServer(tsp, cm_rootUserp, &conns[nconns]);
if (code) {
! lock_ObtainWrite(&cm_serverLock);
cm_PutServerNoLock(tsp);
continue;
}
! lock_ObtainWrite(&cm_serverLock);
! rxconns[nconns] = cm_GetRxConn(conns[nconns]);
if (conntimer[nconns] = (isDown ? 1 : 0))
rx_SetConnDeadTime(rxconns[nconns], 10);
nconns++;
}
! lock_ReleaseWrite(&cm_serverLock);
if (nconns) {
/* Perform the multi call */
--- 332,349 ----
serversp[nconns] = tsp;
code = cm_ConnByServer(tsp, cm_rootUserp, &conns[nconns]);
if (code) {
! lock_ObtainRead(&cm_serverLock);
cm_PutServerNoLock(tsp);
continue;
}
! lock_ObtainRead(&cm_serverLock);
! rxconns[nconns] = cm_GetRxConn(conns[nconns]);
if (conntimer[nconns] = (isDown ? 1 : 0))
rx_SetConnDeadTime(rxconns[nconns], 10);
nconns++;
}
! lock_ReleaseRead(&cm_serverLock);
if (nconns) {
/* Perform the multi call */
***************
*** 403,409 ****
cm_InitReq(&req);
lock_ReleaseMutex(&tsp->mx);
! code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
&req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
lock_ObtainMutex(&tsp->mx);
if (code == 0) {
--- 405,411 ----
cm_InitReq(&req);
lock_ReleaseMutex(&tsp->mx);
! code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
&req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
lock_ObtainMutex(&tsp->mx);
if (code == 0) {
***************
*** 441,447 ****
cm_InitReq(&req);
lock_ReleaseMutex(&tsp->mx);
! code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
&req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
lock_ObtainMutex(&tsp->mx);
if (code == 0) {
--- 443,449 ----
cm_InitReq(&req);
lock_ReleaseMutex(&tsp->mx);
! code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
&req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
lock_ObtainMutex(&tsp->mx);
if (code == 0) {
***************
*** 532,538 ****
cm_InitReq(&req);
lock_ReleaseMutex(&tsp->mx);
! code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
&req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
lock_ObtainMutex(&tsp->mx);
if (code == 0) {
--- 534,540 ----
cm_InitReq(&req);
lock_ReleaseMutex(&tsp->mx);
! code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
&req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
lock_ObtainMutex(&tsp->mx);
if (code == 0) {
***************
*** 570,576 ****
cm_InitReq(&req);
lock_ReleaseMutex(&tsp->mx);
! code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
&req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
lock_ObtainMutex(&tsp->mx);
if (code == 0) {
--- 572,578 ----
cm_InitReq(&req);
lock_ReleaseMutex(&tsp->mx);
! code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
&req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
lock_ObtainMutex(&tsp->mx);
if (code == 0) {
***************
*** 597,603 ****
if ((flags & CM_FLAG_CHECKVLDBSERVERS) ||
!(flags & (CM_FLAG_CHECKFILESERVERS|CM_FLAG_CHECKVLDBSERVERS)))
{
! lock_ObtainWrite(&cm_serverLock);
nconns = 0;
for (nconns=0, tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
if (tsp->type != CM_SERVER_VLDB ||
--- 599,605 ----
if ((flags & CM_FLAG_CHECKVLDBSERVERS) ||
!(flags & (CM_FLAG_CHECKFILESERVERS|CM_FLAG_CHECKVLDBSERVERS)))
{
! lock_ObtainRead(&cm_serverLock);
nconns = 0;
for (nconns=0, tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
if (tsp->type != CM_SERVER_VLDB ||
***************
*** 606,612 ****
continue;
cm_GetServerNoLock(tsp);
! lock_ReleaseWrite(&cm_serverLock);
lock_ObtainMutex(&tsp->mx);
isDown = tsp->flags & CM_SERVERFLAG_DOWN;
--- 608,614 ----
continue;
cm_GetServerNoLock(tsp);
! lock_ReleaseRead(&cm_serverLock);
lock_ObtainMutex(&tsp->mx);
isDown = tsp->flags & CM_SERVERFLAG_DOWN;
***************
*** 615,621 ****
!((isDown && (flags & CM_FLAG_CHECKDOWNSERVERS)) ||
(!isDown && (flags & CM_FLAG_CHECKUPSERVERS)))) {
lock_ReleaseMutex(&tsp->mx);
! lock_ObtainWrite(&cm_serverLock);
continue;
}
--- 617,624 ----
!((isDown && (flags & CM_FLAG_CHECKDOWNSERVERS)) ||
(!isDown && (flags & CM_FLAG_CHECKUPSERVERS)))) {
lock_ReleaseMutex(&tsp->mx);
! lock_ObtainRead(&cm_serverLock);
! cm_PutServerNoLock(tsp);
continue;
}
***************
*** 625,635 ****
serversp[nconns] = tsp;
code = cm_ConnByServer(tsp, cm_rootUserp, &conns[nconns]);
if (code) {
! lock_ObtainWrite(&cm_serverLock);
cm_PutServerNoLock(tsp);
continue;
}
! lock_ObtainWrite(&cm_serverLock);
rxconns[nconns] = cm_GetRxConn(conns[nconns]);
conntimer[nconns] = (isDown ? 1 : 0);
if (isDown)
--- 628,638 ----
serversp[nconns] = tsp;
code = cm_ConnByServer(tsp, cm_rootUserp, &conns[nconns]);
if (code) {
! lock_ObtainRead(&cm_serverLock);
cm_PutServerNoLock(tsp);
continue;
}
! lock_ObtainRead(&cm_serverLock);
rxconns[nconns] = cm_GetRxConn(conns[nconns]);
conntimer[nconns] = (isDown ? 1 : 0);
if (isDown)
***************
*** 637,643 ****
nconns++;
}
! lock_ReleaseWrite(&cm_serverLock);
if (nconns) {
/* Perform the multi call */
--- 640,646 ----
nconns++;
}
! lock_ReleaseRead(&cm_serverLock);
if (nconns) {
/* Perform the multi call */
***************
*** 686,692 ****
cm_InitReq(&req);
lock_ReleaseMutex(&tsp->mx);
! code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
&req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
lock_ObtainMutex(&tsp->mx);
if (code == 0) {
--- 689,695 ----
cm_InitReq(&req);
lock_ReleaseMutex(&tsp->mx);
! code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
&req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
lock_ObtainMutex(&tsp->mx);
if (code == 0) {
***************
*** 724,730 ****
cm_InitReq(&req);
lock_ReleaseMutex(&tsp->mx);
! code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
&req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
lock_ObtainMutex(&tsp->mx);
if (code == 0) {
--- 727,733 ----
cm_InitReq(&req);
lock_ReleaseMutex(&tsp->mx);
! code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
&req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
lock_ObtainMutex(&tsp->mx);
if (code == 0) {
***************
*** 763,794 ****
if (osi_Once(&once)) {
lock_InitializeRWLock(&cm_serverLock, "cm_serverLock");
osi_EndOnce(&once);
}
}
void cm_GetServer(cm_server_t *serverp)
{
! lock_ObtainWrite(&cm_serverLock);
! serverp->refCount++;
! lock_ReleaseWrite(&cm_serverLock);
}
void cm_GetServerNoLock(cm_server_t *serverp)
{
! serverp->refCount++;
}
void cm_PutServer(cm_server_t *serverp)
{
! lock_ObtainWrite(&cm_serverLock);
! osi_assertx(serverp->refCount-- > 0, "cm_server_t refCount 0");
! lock_ReleaseWrite(&cm_serverLock);
}
void cm_PutServerNoLock(cm_server_t *serverp)
{
! osi_assertx(serverp->refCount-- > 0, "cm_server_t refCount 0");
}
void cm_SetServerNo64Bit(cm_server_t * serverp, int no64bit)
--- 766,816 ----
if (osi_Once(&once)) {
lock_InitializeRWLock(&cm_serverLock, "cm_serverLock");
+ lock_InitializeRWLock(&cm_syscfgLock, "cm_syscfgLock");
osi_EndOnce(&once);
}
}
+ /* Protected by cm_syscfgLock (rw) */
+ int cm_noIPAddr; /* number of client network interfaces */
+ int cm_IPAddr[CM_MAXINTERFACE_ADDR]; /* client's IP address in host order */
+ int cm_SubnetMask[CM_MAXINTERFACE_ADDR];/* client's subnet mask in host order*/
+ int cm_NetMtu[CM_MAXINTERFACE_ADDR]; /* client's MTU sizes */
+ int cm_NetFlags[CM_MAXINTERFACE_ADDR]; /* network flags */
+ int cm_LanAdapterChangeDetected = 1;
+
+ void cm_SetLanAdapterChangeDetected(void)
+ {
+ lock_ObtainWrite(&cm_syscfgLock);
+ cm_LanAdapterChangeDetected = 1;
+ lock_ReleaseWrite(&cm_syscfgLock);
+ }
+
void cm_GetServer(cm_server_t *serverp)
{
! lock_ObtainRead(&cm_serverLock);
! InterlockedIncrement(&serverp->refCount);
! lock_ReleaseRead(&cm_serverLock);
}
void cm_GetServerNoLock(cm_server_t *serverp)
{
! InterlockedIncrement(&serverp->refCount);
}
void cm_PutServer(cm_server_t *serverp)
{
! afs_int32 refCount;
! lock_ObtainRead(&cm_serverLock);
! refCount = InterlockedDecrement(&serverp->refCount);
! osi_assertx(refCount >= 0, "cm_server_t refCount underflow");
! lock_ReleaseRead(&cm_serverLock);
}
void cm_PutServerNoLock(cm_server_t *serverp)
{
! afs_int32 refCount = InterlockedDecrement(&serverp->refCount);
! osi_assertx(refCount >= 0, "cm_server_t refCount underflow");
}
void cm_SetServerNo64Bit(cm_server_t * serverp, int no64bit)
***************
*** 817,835 ****
unsigned long myAddr, myNet, mySubnet;/* in host byte order */
unsigned long netMask;
int i;
-
- int cm_noIPAddr; /* number of client network interfaces */
- int cm_IPAddr[CM_MAXINTERFACE_ADDR]; /* client's IP address in host order */
- int cm_SubnetMask[CM_MAXINTERFACE_ADDR];/* client's subnet mask in host order*/
- int cm_NetMtu[CM_MAXINTERFACE_ADDR]; /* client's MTU sizes */
- int cm_NetFlags[CM_MAXINTERFACE_ADDR]; /* network flags */
long code;
! /* get network related info */
! cm_noIPAddr = CM_MAXINTERFACE_ADDR;
! code = syscfg_GetIFInfo(&cm_noIPAddr,
! cm_IPAddr, cm_SubnetMask,
! cm_NetMtu, cm_NetFlags);
serverAddr = ntohl(serverp->addr.sin_addr.s_addr);
serverp->ipRank = CM_IPRANK_LOW; /* default setings */
--- 839,861 ----
unsigned long myAddr, myNet, mySubnet;/* in host byte order */
unsigned long netMask;
int i;
long code;
+ int writeLock = 0;
! lock_ObtainRead(&cm_syscfgLock);
! if (cm_LanAdapterChangeDetected) {
! lock_ConvertRToW(&cm_syscfgLock);
! writeLock = 1;
! if (cm_LanAdapterChangeDetected) {
! /* get network related info */
! cm_noIPAddr = CM_MAXINTERFACE_ADDR;
! code = syscfg_GetIFInfo(&cm_noIPAddr,
! cm_IPAddr, cm_SubnetMask,
! cm_NetMtu, cm_NetFlags);
! cm_LanAdapterChangeDetected = 0;
! }
! lock_ConvertWToR(&cm_syscfgLock);
! }
serverAddr = ntohl(serverp->addr.sin_addr.s_addr);
serverp->ipRank = CM_IPRANK_LOW; /* default setings */
***************
*** 868,873 ****
--- 894,900 ----
/* random between 0..15*/
serverp->ipRank += min(serverp->ipRank, rand() % 0x000f);
} /* and of for loop */
+ lock_ReleaseRead(&cm_syscfgLock);
}
cm_server_t *cm_NewServer(struct sockaddr_in *socketp, int type, cm_cell_t *cellp, afs_uint32 flags) {
***************
*** 932,938 ****
osi_assertx(addrp->sin_family == AF_INET, "unexpected socket value");
! lock_ObtainWrite(&cm_serverLock);
for (tsp = cm_allServersp; tsp; tsp=tsp->allNextp) {
if (tsp->type == type &&
tsp->addr.sin_addr.s_addr == addrp->sin_addr.s_addr)
--- 959,965 ----
osi_assertx(addrp->sin_family == AF_INET, "unexpected socket value");
! lock_ObtainRead(&cm_serverLock);
for (tsp = cm_allServersp; tsp; tsp=tsp->allNextp) {
if (tsp->type == type &&
tsp->addr.sin_addr.s_addr == addrp->sin_addr.s_addr)
***************
*** 944,950 ****
cm_GetServerNoLock(tsp);
/* drop big table lock */
! lock_ReleaseWrite(&cm_serverLock);
/* return what we found */
return tsp;
--- 971,977 ----
cm_GetServerNoLock(tsp);
/* drop big table lock */
! lock_ReleaseRead(&cm_serverLock);
/* return what we found */
return tsp;
***************
*** 1026,1032 ****
int first = 1;
cm_serverRef_t *tsrp;
! lock_ObtainWrite(&cm_serverLock);
for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
if (first)
first = 0;
--- 1053,1059 ----
int first = 1;
cm_serverRef_t *tsrp;
! lock_ObtainRead(&cm_serverLock);
for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
if (first)
first = 0;
***************
*** 1035,1047 ****
sum ^= (LONG_PTR) tsrp->server;
}
! lock_ReleaseWrite(&cm_serverLock);
return sum;
}
/*
** Insert a server into the server list keeping the list sorted in
! ** asending order of ipRank.
**
** The refCount of the cm_serverRef_t is increased
*/
--- 1062,1074 ----
sum ^= (LONG_PTR) tsrp->server;
}
! lock_ReleaseRead(&cm_serverLock);
return sum;
}
/*
** Insert a server into the server list keeping the list sorted in
! ** ascending order of ipRank.
**
** The refCount of the cm_serverRef_t is increased
*/
Index: openafs/src/WINNT/afsd/cm_server.h
diff -c openafs/src/WINNT/afsd/cm_server.h:1.13.2.11 openafs/src/WINNT/afsd/cm_server.h:1.13.2.13
*** openafs/src/WINNT/afsd/cm_server.h:1.13.2.11 Tue Feb 5 12:38:02 2008
--- openafs/src/WINNT/afsd/cm_server.h Sat Mar 8 18:25:08 2008
***************
*** 36,42 ****
afs_int32 waitCount; /* by mx */
afs_int32 capabilities; /* by mx */
struct cm_cell *cellp; /* cell containing this server */
! unsigned long refCount; /* locked by cm_serverLock */
osi_mutex_t mx;
unsigned short ipRank; /* server priority */
cm_server_vols_t * vols; /* by mx */
--- 36,42 ----
afs_int32 waitCount; /* by mx */
afs_int32 capabilities; /* by mx */
struct cm_cell *cellp; /* cell containing this server */
! afs_int32 refCount; /* Interlocked with cm_serverLock */
osi_mutex_t mx;
unsigned short ipRank; /* server priority */
cm_server_vols_t * vols; /* by mx */
***************
*** 49,55 ****
struct cm_serverRef *next; /* locked by cm_serverLock */
struct cm_server *server; /* locked by cm_serverLock */
enum repstate status; /* locked by cm_serverLock */
! unsigned long refCount; /* locked by cm_serverLock */
afs_uint32 volID; /* locked by cm_serverLock */
} cm_serverRef_t;
--- 49,55 ----
struct cm_serverRef *next; /* locked by cm_serverLock */
struct cm_server *server; /* locked by cm_serverLock */
enum repstate status; /* locked by cm_serverLock */
! afs_int32 refCount; /* locked by cm_serverLock */
afs_uint32 volID; /* locked by cm_serverLock */
} cm_serverRef_t;
***************
*** 100,105 ****
--- 100,107 ----
extern osi_rwlock_t cm_serverLock;
+ extern osi_rwlock_t cm_syscfgLock;
+
extern void cm_InitServer(void);
extern void cm_CheckServers(afs_uint32 flags, struct cm_cell *cellp);
***************
*** 128,131 ****
--- 130,142 ----
extern cm_server_t * cm_FindServerByIP(afs_uint32 addr, int type);
+ extern void cm_SetLanAdapterChangeDetected(void);
+
+ /* Protected by cm_syscfgLock (rw) */
+ extern int cm_noIPAddr; /* number of client network interfaces */
+ extern int cm_IPAddr[CM_MAXINTERFACE_ADDR]; /* client's IP address in host order */
+ extern int cm_SubnetMask[CM_MAXINTERFACE_ADDR];/* client's subnet mask in host order*/
+ extern int cm_NetMtu[CM_MAXINTERFACE_ADDR]; /* client's MTU sizes */
+ extern int cm_NetFlags[CM_MAXINTERFACE_ADDR]; /* network flags */
+ extern int cm_LanAdapterChangeDetected;
#endif /* __CM_SERVER_H_ENV__ */
Index: openafs/src/WINNT/afsd/cm_vnodeops.c
diff -c openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.64 openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.72
*** openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.64 Sat Feb 23 16:37:08 2008
--- openafs/src/WINNT/afsd/cm_vnodeops.c Wed Mar 19 16:18:37 2008
***************
*** 262,268 ****
if (openMode == 1 || openMode == 2 || trunc)
rights |= PRSFS_WRITE;
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, reqp, rights,
CM_SCACHESYNC_GETSTATUS
--- 262,268 ----
if (openMode == 1 || openMode == 2 || trunc)
rights |= PRSFS_WRITE;
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, reqp, rights,
CM_SCACHESYNC_GETSTATUS
***************
*** 326,332 ****
_done:
! lock_ReleaseMutex(&scp->mx);
return code;
}
--- 326,332 ----
_done:
! lock_ReleaseWrite(&scp->rw);
return code;
}
***************
*** 348,354 ****
rights = 0;
! if (desiredAccess & AFS_ACCESS_READ)
rights |= (scp->fileType == CM_SCACHETYPE_DIRECTORY ? PRSFS_LOOKUP : PRSFS_READ);
/* We used to require PRSFS_WRITE if createDisp was 4
--- 348,354 ----
rights = 0;
! if (desiredAccess & (AFS_ACCESS_READ|AFS_ACCESS_EXECUTE))
rights |= (scp->fileType == CM_SCACHETYPE_DIRECTORY ? PRSFS_LOOKUP : PRSFS_READ);
/* We used to require PRSFS_WRITE if createDisp was 4
***************
*** 358,364 ****
if (desiredAccess & AFS_ACCESS_WRITE)
rights |= PRSFS_WRITE;
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, reqp, rights,
CM_SCACHESYNC_GETSTATUS
--- 358,364 ----
if (desiredAccess & AFS_ACCESS_WRITE)
rights |= PRSFS_WRITE;
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, reqp, rights,
CM_SCACHESYNC_GETSTATUS
***************
*** 440,446 ****
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
_done:
! lock_ReleaseMutex(&scp->mx);
osi_Log3(afsd_logp,"cm_CheckNTOpen scp 0x%p ldp 0x%p code 0x%x", scp, *ldpp, code);
return code;
--- 440,446 ----
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
_done:
! lock_ReleaseWrite(&scp->rw);
osi_Log3(afsd_logp,"cm_CheckNTOpen scp 0x%p ldp 0x%p code 0x%x", scp, *ldpp, code);
return code;
***************
*** 451,460 ****
{
osi_Log2(afsd_logp,"cm_CheckNTOpenDone scp 0x%p ldp 0x%p", scp, *ldpp);
if (*ldpp) {
! lock_ObtainMutex(&scp->mx);
cm_Unlock(scp, (*ldpp)->sLockType, (*ldpp)->LOffset, (*ldpp)->LLength,
(*ldpp)->key, userp, reqp);
! lock_ReleaseMutex(&scp->mx);
free(*ldpp);
*ldpp = NULL;
}
--- 451,460 ----
{
osi_Log2(afsd_logp,"cm_CheckNTOpenDone scp 0x%p ldp 0x%p", scp, *ldpp);
if (*ldpp) {
! lock_ObtainWrite(&scp->rw);
cm_Unlock(scp, (*ldpp)->sLockType, (*ldpp)->LOffset, (*ldpp)->LLength,
(*ldpp)->key, userp, reqp);
! lock_ReleaseWrite(&scp->rw);
free(*ldpp);
*ldpp = NULL;
}
***************
*** 483,495 ****
unsigned short *hashTable;
unsigned int i, idx;
int BeyondPage = 0, HaveDot = 0, HaveDotDot = 0;
/* First check permissions */
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, reqp, PRSFS_DELETE,
CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK);
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
! lock_ReleaseMutex(&scp->mx);
if (code)
return code;
--- 483,496 ----
unsigned short *hashTable;
unsigned int i, idx;
int BeyondPage = 0, HaveDot = 0, HaveDotDot = 0;
+ int releaseLock = 0;
/* First check permissions */
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, reqp, PRSFS_DELETE,
CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK);
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
! lock_ReleaseWrite(&scp->rw);
if (code)
return code;
***************
*** 504,517 ****
return code;
lock_ObtainMutex(&bufferp->mx);
! lock_ObtainMutex(&scp->mx);
while (1) {
code = cm_SyncOp(scp, bufferp, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK
| CM_SCACHESYNC_READ
| CM_SCACHESYNC_BUFLOCKED);
if (code)
! break;
if (cm_HaveBuffer(scp, bufferp, 1))
break;
--- 505,519 ----
return code;
lock_ObtainMutex(&bufferp->mx);
! lock_ObtainWrite(&scp->rw);
! releaseLock = 1;
while (1) {
code = cm_SyncOp(scp, bufferp, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK
| CM_SCACHESYNC_READ
| CM_SCACHESYNC_BUFLOCKED);
if (code)
! goto done;
if (cm_HaveBuffer(scp, bufferp, 1))
break;
***************
*** 519,532 ****
/* otherwise, load the buffer and try again */
lock_ReleaseMutex(&bufferp->mx);
code = cm_GetBuffer(scp, bufferp, NULL, userp, reqp);
! lock_ReleaseMutex(&scp->mx);
lock_ObtainMutex(&bufferp->mx);
! lock_ObtainMutex(&scp->mx);
cm_SyncOpDone(scp, bufferp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ | CM_SCACHESYNC_BUFLOCKED);
if (code)
! break;
}
/* We try to determine emptiness without looking beyond the first page,
* and without assuming "." and ".." are present and are on the first
* page (though these assumptions might, after all, be reasonable).
--- 521,537 ----
/* otherwise, load the buffer and try again */
lock_ReleaseMutex(&bufferp->mx);
code = cm_GetBuffer(scp, bufferp, NULL, userp, reqp);
! lock_ReleaseWrite(&scp->rw);
lock_ObtainMutex(&bufferp->mx);
! lock_ObtainWrite(&scp->rw);
cm_SyncOpDone(scp, bufferp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ | CM_SCACHESYNC_BUFLOCKED);
if (code)
! goto done;
}
+ lock_ReleaseWrite(&scp->rw);
+ releaseLock = 0;
+
/* We try to determine emptiness without looking beyond the first page,
* and without assuming "." and ".." are present and are on the first
* page (though these assumptions might, after all, be reasonable).
***************
*** 558,564 ****
done:
lock_ReleaseMutex(&bufferp->mx);
buf_Release(bufferp);
! lock_ReleaseMutex(&scp->mx);
return code;
}
--- 563,570 ----
done:
lock_ReleaseMutex(&bufferp->mx);
buf_Release(bufferp);
! if (releaseLock)
! lock_ReleaseWrite(&scp->rw);
return code;
}
***************
*** 591,600 ****
int numDirChunks; /* # of 32 byte dir chunks in this entry */
/* get the directory size */
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, reqp, PRSFS_LOOKUP,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
! lock_ReleaseMutex(&scp->mx);
if (code)
return code;
--- 597,606 ----
int numDirChunks; /* # of 32 byte dir chunks in this entry */
/* get the directory size */
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, reqp, PRSFS_LOOKUP,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
! lock_ReleaseWrite(&scp->rw);
if (code)
return code;
***************
*** 740,781 ****
break;
}
- #ifdef AFSIFS
- /* for the IFS version, we bulkstat the dirents because this
- routine is used in place of smb_ReceiveCoreSearchDir. our
- other option is to modify smb_ReceiveCoreSearchDir itself,
- but this seems to be the proper use for cm_ApplyDir. */
- lock_ObtainMutex(&scp->mx);
- if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0
- && (scp->bulkStatProgress.QuadPart <= thyper.QuadPart))
- {
- scp->flags |= CM_SCACHEFLAG_BULKSTATTING;
- code = cm_TryBulkStat(scp, &thyper, userp, reqp);
- scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING;
- scp->bulkStatProgress = thyper;
- }
- lock_ReleaseMutex(&scp->mx);
- #endif
-
lock_ObtainMutex(&bufferp->mx);
bufferOffset = thyper;
/* now get the data in the cache */
while (1) {
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, bufferp, userp, reqp,
PRSFS_LOOKUP,
CM_SCACHESYNC_NEEDCALLBACK
| CM_SCACHESYNC_READ
| CM_SCACHESYNC_BUFLOCKED);
if (code) {
! lock_ReleaseMutex(&scp->mx);
break;
}
cm_SyncOpDone(scp, bufferp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ | CM_SCACHESYNC_BUFLOCKED);
if (cm_HaveBuffer(scp, bufferp, 1)) {
! lock_ReleaseMutex(&scp->mx);
break;
}
--- 746,770 ----
break;
}
lock_ObtainMutex(&bufferp->mx);
bufferOffset = thyper;
/* now get the data in the cache */
while (1) {
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, bufferp, userp, reqp,
PRSFS_LOOKUP,
CM_SCACHESYNC_NEEDCALLBACK
| CM_SCACHESYNC_READ
| CM_SCACHESYNC_BUFLOCKED);
if (code) {
! lock_ReleaseWrite(&scp->rw);
break;
}
cm_SyncOpDone(scp, bufferp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ | CM_SCACHESYNC_BUFLOCKED);
if (cm_HaveBuffer(scp, bufferp, 1)) {
! lock_ReleaseWrite(&scp->rw);
break;
}
***************
*** 783,789 ****
lock_ReleaseMutex(&bufferp->mx);
code = cm_GetBuffer(scp, bufferp, NULL, userp,
reqp);
! lock_ReleaseMutex(&scp->mx);
lock_ObtainMutex(&bufferp->mx);
if (code)
break;
--- 772,778 ----
lock_ReleaseMutex(&bufferp->mx);
code = cm_GetBuffer(scp, bufferp, NULL, userp,
reqp);
! lock_ReleaseWrite(&scp->rw);
lock_ObtainMutex(&bufferp->mx);
if (code)
break;
***************
*** 961,967 ****
}
/* read the contents of a mount point into the appropriate string.
! * called with locked scp, and returns with locked scp.
*/
long cm_ReadMountPoint(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
{
--- 950,956 ----
}
/* read the contents of a mount point into the appropriate string.
! * called with write locked scp, and returns with locked scp.
*/
long cm_ReadMountPoint(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
{
***************
*** 974,985 ****
return 0;
/* otherwise, we have to read it in */
! lock_ReleaseMutex(&scp->mx);
thyper.LowPart = thyper.HighPart = 0;
code = buf_Get(scp, &thyper, &bufp);
! lock_ObtainMutex(&scp->mx);
if (code)
return code;
--- 963,974 ----
return 0;
/* otherwise, we have to read it in */
! lock_ReleaseWrite(&scp->rw);
thyper.LowPart = thyper.HighPart = 0;
code = buf_Get(scp, &thyper, &bufp);
! lock_ObtainWrite(&scp->rw);
if (code)
return code;
***************
*** 1033,1039 ****
/* called with a locked scp and chases the mount point, yielding outScpp.
! * scp remains locked, just for simplicity of describing the interface.
*/
long cm_FollowMountPoint(cm_scache_t *scp, cm_scache_t *dscp, cm_user_t *userp,
cm_req_t *reqp, cm_scache_t **outScpp)
--- 1022,1028 ----
/* called with a locked scp and chases the mount point, yielding outScpp.
! * scp remains write locked, just for simplicity of describing the interface.
*/
long cm_FollowMountPoint(cm_scache_t *scp, cm_scache_t *dscp, cm_user_t *userp,
cm_req_t *reqp, cm_scache_t **outScpp)
***************
*** 1053,1061 ****
if (scp->mountRootFid.cell != 0 && scp->mountRootGen >= cm_data.mountRootGen) {
tfid = scp->mountRootFid;
! lock_ReleaseMutex(&scp->mx);
code = cm_GetSCache(&tfid, outScpp, userp, reqp);
! lock_ObtainMutex(&scp->mx);
return code;
}
--- 1042,1050 ----
if (scp->mountRootFid.cell != 0 && scp->mountRootGen >= cm_data.mountRootGen) {
tfid = scp->mountRootFid;
! lock_ReleaseWrite(&scp->rw);
code = cm_GetSCache(&tfid, outScpp, userp, reqp);
! lock_ObtainWrite(&scp->rw);
return code;
}
***************
*** 1075,1083 ****
strncpy(cellNamep, mpNamep+1, cp - mpNamep - 1);
strcpy(volNamep, cp+1);
/* now look up the cell */
! lock_ReleaseMutex(&scp->mx);
cellp = cm_GetCell(cellNamep, CM_FLAG_CREATE);
! lock_ObtainMutex(&scp->mx);
}
else {
/* normal mt pt */
--- 1064,1072 ----
strncpy(cellNamep, mpNamep+1, cp - mpNamep - 1);
strcpy(volNamep, cp+1);
/* now look up the cell */
! lock_ReleaseWrite(&scp->rw);
cellp = cm_GetCell(cellNamep, CM_FLAG_CREATE);
! lock_ObtainWrite(&scp->rw);
}
else {
/* normal mt pt */
***************
*** 1109,1137 ****
}
/* now we need to get the volume */
! lock_ReleaseMutex(&scp->mx);
if (cm_VolNameIsID(volNamep)) {
! code = cm_GetVolumeByID(cellp, atoi(volNamep), userp, reqp,
CM_GETVOL_FLAG_CREATE, &volp);
} else {
! code = cm_GetVolumeByName(cellp, volNamep, userp, reqp,
CM_GETVOL_FLAG_CREATE, &volp);
}
! lock_ObtainMutex(&scp->mx);
if (code == 0) {
afs_uint32 cell, volume;
- /* save the parent of the volume root for this is the
- * place where the volume is mounted and we must remember
- * this in the volume structure rather than just in the
- * scache entry lest the scache entry gets recycled
- * (defect 11489)
- */
- lock_ObtainMutex(&volp->mx);
- volp->dotdotFid = dscp->fid;
- lock_ReleaseMutex(&volp->mx);
-
cell = cellp->cellID;
/* if the mt pt originates in a .backup volume (not a .readonly)
--- 1098,1116 ----
}
/* now we need to get the volume */
! lock_ReleaseWrite(&scp->rw);
if (cm_VolNameIsID(volNamep)) {
! code = cm_FindVolumeByID(cellp, atoi(volNamep), userp, reqp,
CM_GETVOL_FLAG_CREATE, &volp);
} else {
! code = cm_FindVolumeByName(cellp, volNamep, userp, reqp,
CM_GETVOL_FLAG_CREATE, &volp);
}
! lock_ObtainWrite(&scp->rw);
if (code == 0) {
afs_uint32 cell, volume;
cell = cellp->cellID;
/* if the mt pt originates in a .backup volume (not a .readonly)
***************
*** 1156,1176 ****
volp->ro.ID != 0) {
targetType = ROVOL;
}
! if (targetType == ROVOL)
volume = volp->ro.ID;
! else if (targetType == BACKVOL)
volume = volp->bk.ID;
! else
volume = volp->rw.ID;
/* the rest of the fid is a magic number */
cm_SetFid(&scp->mountRootFid, cell, volume, 1, 1);
scp->mountRootGen = cm_data.mountRootGen;
tfid = scp->mountRootFid;
! lock_ReleaseMutex(&scp->mx);
code = cm_GetSCache(&tfid, outScpp, userp, reqp);
! lock_ObtainMutex(&scp->mx);
}
done:
--- 1135,1165 ----
volp->ro.ID != 0) {
targetType = ROVOL;
}
! if (targetType == ROVOL) {
volume = volp->ro.ID;
! lock_ObtainMutex(&volp->mx);
! volp->ro.dotdotFid = dscp->fid;
! lock_ReleaseMutex(&volp->mx);
! } else if (targetType == BACKVOL) {
volume = volp->bk.ID;
! lock_ObtainMutex(&volp->mx);
! volp->bk.dotdotFid = dscp->fid;
! lock_ReleaseMutex(&volp->mx);
! } else {
volume = volp->rw.ID;
+ lock_ObtainMutex(&volp->mx);
+ volp->rw.dotdotFid = dscp->fid;
+ lock_ReleaseMutex(&volp->mx);
+ }
/* the rest of the fid is a magic number */
cm_SetFid(&scp->mountRootFid, cell, volume, 1, 1);
scp->mountRootGen = cm_data.mountRootGen;
tfid = scp->mountRootFid;
! lock_ReleaseWrite(&scp->rw);
code = cm_GetSCache(&tfid, outScpp, userp, reqp);
! lock_ObtainWrite(&scp->rw);
}
done:
***************
*** 1341,1351 ****
}
/* tscp is now held */
! lock_ObtainMutex(&tscp->mx);
code = cm_SyncOp(tscp, NULL, userp, reqp, 0,
CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
! lock_ReleaseMutex(&tscp->mx);
cm_ReleaseSCache(tscp);
return code;
}
--- 1330,1340 ----
}
/* tscp is now held */
! lock_ObtainWrite(&tscp->rw);
code = cm_SyncOp(tscp, NULL, userp, reqp, 0,
CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
! lock_ReleaseWrite(&tscp->rw);
cm_ReleaseSCache(tscp);
return code;
}
***************
*** 1361,1367 ****
if (code == 0)
code = cm_FollowMountPoint(tscp, dscp, userp, reqp,
&mountedScp);
! lock_ReleaseMutex(&tscp->mx);
cm_ReleaseSCache(tscp);
if (code) {
return code;
--- 1350,1356 ----
if (code == 0)
code = cm_FollowMountPoint(tscp, dscp, userp, reqp,
&mountedScp);
! lock_ReleaseWrite(&tscp->rw);
cm_ReleaseSCache(tscp);
if (code) {
return code;
***************
*** 1369,1375 ****
tscp = mountedScp;
}
else {
! lock_ReleaseMutex(&tscp->mx);
}
/* copy back pointer */
--- 1358,1364 ----
tscp = mountedScp;
}
else {
! lock_ReleaseWrite(&tscp->rw);
}
/* copy back pointer */
***************
*** 1378,1387 ****
/* insert scache in dnlc */
if ( !dnlcHit && !(flags & CM_FLAG_NOMOUNTCHASE) && rock.ExactFound ) {
/* lock the directory entry to prevent racing callback revokes */
! lock_ObtainMutex(&dscp->mx);
if ( dscp->cbServerp != NULL && dscp->cbExpires > 0 )
cm_dnlcEnter(dscp, namep, tscp);
! lock_ReleaseMutex(&dscp->mx);
}
/* and return */
--- 1367,1376 ----
/* insert scache in dnlc */
if ( !dnlcHit && !(flags & CM_FLAG_NOMOUNTCHASE) && rock.ExactFound ) {
/* lock the directory entry to prevent racing callback revokes */
! lock_ObtainRead(&dscp->rw);
if ( dscp->cbServerp != NULL && dscp->cbExpires > 0 )
cm_dnlcEnter(dscp, namep, tscp);
! lock_ReleaseRead(&dscp->rw);
}
/* and return */
***************
*** 1404,1410 ****
if (outp == NULL)
return 1;
! if (index >= MAXNUMSYSNAMES)
return -1;
/* otherwise generate the properly expanded @sys name */
--- 1393,1399 ----
if (outp == NULL)
return 1;
! if (index >= cm_sysNameCount)
return -1;
/* otherwise generate the properly expanded @sys name */
***************
*** 1486,1495 ****
volType = RWVOL;
if (cm_VolNameIsID(volumeName)) {
! code = cm_GetVolumeByID(cellp, atoi(volumeName), userp, reqp,
CM_GETVOL_FLAG_CREATE, &volp);
} else {
! code = cm_GetVolumeByName(cellp, volumeName, userp, reqp,
CM_GETVOL_FLAG_CREATE, &volp);
}
--- 1475,1484 ----
volType = RWVOL;
if (cm_VolNameIsID(volumeName)) {
! code = cm_FindVolumeByID(cellp, atoi(volumeName), userp, reqp,
CM_GETVOL_FLAG_CREATE, &volp);
} else {
! code = cm_FindVolumeByName(cellp, volumeName, userp, reqp,
CM_GETVOL_FLAG_CREATE, &volp);
}
***************
*** 1619,1628 ****
/* make sure we don't screw up the dir status during the merge */
code = cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_NONE, &dirop);
! lock_ObtainMutex(&dscp->mx);
sflags = CM_SCACHESYNC_STOREDATA;
code = cm_SyncOp(dscp, NULL, userp, reqp, 0, sflags);
! lock_ReleaseMutex(&dscp->mx);
if (code) {
cm_EndDirOp(&dirop);
return code;
--- 1608,1617 ----
/* make sure we don't screw up the dir status during the merge */
code = cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_NONE, &dirop);
! lock_ObtainWrite(&dscp->rw);
sflags = CM_SCACHESYNC_STOREDATA;
code = cm_SyncOp(dscp, NULL, userp, reqp, 0, sflags);
! lock_ReleaseWrite(&dscp->rw);
if (code) {
cm_EndDirOp(&dirop);
return code;
***************
*** 1656,1662 ****
lock_ObtainWrite(&dirop.scp->dirlock);
dirop.lockType = CM_DIRLOCK_WRITE;
}
! lock_ObtainMutex(&dscp->mx);
cm_dnlcRemove(dscp, namep);
cm_SyncOpDone(dscp, NULL, sflags);
if (code == 0) {
--- 1645,1651 ----
lock_ObtainWrite(&dirop.scp->dirlock);
dirop.lockType = CM_DIRLOCK_WRITE;
}
! lock_ObtainWrite(&dscp->rw);
cm_dnlcRemove(dscp, namep);
cm_SyncOpDone(dscp, NULL, sflags);
if (code == 0) {
***************
*** 1668,1674 ****
*/
dscp->cbServerp = NULL;
}
! lock_ReleaseMutex(&dscp->mx);
if (code == 0 && cm_CheckDirOpForSingleChange(&dirop)) {
cm_DirDeleteEntry(&dirop, namep);
--- 1657,1663 ----
*/
dscp->cbServerp = NULL;
}
! lock_ReleaseWrite(&dscp->rw);
if (code == 0 && cm_CheckDirOpForSingleChange(&dirop)) {
cm_DirDeleteEntry(&dirop, namep);
***************
*** 1681,1688 ****
return code;
}
! /* called with a locked vnode, and fills in the link info.
! * returns this the vnode still locked.
*/
long cm_HandleLink(cm_scache_t *linkScp, cm_user_t *userp, cm_req_t *reqp)
{
--- 1670,1677 ----
return code;
}
! /* called with a write locked vnode, and fills in the link info.
! * returns this the vnode still write locked.
*/
long cm_HandleLink(cm_scache_t *linkScp, cm_user_t *userp, cm_req_t *reqp)
{
***************
*** 1691,1703 ****
long temp;
osi_hyper_t thyper;
! lock_AssertMutex(&linkScp->mx);
if (!linkScp->mountPointStringp[0]) {
/* read the link data */
! lock_ReleaseMutex(&linkScp->mx);
thyper.LowPart = thyper.HighPart = 0;
code = buf_Get(linkScp, &thyper, &bufp);
! lock_ObtainMutex(&linkScp->mx);
if (code)
return code;
while (1) {
--- 1680,1692 ----
long temp;
osi_hyper_t thyper;
! lock_AssertWrite(&linkScp->rw);
if (!linkScp->mountPointStringp[0]) {
/* read the link data */
! lock_ReleaseWrite(&linkScp->rw);
thyper.LowPart = thyper.HighPart = 0;
code = buf_Get(linkScp, &thyper, &bufp);
! lock_ObtainWrite(&linkScp->rw);
if (code)
return code;
while (1) {
***************
*** 1761,1767 ****
*newRootScpp = NULL;
*newSpaceBufferp = NULL;
! lock_ObtainMutex(&linkScp->mx);
code = cm_HandleLink(linkScp, userp, reqp);
if (code)
goto done;
--- 1750,1756 ----
*newRootScpp = NULL;
*newSpaceBufferp = NULL;
! lock_ObtainWrite(&linkScp->rw);
code = cm_HandleLink(linkScp, userp, reqp);
if (code)
goto done;
***************
*** 1771,1778 ****
* being a little conservative here.
*/
if (strlen(linkScp->mountPointStringp) + strlen(pathSuffixp) + 2
! >= CM_UTILS_SPACESIZE)
! return CM_ERROR_TOOBIG;
tsp = cm_GetSpace();
linkp = linkScp->mountPointStringp;
--- 1760,1769 ----
* being a little conservative here.
*/
if (strlen(linkScp->mountPointStringp) + strlen(pathSuffixp) + 2
! >= CM_UTILS_SPACESIZE) {
! code = CM_ERROR_TOOBIG;
! goto done;
! }
tsp = cm_GetSpace();
linkp = linkScp->mountPointStringp;
***************
*** 1841,1847 ****
}
done:
! lock_ReleaseMutex(&linkScp->mx);
return code;
}
#ifdef DEBUG_REFCOUNT
--- 1832,1838 ----
}
done:
! lock_ReleaseWrite(&linkScp->rw);
return code;
}
#ifdef DEBUG_REFCOUNT
***************
*** 2003,2014 ****
/* now, if tscp is a symlink, we should follow
* it and assemble the path again.
*/
! lock_ObtainMutex(&tscp->mx);
code = cm_SyncOp(tscp, NULL, userp, reqp, 0,
CM_SCACHESYNC_GETSTATUS
| CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
! lock_ReleaseMutex(&tscp->mx);
cm_ReleaseSCache(tscp);
tscp = NULL;
if (dirScp) {
--- 1994,2005 ----
/* now, if tscp is a symlink, we should follow
* it and assemble the path again.
*/
! lock_ObtainWrite(&tscp->rw);
code = cm_SyncOp(tscp, NULL, userp, reqp, 0,
CM_SCACHESYNC_GETSTATUS
| CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
! lock_ReleaseWrite(&tscp->rw);
cm_ReleaseSCache(tscp);
tscp = NULL;
if (dirScp) {
***************
*** 2021,2027 ****
if (tscp->fileType == CM_SCACHETYPE_SYMLINK) {
/* this is a symlink; assemble a new buffer */
! lock_ReleaseMutex(&tscp->mx);
if (symlinkCount++ >= MAX_SYMLINK_COUNT) {
cm_ReleaseSCache(tscp);
tscp = NULL;
--- 2012,2018 ----
if (tscp->fileType == CM_SCACHETYPE_SYMLINK) {
/* this is a symlink; assemble a new buffer */
! lock_ReleaseWrite(&tscp->rw);
if (symlinkCount++ >= MAX_SYMLINK_COUNT) {
cm_ReleaseSCache(tscp);
tscp = NULL;
***************
*** 2100,2106 ****
}
} else {
/* not a symlink, we may be done */
! lock_ReleaseMutex(&tscp->mx);
if (tc == 0) {
if (phase == 1) {
phase = 2;
--- 2091,2097 ----
}
} else {
/* not a symlink, we may be done */
! lock_ReleaseWrite(&tscp->rw);
if (tc == 0) {
if (phase == 1) {
phase = 2;
***************
*** 2258,2275 ****
cm_SetFid(&tfid, scp->fid.cell, scp->fid.volume, ntohl(dep->fid.vnode), ntohl(dep->fid.unique));
tscp = cm_FindSCache(&tfid);
if (tscp) {
! if (lock_TryMutex(&tscp->mx)) {
/* we have an entry that we can look at */
if (!(tscp->flags & CM_SCACHEFLAG_EACCESS) && cm_HaveCallback(tscp)) {
/* we have a callback on it. Don't bother
* fetching this stat entry, since we're happy
* with the info we have.
*/
! lock_ReleaseMutex(&tscp->mx);
cm_ReleaseSCache(tscp);
return 0;
}
! lock_ReleaseMutex(&tscp->mx);
} /* got lock */
cm_ReleaseSCache(tscp);
} /* found entry */
--- 2249,2266 ----
cm_SetFid(&tfid, scp->fid.cell, scp->fid.volume, ntohl(dep->fid.vnode), ntohl(dep->fid.unique));
tscp = cm_FindSCache(&tfid);
if (tscp) {
! if (lock_TryWrite(&tscp->rw)) {
/* we have an entry that we can look at */
if (!(tscp->flags & CM_SCACHEFLAG_EACCESS) && cm_HaveCallback(tscp)) {
/* we have a callback on it. Don't bother
* fetching this stat entry, since we're happy
* with the info we have.
*/
! lock_ReleaseWrite(&tscp->rw);
cm_ReleaseSCache(tscp);
return 0;
}
! lock_ReleaseWrite(&tscp->rw);
} /* got lock */
cm_ReleaseSCache(tscp);
} /* found entry */
***************
*** 2295,2301 ****
return 0;
}
! /* called with a locked scp and a pointer to a buffer. Make bulk stat
* calls on all undeleted files in the page of the directory specified.
*/
afs_int32
--- 2286,2292 ----
return 0;
}
! /* called with a write locked scp and a pointer to a buffer. Make bulk stat
* calls on all undeleted files in the page of the directory specified.
*/
afs_int32
***************
*** 2328,2340 ****
memset(&bb, 0, sizeof(bb));
bb.bufOffset = *offsetp;
! lock_ReleaseMutex(&dscp->mx);
/* first, assemble the file IDs we need to stat */
code = cm_ApplyDir(dscp, cm_TryBulkProc, (void *) &bb, offsetp, userp, reqp, NULL);
/* if we failed, bail out early */
if (code && code != CM_ERROR_STOPNOW) {
! lock_ObtainMutex(&dscp->mx);
return code;
}
--- 2319,2331 ----
memset(&bb, 0, sizeof(bb));
bb.bufOffset = *offsetp;
! lock_ReleaseWrite(&dscp->rw);
/* first, assemble the file IDs we need to stat */
code = cm_ApplyDir(dscp, cm_TryBulkProc, (void *) &bb, offsetp, userp, reqp, NULL);
/* if we failed, bail out early */
if (code && code != CM_ERROR_STOPNOW) {
! lock_ObtainWrite(&dscp->rw);
return code;
}
***************
*** 2405,2411 ****
/* otherwise, if this entry has no callback info,
* merge in this.
*/
! lock_ObtainMutex(&scp->mx);
/* now, we have to be extra paranoid on merging in this
* information, since we didn't use cm_SyncOp before
* starting the fetch to make sure that no bad races
--- 2396,2402 ----
/* otherwise, if this entry has no callback info,
* merge in this.
*/
! lock_ObtainWrite(&scp->rw);
/* now, we have to be extra paranoid on merging in this
* information, since we didn't use cm_SyncOp before
* starting the fetch to make sure that no bad races
***************
*** 2426,2432 ****
CM_CALLBACK_MAINTAINCOUNT);
cm_MergeStatus(dscp, scp, &bb.stats[j], &volSync, userp, 0);
}
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
} /* all files in the response */
/* now tell it to drop the count,
--- 2417,2423 ----
CM_CALLBACK_MAINTAINCOUNT);
cm_MergeStatus(dscp, scp, &bb.stats[j], &volSync, userp, 0);
}
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
} /* all files in the response */
/* now tell it to drop the count,
***************
*** 2435,2441 ****
filex += filesThisCall;
} /* while there are still more files to process */
! lock_ObtainMutex(&dscp->mx);
/* If we did the InlineBulk RPC pull out the return code and log it */
if (inlinebulk) {
--- 2426,2432 ----
filex += filesThisCall;
} /* while there are still more files to process */
! lock_ObtainWrite(&dscp->rw);
/* If we did the InlineBulk RPC pull out the return code and log it */
if (inlinebulk) {
***************
*** 2502,2508 ****
lock_ObtainWrite(&scp->bufCreateLock);
/* verify that this is a file, not a dir or a symlink */
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code)
--- 2493,2499 ----
lock_ObtainWrite(&scp->bufCreateLock);
/* verify that this is a file, not a dir or a symlink */
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code)
***************
*** 2520,2528 ****
else
shrinking = 0;
! lock_ReleaseMutex(&scp->mx);
! /* can't hold scp->mx lock here, since we may wait for a storeback to
* finish if the buffer package is cleaning a buffer by storing it to
* the server.
*/
--- 2511,2519 ----
else
shrinking = 0;
! lock_ReleaseWrite(&scp->rw);
! /* can't hold scp->rw lock here, since we may wait for a storeback to
* finish if the buffer package is cleaning a buffer by storing it to
* the server.
*/
***************
*** 2530,2536 ****
buf_Truncate(scp, userp, reqp, sizep);
/* now ensure that file length is short enough, and update truncPos */
! lock_ObtainMutex(&scp->mx);
/* make sure we have a callback (so we have the right value for the
* length), and wait for it to be safe to do a truncate.
--- 2521,2527 ----
buf_Truncate(scp, userp, reqp, sizep);
/* now ensure that file length is short enough, and update truncPos */
! lock_ObtainWrite(&scp->rw);
/* make sure we have a callback (so we have the right value for the
* length), and wait for it to be safe to do a truncate.
***************
*** 2581,2587 ****
| CM_SCACHESYNC_SETSTATUS | CM_SCACHESYNC_SETSIZE);
done:
! lock_ReleaseMutex(&scp->mx);
lock_ReleaseWrite(&scp->bufCreateLock);
return code;
--- 2572,2578 ----
| CM_SCACHESYNC_SETSTATUS | CM_SCACHESYNC_SETSIZE);
done:
! lock_ReleaseWrite(&scp->rw);
lock_ReleaseWrite(&scp->bufCreateLock);
return code;
***************
*** 2603,2615 ****
if (attrp->mask & CM_ATTRMASK_LENGTH)
return cm_SetLength(scp, &attrp->length, userp, reqp);
! lock_ObtainMutex(&scp->mx);
/* otherwise, we have to make an RPC to get the status */
code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_STORESTATUS);
if (code) {
! lock_ReleaseMutex(&scp->mx);
return code;
}
/* make the attr structure */
cm_StatusFromAttr(&afsInStatus, scp, attrp);
--- 2594,2607 ----
if (attrp->mask & CM_ATTRMASK_LENGTH)
return cm_SetLength(scp, &attrp->length, userp, reqp);
! lock_ObtainWrite(&scp->rw);
/* otherwise, we have to make an RPC to get the status */
code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_STORESTATUS);
if (code) {
! lock_ReleaseWrite(&scp->rw);
return code;
}
+ lock_ConvertWToR(&scp->rw);
/* make the attr structure */
cm_StatusFromAttr(&afsInStatus, scp, attrp);
***************
*** 2617,2623 ****
tfid.Volume = scp->fid.volume;
tfid.Vnode = scp->fid.vnode;
tfid.Unique = scp->fid.unique;
! lock_ReleaseMutex(&scp->mx);
/* now make the RPC */
osi_Log1(afsd_logp, "CALL StoreStatus scp 0x%p", scp);
--- 2609,2615 ----
tfid.Volume = scp->fid.volume;
tfid.Vnode = scp->fid.vnode;
tfid.Unique = scp->fid.unique;
! lock_ReleaseRead(&scp->rw);
/* now make the RPC */
osi_Log1(afsd_logp, "CALL StoreStatus scp 0x%p", scp);
***************
*** 2640,2646 ****
else
osi_Log0(afsd_logp, "CALL StoreStatus SUCCESS");
! lock_ObtainMutex(&scp->mx);
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_STORESTATUS);
if (code == 0)
cm_MergeStatus(NULL, scp, &afsOutStatus, &volSync, userp,
--- 2632,2638 ----
else
osi_Log0(afsd_logp, "CALL StoreStatus SUCCESS");
! lock_ObtainWrite(&scp->rw);
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_STORESTATUS);
if (code == 0)
cm_MergeStatus(NULL, scp, &afsOutStatus, &volSync, userp,
***************
*** 2651,2657 ****
*/
if (afsInStatus.Mask & AFS_SETMODE)
cm_FreeAllACLEnts(scp);
! lock_ReleaseMutex(&scp->mx);
return code;
}
--- 2643,2649 ----
*/
if (afsInStatus.Mask & AFS_SETMODE)
cm_FreeAllACLEnts(scp);
! lock_ReleaseWrite(&scp->rw);
return code;
}
***************
*** 2696,2704 ****
* completes.
*/
cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_NONE, &dirop);
! lock_ObtainMutex(&dscp->mx);
code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA);
! lock_ReleaseMutex(&dscp->mx);
if (code == 0) {
cm_StartCallbackGrantingCall(NULL, &cbReq);
} else {
--- 2688,2696 ----
* completes.
*/
cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_NONE, &dirop);
! lock_ObtainWrite(&dscp->rw);
code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA);
! lock_ReleaseWrite(&dscp->rw);
if (code == 0) {
cm_StartCallbackGrantingCall(NULL, &cbReq);
} else {
***************
*** 2742,2753 ****
lock_ObtainWrite(&dirop.scp->dirlock);
dirop.lockType = CM_DIRLOCK_WRITE;
}
! lock_ObtainMutex(&dscp->mx);
cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0) {
cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, CM_MERGEFLAG_DIROP);
}
! lock_ReleaseMutex(&dscp->mx);
/* now try to create the file's entry, too, but be careful to
* make sure that we don't merge in old info. Since we weren't locking
--- 2734,2745 ----
lock_ObtainWrite(&dirop.scp->dirlock);
dirop.lockType = CM_DIRLOCK_WRITE;
}
! lock_ObtainWrite(&dscp->rw);
cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0) {
cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, CM_MERGEFLAG_DIROP);
}
! lock_ReleaseWrite(&dscp->rw);
/* now try to create the file's entry, too, but be careful to
* make sure that we don't merge in old info. Since we weren't locking
***************
*** 2758,2764 ****
cm_SetFid(&newFid, dscp->fid.cell, dscp->fid.volume, newAFSFid.Vnode, newAFSFid.Unique);
code = cm_GetSCache(&newFid, &scp, userp, reqp);
if (code == 0) {
! lock_ObtainMutex(&scp->mx);
scp->creator = userp; /* remember who created it */
if (!cm_HaveCallback(scp)) {
cm_MergeStatus(dscp, scp, &newFileStatus, &volSync,
--- 2750,2756 ----
cm_SetFid(&newFid, dscp->fid.cell, dscp->fid.volume, newAFSFid.Vnode, newAFSFid.Unique);
code = cm_GetSCache(&newFid, &scp, userp, reqp);
if (code == 0) {
! lock_ObtainWrite(&scp->rw);
scp->creator = userp; /* remember who created it */
if (!cm_HaveCallback(scp)) {
cm_MergeStatus(dscp, scp, &newFileStatus, &volSync,
***************
*** 2767,2773 ****
&newFileCallback, 0);
didEnd = 1;
}
! lock_ReleaseMutex(&scp->mx);
*scpp = scp;
}
}
--- 2759,2765 ----
&newFileCallback, 0);
didEnd = 1;
}
! lock_ReleaseWrite(&scp->rw);
*scpp = scp;
}
}
***************
*** 2793,2799 ****
code = buf_CleanVnode(scp, userp, reqp);
if (code == 0) {
! lock_ObtainMutex(&scp->mx);
if (scp->mask & (CM_SCACHEMASK_TRUNCPOS
| CM_SCACHEMASK_CLIENTMODTIME
--- 2785,2791 ----
code = buf_CleanVnode(scp, userp, reqp);
if (code == 0) {
! lock_ObtainWrite(&scp->rw);
if (scp->mask & (CM_SCACHEMASK_TRUNCPOS
| CM_SCACHEMASK_CLIENTMODTIME
***************
*** 2805,2811 ****
scp->flags &= ~(CM_SCACHEFLAG_OVERQUOTA | CM_SCACHEFLAG_OUTOFSPACE);
}
! lock_ReleaseMutex(&scp->mx);
}
return code;
}
--- 2797,2803 ----
scp->flags &= ~(CM_SCACHEFLAG_OVERQUOTA | CM_SCACHEFLAG_OUTOFSPACE);
}
! lock_ReleaseWrite(&scp->rw);
}
return code;
}
***************
*** 2851,2859 ****
* our call completes.
*/
cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_NONE, &dirop);
! lock_ObtainMutex(&dscp->mx);
code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA);
! lock_ReleaseMutex(&dscp->mx);
if (code == 0) {
cm_StartCallbackGrantingCall(NULL, &cbReq);
} else {
--- 2843,2851 ----
* our call completes.
*/
cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_NONE, &dirop);
! lock_ObtainWrite(&dscp->rw);
code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA);
! lock_ReleaseWrite(&dscp->rw);
if (code == 0) {
cm_StartCallbackGrantingCall(NULL, &cbReq);
} else {
***************
*** 2897,2908 ****
lock_ObtainWrite(&dirop.scp->dirlock);
dirop.lockType = CM_DIRLOCK_WRITE;
}
! lock_ObtainMutex(&dscp->mx);
cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0) {
cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, CM_MERGEFLAG_DIROP);
}
! lock_ReleaseMutex(&dscp->mx);
/* now try to create the new dir's entry, too, but be careful to
* make sure that we don't merge in old info. Since we weren't locking
--- 2889,2900 ----
lock_ObtainWrite(&dirop.scp->dirlock);
dirop.lockType = CM_DIRLOCK_WRITE;
}
! lock_ObtainWrite(&dscp->rw);
cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0) {
cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, CM_MERGEFLAG_DIROP);
}
! lock_ReleaseWrite(&dscp->rw);
/* now try to create the new dir's entry, too, but be careful to
* make sure that we don't merge in old info. Since we weren't locking
***************
*** 2913,2919 ****
cm_SetFid(&newFid, dscp->fid.cell, dscp->fid.volume, newAFSFid.Vnode, newAFSFid.Unique);
code = cm_GetSCache(&newFid, &scp, userp, reqp);
if (code == 0) {
! lock_ObtainMutex(&scp->mx);
if (!cm_HaveCallback(scp)) {
cm_MergeStatus(dscp, scp, &newDirStatus, &volSync,
userp, 0);
--- 2905,2911 ----
cm_SetFid(&newFid, dscp->fid.cell, dscp->fid.volume, newAFSFid.Vnode, newAFSFid.Unique);
code = cm_GetSCache(&newFid, &scp, userp, reqp);
if (code == 0) {
! lock_ObtainWrite(&scp->rw);
if (!cm_HaveCallback(scp)) {
cm_MergeStatus(dscp, scp, &newDirStatus, &volSync,
userp, 0);
***************
*** 2921,2927 ****
&newDirCallback, 0);
didEnd = 1;
}
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
}
}
--- 2913,2919 ----
&newDirCallback, 0);
didEnd = 1;
}
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
}
}
***************
*** 2961,2969 ****
}
cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_NONE, &dirop);
! lock_ObtainMutex(&dscp->mx);
code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA);
! lock_ReleaseMutex(&dscp->mx);
if (code != 0)
cm_EndDirOp(&dirop);
--- 2953,2961 ----
}
cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_NONE, &dirop);
! lock_ObtainWrite(&dscp->rw);
code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA);
! lock_ReleaseWrite(&dscp->rw);
if (code != 0)
cm_EndDirOp(&dirop);
***************
*** 3004,3015 ****
lock_ObtainWrite(&dirop.scp->dirlock);
dirop.lockType = CM_DIRLOCK_WRITE;
}
! lock_ObtainMutex(&dscp->mx);
cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0) {
cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, CM_MERGEFLAG_DIROP);
}
! lock_ReleaseMutex(&dscp->mx);
if (code == 0) {
if (cm_CheckDirOpForSingleChange(&dirop)) {
--- 2996,3007 ----
lock_ObtainWrite(&dirop.scp->dirlock);
dirop.lockType = CM_DIRLOCK_WRITE;
}
! lock_ObtainWrite(&dscp->rw);
cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0) {
cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, CM_MERGEFLAG_DIROP);
}
! lock_ReleaseWrite(&dscp->rw);
if (code == 0) {
if (cm_CheckDirOpForSingleChange(&dirop)) {
***************
*** 3045,3053 ****
* call completes.
*/
cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_NONE, &dirop);
! lock_ObtainMutex(&dscp->mx);
code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA);
! lock_ReleaseMutex(&dscp->mx);
if (code != 0)
cm_EndDirOp(&dirop);
if (code) {
--- 3037,3045 ----
* call completes.
*/
cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_NONE, &dirop);
! lock_ObtainWrite(&dscp->rw);
code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA);
! lock_ReleaseWrite(&dscp->rw);
if (code != 0)
cm_EndDirOp(&dirop);
if (code) {
***************
*** 3086,3097 ****
lock_ObtainWrite(&dirop.scp->dirlock);
dirop.lockType = CM_DIRLOCK_WRITE;
}
! lock_ObtainMutex(&dscp->mx);
cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0) {
cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, CM_MERGEFLAG_DIROP);
}
! lock_ReleaseMutex(&dscp->mx);
if (code == 0) {
if (cm_CheckDirOpForSingleChange(&dirop)) {
--- 3078,3089 ----
lock_ObtainWrite(&dirop.scp->dirlock);
dirop.lockType = CM_DIRLOCK_WRITE;
}
! lock_ObtainWrite(&dscp->rw);
cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0) {
cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, CM_MERGEFLAG_DIROP);
}
! lock_ReleaseWrite(&dscp->rw);
if (code == 0) {
if (cm_CheckDirOpForSingleChange(&dirop)) {
***************
*** 3114,3125 ****
cm_SetFid(&newFid, dscp->fid.cell, dscp->fid.volume, newAFSFid.Vnode, newAFSFid.Unique);
code = cm_GetSCache(&newFid, &scp, userp, reqp);
if (code == 0) {
! lock_ObtainMutex(&scp->mx);
if (!cm_HaveCallback(scp)) {
cm_MergeStatus(dscp, scp, &newLinkStatus, &volSync,
userp, 0);
}
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
}
}
--- 3106,3117 ----
cm_SetFid(&newFid, dscp->fid.cell, dscp->fid.volume, newAFSFid.Vnode, newAFSFid.Unique);
code = cm_GetSCache(&newFid, &scp, userp, reqp);
if (code == 0) {
! lock_ObtainWrite(&scp->rw);
if (!cm_HaveCallback(scp)) {
cm_MergeStatus(dscp, scp, &newLinkStatus, &volSync,
userp, 0);
}
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
}
}
***************
*** 3145,3153 ****
* call completes.
*/
cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_NONE, &dirop);
! lock_ObtainMutex(&dscp->mx);
code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA);
! lock_ReleaseMutex(&dscp->mx);
if (code) {
cm_EndDirOp(&dirop);
return code;
--- 3137,3145 ----
* call completes.
*/
cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_NONE, &dirop);
! lock_ObtainWrite(&dscp->rw);
code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA);
! lock_ReleaseWrite(&dscp->rw);
if (code) {
cm_EndDirOp(&dirop);
return code;
***************
*** 3183,3195 ****
lock_ObtainWrite(&dirop.scp->dirlock);
dirop.lockType = CM_DIRLOCK_WRITE;
}
! lock_ObtainMutex(&dscp->mx);
cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0) {
cm_dnlcRemove(dscp, namep);
cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, CM_MERGEFLAG_DIROP);
}
! lock_ReleaseMutex(&dscp->mx);
if (code == 0) {
if (cm_CheckDirOpForSingleChange(&dirop)) {
--- 3175,3187 ----
lock_ObtainWrite(&dirop.scp->dirlock);
dirop.lockType = CM_DIRLOCK_WRITE;
}
! lock_ObtainWrite(&dscp->rw);
cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0) {
cm_dnlcRemove(dscp, namep);
cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, CM_MERGEFLAG_DIROP);
}
! lock_ReleaseWrite(&dscp->rw);
if (code == 0) {
if (cm_CheckDirOpForSingleChange(&dirop)) {
***************
*** 3208,3214 ****
long cm_Open(cm_scache_t *scp, int type, cm_user_t *userp)
{
/* grab mutex on contents */
! lock_ObtainMutex(&scp->mx);
/* reset the prefetch info */
scp->prefetch.base.LowPart = 0; /* base */
--- 3200,3206 ----
long cm_Open(cm_scache_t *scp, int type, cm_user_t *userp)
{
/* grab mutex on contents */
! lock_ObtainWrite(&scp->rw);
/* reset the prefetch info */
scp->prefetch.base.LowPart = 0; /* base */
***************
*** 3217,3223 ****
scp->prefetch.end.HighPart = 0;
/* release mutex on contents */
! lock_ReleaseMutex(&scp->mx);
/* we're done */
return 0;
--- 3209,3215 ----
scp->prefetch.end.HighPart = 0;
/* release mutex on contents */
! lock_ReleaseWrite(&scp->rw);
/* we're done */
return 0;
***************
*** 3253,3264 ****
oneDir = 1;
cm_BeginDirOp(oldDscp, userp, reqp, CM_DIRLOCK_NONE, &oldDirOp);
! lock_ObtainMutex(&oldDscp->mx);
cm_dnlcRemove(oldDscp, oldNamep);
cm_dnlcRemove(oldDscp, newNamep);
code = cm_SyncOp(oldDscp, NULL, userp, reqp, 0,
CM_SCACHESYNC_STOREDATA);
! lock_ReleaseMutex(&oldDscp->mx);
if (code != 0) {
cm_EndDirOp(&oldDirOp);
}
--- 3245,3256 ----
oneDir = 1;
cm_BeginDirOp(oldDscp, userp, reqp, CM_DIRLOCK_NONE, &oldDirOp);
! lock_ObtainWrite(&oldDscp->rw);
cm_dnlcRemove(oldDscp, oldNamep);
cm_dnlcRemove(oldDscp, newNamep);
code = cm_SyncOp(oldDscp, NULL, userp, reqp, 0,
CM_SCACHESYNC_STOREDATA);
! lock_ReleaseWrite(&oldDscp->rw);
if (code != 0) {
cm_EndDirOp(&oldDirOp);
}
***************
*** 3279,3306 ****
if (oldDscp->fid.vnode < newDscp->fid.vnode) {
cm_BeginDirOp(oldDscp, userp, reqp, CM_DIRLOCK_NONE, &oldDirOp);
! lock_ObtainMutex(&oldDscp->mx);
cm_dnlcRemove(oldDscp, oldNamep);
code = cm_SyncOp(oldDscp, NULL, userp, reqp, 0,
CM_SCACHESYNC_STOREDATA);
! lock_ReleaseMutex(&oldDscp->mx);
if (code != 0)
cm_EndDirOp(&oldDirOp);
if (code == 0) {
cm_BeginDirOp(newDscp, userp, reqp, CM_DIRLOCK_NONE, &newDirOp);
! lock_ObtainMutex(&newDscp->mx);
cm_dnlcRemove(newDscp, newNamep);
code = cm_SyncOp(newDscp, NULL, userp, reqp, 0,
CM_SCACHESYNC_STOREDATA);
! lock_ReleaseMutex(&newDscp->mx);
if (code) {
cm_EndDirOp(&newDirOp);
/* cleanup first one */
! lock_ObtainMutex(&oldDscp->mx);
cm_SyncOpDone(oldDscp, NULL,
CM_SCACHESYNC_STOREDATA);
! lock_ReleaseMutex(&oldDscp->mx);
cm_EndDirOp(&oldDirOp);
}
}
--- 3271,3298 ----
if (oldDscp->fid.vnode < newDscp->fid.vnode) {
cm_BeginDirOp(oldDscp, userp, reqp, CM_DIRLOCK_NONE, &oldDirOp);
! lock_ObtainWrite(&oldDscp->rw);
cm_dnlcRemove(oldDscp, oldNamep);
code = cm_SyncOp(oldDscp, NULL, userp, reqp, 0,
CM_SCACHESYNC_STOREDATA);
! lock_ReleaseWrite(&oldDscp->rw);
if (code != 0)
cm_EndDirOp(&oldDirOp);
if (code == 0) {
cm_BeginDirOp(newDscp, userp, reqp, CM_DIRLOCK_NONE, &newDirOp);
! lock_ObtainWrite(&newDscp->rw);
cm_dnlcRemove(newDscp, newNamep);
code = cm_SyncOp(newDscp, NULL, userp, reqp, 0,
CM_SCACHESYNC_STOREDATA);
! lock_ReleaseWrite(&newDscp->rw);
if (code) {
cm_EndDirOp(&newDirOp);
/* cleanup first one */
! lock_ObtainWrite(&oldDscp->rw);
cm_SyncOpDone(oldDscp, NULL,
CM_SCACHESYNC_STOREDATA);
! lock_ReleaseWrite(&oldDscp->rw);
cm_EndDirOp(&oldDirOp);
}
}
***************
*** 3308,3335 ****
else {
/* lock the new vnode entry first */
cm_BeginDirOp(newDscp, userp, reqp, CM_DIRLOCK_NONE, &newDirOp);
! lock_ObtainMutex(&newDscp->mx);
cm_dnlcRemove(newDscp, newNamep);
code = cm_SyncOp(newDscp, NULL, userp, reqp, 0,
CM_SCACHESYNC_STOREDATA);
! lock_ReleaseMutex(&newDscp->mx);
if (code != 0)
cm_EndDirOp(&newDirOp);
if (code == 0) {
cm_BeginDirOp(oldDscp, userp, reqp, CM_DIRLOCK_NONE, &oldDirOp);
! lock_ObtainMutex(&oldDscp->mx);
cm_dnlcRemove(oldDscp, oldNamep);
code = cm_SyncOp(oldDscp, NULL, userp, reqp, 0,
CM_SCACHESYNC_STOREDATA);
! lock_ReleaseMutex(&oldDscp->mx);
if (code != 0)
cm_EndDirOp(&oldDirOp);
if (code) {
/* cleanup first one */
! lock_ObtainMutex(&newDscp->mx);
cm_SyncOpDone(newDscp, NULL,
CM_SCACHESYNC_STOREDATA);
! lock_ReleaseMutex(&newDscp->mx);
cm_EndDirOp(&newDirOp);
}
}
--- 3300,3327 ----
else {
/* lock the new vnode entry first */
cm_BeginDirOp(newDscp, userp, reqp, CM_DIRLOCK_NONE, &newDirOp);
! lock_ObtainWrite(&newDscp->rw);
cm_dnlcRemove(newDscp, newNamep);
code = cm_SyncOp(newDscp, NULL, userp, reqp, 0,
CM_SCACHESYNC_STOREDATA);
! lock_ReleaseWrite(&newDscp->rw);
if (code != 0)
cm_EndDirOp(&newDirOp);
if (code == 0) {
cm_BeginDirOp(oldDscp, userp, reqp, CM_DIRLOCK_NONE, &oldDirOp);
! lock_ObtainWrite(&oldDscp->rw);
cm_dnlcRemove(oldDscp, oldNamep);
code = cm_SyncOp(oldDscp, NULL, userp, reqp, 0,
CM_SCACHESYNC_STOREDATA);
! lock_ReleaseWrite(&oldDscp->rw);
if (code != 0)
cm_EndDirOp(&oldDirOp);
if (code) {
/* cleanup first one */
! lock_ObtainWrite(&newDscp->rw);
cm_SyncOpDone(newDscp, NULL,
CM_SCACHESYNC_STOREDATA);
! lock_ReleaseWrite(&newDscp->rw);
cm_EndDirOp(&newDirOp);
}
}
***************
*** 3377,3389 ****
lock_ObtainWrite(&oldDirOp.scp->dirlock);
oldDirOp.lockType = CM_DIRLOCK_WRITE;
}
! lock_ObtainMutex(&oldDscp->mx);
cm_SyncOpDone(oldDscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0)
cm_MergeStatus(NULL, oldDscp, &updatedOldDirStatus, &volSync,
userp, CM_MERGEFLAG_DIROP);
! lock_ReleaseMutex(&oldDscp->mx);
if (code == 0) {
if (cm_CheckDirOpForSingleChange(&oldDirOp)) {
--- 3369,3381 ----
lock_ObtainWrite(&oldDirOp.scp->dirlock);
oldDirOp.lockType = CM_DIRLOCK_WRITE;
}
! lock_ObtainWrite(&oldDscp->rw);
cm_SyncOpDone(oldDscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0)
cm_MergeStatus(NULL, oldDscp, &updatedOldDirStatus, &volSync,
userp, CM_MERGEFLAG_DIROP);
! lock_ReleaseWrite(&oldDscp->rw);
if (code == 0) {
if (cm_CheckDirOpForSingleChange(&oldDirOp)) {
***************
*** 3421,3432 ****
lock_ObtainWrite(&newDirOp.scp->dirlock);
newDirOp.lockType = CM_DIRLOCK_WRITE;
}
! lock_ObtainMutex(&newDscp->mx);
cm_SyncOpDone(newDscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0)
cm_MergeStatus(NULL, newDscp, &updatedNewDirStatus, &volSync,
userp, CM_MERGEFLAG_DIROP);
! lock_ReleaseMutex(&newDscp->mx);
if (code == 0) {
/* we only make the local change if we successfully made
--- 3413,3424 ----
lock_ObtainWrite(&newDirOp.scp->dirlock);
newDirOp.lockType = CM_DIRLOCK_WRITE;
}
! lock_ObtainWrite(&newDscp->rw);
cm_SyncOpDone(newDscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0)
cm_MergeStatus(NULL, newDscp, &updatedNewDirStatus, &volSync,
userp, CM_MERGEFLAG_DIROP);
! lock_ReleaseWrite(&newDscp->rw);
if (code == 0) {
/* we only make the local change if we successfully made
***************
*** 3776,3782 ****
}
}
! /* Called with scp->mx held. Returns 0 if all is clear to read the
specified range by the client identified by key.
*/
long cm_LockCheckRead(cm_scache_t *scp,
--- 3768,3774 ----
}
}
! /* Called with scp->rw held. Returns 0 if all is clear to read the
specified range by the client identified by key.
*/
long cm_LockCheckRead(cm_scache_t *scp,
***************
*** 3860,3866 ****
#endif
}
! /* Called with scp->mx held. Returns 0 if all is clear to write the
specified range by the client identified by key.
*/
long cm_LockCheckWrite(cm_scache_t *scp,
--- 3852,3858 ----
#endif
}
! /* Called with scp->rw held. Returns 0 if all is clear to write the
specified range by the client identified by key.
*/
long cm_LockCheckWrite(cm_scache_t *scp,
***************
*** 3955,3961 ****
osi_QAdd(&cm_freeFileLocks, &l->q);
}
! /* called with scp->mx held. May release it during processing, but
leaves it held on exit. */
long cm_IntSetLock(cm_scache_t * scp, cm_user_t * userp, int lockType,
cm_req_t * reqp) {
--- 3947,3953 ----
osi_QAdd(&cm_freeFileLocks, &l->q);
}
! /* called with scp->rw held. May release it during processing, but
leaves it held on exit. */
long cm_IntSetLock(cm_scache_t * scp, cm_user_t * userp, int lockType,
cm_req_t * reqp) {
***************
*** 3965,3970 ****
--- 3957,3963 ----
cm_conn_t * connp;
struct rx_connection * callp;
AFSVolSync volSync;
+ afs_uint32 reqflags = reqp->flags;
tfid.Volume = scp->fid.volume;
tfid.Vnode = scp->fid.vnode;
***************
*** 3973,3979 ****
osi_Log2(afsd_logp, "CALL SetLock scp 0x%p for lock %d", scp, lockType);
! lock_ReleaseMutex(&scp->mx);
do {
code = cm_ConnFromFID(&cfid, userp, reqp, &connp);
--- 3966,3973 ----
osi_Log2(afsd_logp, "CALL SetLock scp 0x%p for lock %d", scp, lockType);
! reqp->flags |= CM_REQ_NORETRY;
! lock_ReleaseWrite(&scp->rw);
do {
code = cm_ConnFromFID(&cfid, userp, reqp, &connp);
***************
*** 3995,4006 ****
osi_Log0(afsd_logp, "CALL SetLock SUCCESS");
}
! lock_ObtainMutex(&scp->mx);
!
return code;
}
! /* called with scp->mx held. Releases it during processing */
long cm_IntReleaseLock(cm_scache_t * scp, cm_user_t * userp,
cm_req_t * reqp) {
long code = 0;
--- 3989,4000 ----
osi_Log0(afsd_logp, "CALL SetLock SUCCESS");
}
! lock_ObtainWrite(&scp->rw);
! reqp->flags = reqflags;
return code;
}
! /* called with scp->rw held. Releases it during processing */
long cm_IntReleaseLock(cm_scache_t * scp, cm_user_t * userp,
cm_req_t * reqp) {
long code = 0;
***************
*** 4015,4021 ****
tfid.Unique = scp->fid.unique;
cfid = scp->fid;
! lock_ReleaseMutex(&scp->mx);
osi_Log1(afsd_logp, "CALL ReleaseLock scp 0x%p", scp);
--- 4009,4015 ----
tfid.Unique = scp->fid.unique;
cfid = scp->fid;
! lock_ReleaseWrite(&scp->rw);
osi_Log1(afsd_logp, "CALL ReleaseLock scp 0x%p", scp);
***************
*** 4038,4049 ****
osi_Log0(afsd_logp,
"CALL ReleaseLock SUCCESS");
! lock_ObtainMutex(&scp->mx);
return code;
}
! /* called with scp->mx held. May release it during processing, but
will exit with lock held.
This will return:
--- 4032,4043 ----
osi_Log0(afsd_logp,
"CALL ReleaseLock SUCCESS");
! lock_ObtainWrite(&scp->rw);
return code;
}
! /* called with scp->rw held. May release it during processing, but
will exit with lock held.
This will return:
***************
*** 4129,4135 ****
return code;
}
! /* called with scp->mx held */
long cm_Lock(cm_scache_t *scp, unsigned char sLockType,
LARGE_INTEGER LOffset, LARGE_INTEGER LLength,
cm_key_t key,
--- 4123,4129 ----
return code;
}
! /* called with scp->rw held */
long cm_Lock(cm_scache_t *scp, unsigned char sLockType,
LARGE_INTEGER LOffset, LARGE_INTEGER LLength,
cm_key_t key,
***************
*** 4496,4502 ****
static int cm_KeyEquals(cm_key_t k1, cm_key_t k2, int flags);
! /* Called with scp->mx held */
long cm_UnlockByKey(cm_scache_t * scp,
cm_key_t key,
int flags,
--- 4490,4496 ----
static int cm_KeyEquals(cm_key_t k1, cm_key_t k2, int flags);
! /* Called with scp->rw held */
long cm_UnlockByKey(cm_scache_t * scp,
cm_key_t key,
int flags,
***************
*** 4740,4749 ****
return CM_ERROR_RANGE_NOT_LOCKED;
}
- lock_ReleaseRead(&cm_scacheLock);
-
/* discard lock record */
! lock_ObtainWrite(&cm_scacheLock);
if (scp->fileLocksT == q)
scp->fileLocksT = osi_QPrev(q);
osi_QRemoveHT(&scp->fileLocksH, &scp->fileLocksT, q);
--- 4734,4741 ----
return CM_ERROR_RANGE_NOT_LOCKED;
}
/* discard lock record */
! lock_ConvertRToW(&cm_scacheLock);
if (scp->fileLocksT == q)
scp->fileLocksT = osi_QPrev(q);
osi_QRemoveHT(&scp->fileLocksH, &scp->fileLocksT, q);
***************
*** 4877,4883 ****
return code;
}
! /* called with scp->mx held */
void cm_LockMarkSCacheLost(cm_scache_t * scp)
{
cm_file_lock_t *fileLock;
--- 4869,4875 ----
return code;
}
! /* called with scp->rw held */
void cm_LockMarkSCacheLost(cm_scache_t * scp)
{
cm_file_lock_t *fileLock;
***************
*** 4980,4986 ****
osi_Log1(afsd_logp, "cm_CheckLocks Updating scp 0x%x", scp);
lock_ReleaseWrite(&cm_scacheLock);
! lock_ObtainMutex(&scp->mx);
/* did the lock change while we weren't holding the lock? */
if (!IS_LOCK_ACTIVE(fileLock))
--- 4972,4978 ----
osi_Log1(afsd_logp, "cm_CheckLocks Updating scp 0x%x", scp);
lock_ReleaseWrite(&cm_scacheLock);
! lock_ObtainWrite(&scp->rw);
/* did the lock change while we weren't holding the lock? */
if (!IS_LOCK_ACTIVE(fileLock))
***************
*** 4997,5003 ****
goto post_syncopdone;
}
! /* cm_SyncOp releases scp->mx during which the lock
may get released. */
if (!IS_LOCK_ACTIVE(fileLock))
goto pre_syncopdone;
--- 4989,4995 ----
goto post_syncopdone;
}
! /* cm_SyncOp releases scp->rw during which the lock
may get released. */
if (!IS_LOCK_ACTIVE(fileLock))
goto pre_syncopdone;
***************
*** 5017,5023 ****
scp,
(int) scp->serverLock);
! lock_ReleaseMutex(&scp->mx);
do {
code = cm_ConnFromFID(&cfid, userp,
--- 5009,5015 ----
scp,
(int) scp->serverLock);
! lock_ReleaseWrite(&scp->rw);
do {
code = cm_ConnFromFID(&cfid, userp,
***************
*** 5038,5044 ****
code = cm_MapRPCError(code, &req);
! lock_ObtainMutex(&scp->mx);
if (code) {
osi_Log1(afsd_logp, "CALL ExtendLock FAILURE, code 0x%x", code);
--- 5030,5036 ----
code = cm_MapRPCError(code, &req);
! lock_ObtainWrite(&scp->rw);
if (code) {
osi_Log1(afsd_logp, "CALL ExtendLock FAILURE, code 0x%x", code);
***************
*** 5098,5104 ****
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
post_syncopdone:
! lock_ReleaseMutex(&scp->mx);
lock_ObtainWrite(&cm_scacheLock);
--- 5090,5096 ----
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
post_syncopdone:
! lock_ReleaseWrite(&scp->rw);
lock_ObtainWrite(&cm_scacheLock);
***************
*** 5125,5131 ****
osi_Log1(afsd_logp, "cm_CheckLocks completes lock check cycle %d", cm_lockRefreshCycle);
}
! /* NOT called with scp->mx held. */
long cm_RetryLock(cm_file_lock_t *oldFileLock, int client_is_dead)
{
long code = 0;
--- 5117,5123 ----
osi_Log1(afsd_logp, "cm_CheckLocks completes lock check cycle %d", cm_lockRefreshCycle);
}
! /* NOT called with scp->rw held. */
long cm_RetryLock(cm_file_lock_t *oldFileLock, int client_is_dead)
{
long code = 0;
***************
*** 5178,5184 ****
osi_assertx(scp != NULL, "null cm_scache_t");
lock_ReleaseRead(&cm_scacheLock);
! lock_ObtainMutex(&scp->mx);
code = cm_LockCheckPerms(scp, oldFileLock->lockType,
oldFileLock->userp,
--- 5170,5176 ----
osi_assertx(scp != NULL, "null cm_scache_t");
lock_ReleaseRead(&cm_scacheLock);
! lock_ObtainWrite(&scp->rw);
code = cm_LockCheckPerms(scp, oldFileLock->lockType,
oldFileLock->userp,
***************
*** 5190,5196 ****
}
code = 0;
} else if (code) {
! lock_ReleaseMutex(&scp->mx);
return code;
}
--- 5182,5188 ----
}
code = 0;
} else if (code) {
! lock_ReleaseWrite(&scp->rw);
return code;
}
***************
*** 5213,5219 ****
}
lock_ReleaseWrite(&cm_scacheLock);
! lock_ReleaseMutex(&scp->mx);
return 0;
}
--- 5205,5211 ----
}
lock_ReleaseWrite(&cm_scacheLock);
! lock_ReleaseWrite(&scp->rw);
return 0;
}
***************
*** 5257,5263 ****
if (code != 0) {
lock_ReleaseWrite(&cm_scacheLock);
! lock_ReleaseMutex(&scp->mx);
goto handleCode;
}
--- 5249,5255 ----
if (code != 0) {
lock_ReleaseWrite(&cm_scacheLock);
! lock_ReleaseWrite(&scp->rw);
goto handleCode;
}
***************
*** 5306,5312 ****
}
lock_ReleaseWrite(&cm_scacheLock);
! lock_ReleaseMutex(&scp->mx);
return 0;
--- 5298,5304 ----
}
lock_ReleaseWrite(&cm_scacheLock);
! lock_ReleaseWrite(&scp->rw);
return 0;
***************
*** 5409,5415 ****
osi_QRemoveHT(&scp->fileLocksH, &scp->fileLocksT, &oldFileLock->fileq);
lock_ReleaseWrite(&cm_scacheLock);
}
! lock_ReleaseMutex(&scp->mx);
updateLock:
lock_ObtainWrite(&cm_scacheLock);
--- 5401,5407 ----
osi_QRemoveHT(&scp->fileLocksH, &scp->fileLocksT, &oldFileLock->fileq);
lock_ReleaseWrite(&cm_scacheLock);
}
! lock_ReleaseWrite(&scp->rw);
updateLock:
lock_ObtainWrite(&cm_scacheLock);
***************
*** 5465,5475 ****
{
for ( scp = cm_data.scacheHashTablep[i]; scp; scp = scp->nextp ) {
while (scp->fileLocksH != NULL) {
! lock_ObtainMutex(&scp->mx);
lock_ObtainWrite(&cm_scacheLock);
if (!scp->fileLocksH) {
lock_ReleaseWrite(&cm_scacheLock);
! lock_ReleaseMutex(&scp->mx);
break;
}
fileLock = (cm_file_lock_t *)((char *) scp->fileLocksH - offsetof(cm_file_lock_t, fileq));
--- 5457,5467 ----
{
for ( scp = cm_data.scacheHashTablep[i]; scp; scp = scp->nextp ) {
while (scp->fileLocksH != NULL) {
! lock_ObtainWrite(&scp->rw);
lock_ObtainWrite(&cm_scacheLock);
if (!scp->fileLocksH) {
lock_ReleaseWrite(&cm_scacheLock);
! lock_ReleaseWrite(&scp->rw);
break;
}
fileLock = (cm_file_lock_t *)((char *) scp->fileLocksH - offsetof(cm_file_lock_t, fileq));
***************
*** 5481,5487 ****
cm_UnlockByKey(scp, key, 0, userp, &req);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
! lock_ReleaseMutex(&scp->mx);
}
}
}
--- 5473,5479 ----
cm_UnlockByKey(scp, key, 0, userp, &req);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
! lock_ReleaseWrite(&scp->rw);
}
}
}
Index: openafs/src/WINNT/afsd/cm_vnodeops.h
diff -c openafs/src/WINNT/afsd/cm_vnodeops.h:1.14.4.8 openafs/src/WINNT/afsd/cm_vnodeops.h:1.14.4.9
*** openafs/src/WINNT/afsd/cm_vnodeops.h:1.14.4.8 Sun Feb 17 00:59:30 2008
--- openafs/src/WINNT/afsd/cm_vnodeops.h Sun Mar 9 11:25:01 2008
***************
*** 170,175 ****
--- 170,176 ----
#define AFS_ACCESS_READ (FILE_GENERIC_READ & ~SYNCHRONIZE)
#define AFS_ACCESS_WRITE ((FILE_GENERIC_WRITE & ~(READ_CONTROL | SYNCHRONIZE)) \
& ~FILE_WRITE_ATTRIBUTES)
+ #define AFS_ACCESS_EXECUTE (FILE_GENERIC_EXECUTE & ~SYNCHRONIZE)
typedef struct cm_lock_data {
cm_key_t key;
Index: openafs/src/WINNT/afsd/cm_volstat.c
diff -c openafs/src/WINNT/afsd/cm_volstat.c:1.1.2.4 openafs/src/WINNT/afsd/cm_volstat.c:1.1.2.6
*** openafs/src/WINNT/afsd/cm_volstat.c:1.1.2.4 Sat Dec 22 23:52:58 2007
--- openafs/src/WINNT/afsd/cm_volstat.c Thu Mar 13 00:39:17 2008
***************
*** 298,303 ****
--- 298,304 ----
afs_uint32 code = 0;
cm_req_t req;
cm_scache_t *scp;
+ cm_volume_t *volp;
if (cellID == NULL || volID == NULL)
return CM_ERROR_INVAL;
***************
*** 311,321 ****
if (code)
goto done;
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL,cm_rootUserp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
goto done;
}
--- 312,322 ----
if (code)
goto done;
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL,cm_rootUserp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
goto done;
}
***************
*** 324,332 ****
*cellID = scp->fid.cell;
*volID = scp->fid.volume;
! *pstatus = cm_GetVolumeStatus(scp->volp, scp->fid.volume);
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
done:
--- 325,338 ----
*cellID = scp->fid.cell;
*volID = scp->fid.volume;
! volp = cm_GetVolumeByFID(&scp->fid);
! if (volp) {
! *pstatus = cm_GetVolumeStatus(volp, scp->fid.volume);
! cm_PutVolume(volp);
! } else
! *pstatus = vl_unknown;
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
done:
***************
*** 355,365 ****
if (code)
goto done;
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, cm_rootUserp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
goto done;
}
--- 361,371 ----
if (code)
goto done;
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, cm_rootUserp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
goto done;
}
***************
*** 382,388 ****
goto done;
}
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
done:
--- 388,394 ----
goto done;
}
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
done:
Index: openafs/src/WINNT/afsd/cm_volume.c
diff -c openafs/src/WINNT/afsd/cm_volume.c:1.14.4.31 openafs/src/WINNT/afsd/cm_volume.c:1.14.4.36
*** openafs/src/WINNT/afsd/cm_volume.c:1.14.4.31 Mon Feb 25 14:40:13 2008
--- openafs/src/WINNT/afsd/cm_volume.c Wed Mar 19 16:18:37 2008
***************
*** 528,533 ****
--- 528,559 ----
rwNewstate = rwServers_alldown ? vl_alldown : vl_online;
roNewstate = roServers_alldown ? vl_alldown : vl_online;
bkNewstate = bkServers_alldown ? vl_alldown : vl_online;
+ } else if (code == CM_ERROR_NOSUCHVOLUME || code == VL_NOENT) {
+ /* this volume does not exist - we should discard it */
+ if (volp->flags & CM_VOLUMEFLAG_IN_HASH)
+ cm_RemoveVolumeFromNameHashTable(volp);
+ if (volp->rw.flags & CM_VOLUMEFLAG_IN_HASH)
+ cm_RemoveVolumeFromIDHashTable(volp, RWVOL);
+ if (volp->ro.flags & CM_VOLUMEFLAG_IN_HASH)
+ cm_RemoveVolumeFromIDHashTable(volp, ROVOL);
+ if (volp->bk.flags & CM_VOLUMEFLAG_IN_HASH)
+ cm_RemoveVolumeFromIDHashTable(volp, BACKVOL);
+
+ /* Move to the end so it will be recycled first */
+ cm_MoveVolumeToLRULast(volp);
+
+ if (volp->rw.ID)
+ cm_VolumeStatusNotification(volp, volp->rw.ID, volp->rw.state, vl_alldown);
+ if (volp->ro.ID)
+ cm_VolumeStatusNotification(volp, volp->ro.ID, volp->ro.state, vl_alldown);
+ if (volp->bk.ID)
+ cm_VolumeStatusNotification(volp, volp->bk.ID, volp->bk.state, vl_alldown);
+
+ volp->rw.ID = volp->ro.ID = volp->bk.ID = 0;
+ cm_SetFid(&volp->rw.dotdotFid, 0, 0, 0, 0);
+ cm_SetFid(&volp->ro.dotdotFid, 0, 0, 0, 0);
+ cm_SetFid(&volp->bk.dotdotFid, 0, 0, 0, 0);
+ volp->namep[0] ='\0';
} else {
rwNewstate = roNewstate = bkNewstate = vl_alldown;
}
***************
*** 551,567 ****
return code;
}
void cm_GetVolume(cm_volume_t *volp)
{
! if (volp) {
! lock_ObtainWrite(&cm_volumeLock);
! volp->refCount++;
! lock_ReleaseWrite(&cm_volumeLock);
! }
}
! long cm_GetVolumeByID(cm_cell_t *cellp, afs_uint32 volumeID, cm_user_t *userp,
cm_req_t *reqp, afs_uint32 flags, cm_volume_t **outVolpp)
{
cm_volume_t *volp;
--- 577,627 ----
return code;
}
+ /* Requires read or write lock on cm_volumeLock */
void cm_GetVolume(cm_volume_t *volp)
{
! InterlockedIncrement(&volp->refCount);
}
+ cm_volume_t *cm_GetVolumeByFID(cm_fid_t *fidp)
+ {
+ cm_volume_t *volp;
+ afs_uint32 hash;
! lock_ObtainRead(&cm_volumeLock);
! hash = CM_VOLUME_ID_HASH(fidp->volume);
! /* The volumeID can be any one of the three types. So we must
! * search the hash table for all three types until we find it.
! * We will search in the order of RO, RW, BK.
! */
! for ( volp = cm_data.volumeROIDHashTablep[hash]; volp; volp = volp->ro.nextp) {
! if ( fidp->cell == volp->cellp->cellID && fidp->volume == volp->ro.ID )
! break;
! }
! if (!volp) {
! /* try RW volumes */
! for ( volp = cm_data.volumeRWIDHashTablep[hash]; volp; volp = volp->rw.nextp) {
! if ( fidp->cell == volp->cellp->cellID && fidp->volume == volp->rw.ID )
! break;
! }
! }
! if (!volp) {
! /* try BK volumes */
! for ( volp = cm_data.volumeBKIDHashTablep[hash]; volp; volp = volp->bk.nextp) {
! if ( fidp->cell == volp->cellp->cellID && fidp->volume == volp->bk.ID )
! break;
! }
! }
!
! /* hold the volume if we found it */
! if (volp)
! cm_GetVolume(volp);
!
! lock_ReleaseRead(&cm_volumeLock);
! return volp;
! }
!
! long cm_FindVolumeByID(cm_cell_t *cellp, afs_uint32 volumeID, cm_user_t *userp,
cm_req_t *reqp, afs_uint32 flags, cm_volume_t **outVolpp)
{
cm_volume_t *volp;
***************
*** 613,624 ****
osi_assertx(volp == volp2, "unexpected cm_vol_t");
#endif
- lock_ReleaseRead(&cm_volumeLock);
-
/* hold the volume if we found it */
if (volp)
cm_GetVolume(volp);
/* return it held */
if (volp) {
lock_ObtainMutex(&volp->mx);
--- 673,684 ----
osi_assertx(volp == volp2, "unexpected cm_vol_t");
#endif
/* hold the volume if we found it */
if (volp)
cm_GetVolume(volp);
+ lock_ReleaseRead(&cm_volumeLock);
+
/* return it held */
if (volp) {
lock_ObtainMutex(&volp->mx);
***************
*** 646,658 ****
/* otherwise, we didn't find it so consult the VLDB */
sprintf(volNameString, "%u", volumeID);
! code = cm_GetVolumeByName(cellp, volNameString, userp, reqp,
flags, outVolpp);
return code;
}
! long cm_GetVolumeByName(struct cm_cell *cellp, char *volumeNamep,
struct cm_user *userp, struct cm_req *reqp,
afs_uint32 flags, cm_volume_t **outVolpp)
{
--- 706,718 ----
/* otherwise, we didn't find it so consult the VLDB */
sprintf(volNameString, "%u", volumeID);
! code = cm_FindVolumeByName(cellp, volNameString, userp, reqp,
flags, outVolpp);
return code;
}
! long cm_FindVolumeByName(struct cm_cell *cellp, char *volumeNamep,
struct cm_user *userp, struct cm_req *reqp,
afs_uint32 flags, cm_volume_t **outVolpp)
{
***************
*** 752,762 ****
cm_VolumeStatusNotification(volp, volp->bk.ID, volp->bk.state, vl_unknown);
volp->rw.ID = volp->ro.ID = volp->bk.ID = 0;
! volp->dotdotFid.cell = 0;
! volp->dotdotFid.volume = 0;
! volp->dotdotFid.unique = 0;
! volp->dotdotFid.vnode = 0;
! volp->dotdotFid.hash = 0;
} else {
volp = &cm_data.volumeBaseAddress[cm_data.currentVolumes++];
memset(volp, 0, sizeof(cm_volume_t));
--- 812,820 ----
cm_VolumeStatusNotification(volp, volp->bk.ID, volp->bk.state, vl_unknown);
volp->rw.ID = volp->ro.ID = volp->bk.ID = 0;
! cm_SetFid(&volp->rw.dotdotFid, 0, 0, 0, 0);
! cm_SetFid(&volp->ro.dotdotFid, 0, 0, 0, 0);
! cm_SetFid(&volp->bk.dotdotFid, 0, 0, 0, 0);
} else {
volp = &cm_data.volumeBaseAddress[cm_data.currentVolumes++];
memset(volp, 0, sizeof(cm_volume_t));
***************
*** 781,793 ****
lock_ReleaseWrite(&cm_volumeLock);
}
else {
! lock_ReleaseRead(&cm_volumeLock);
! if (volp) {
cm_GetVolume(volp);
! lock_ObtainMutex(&volp->mx);
! } else {
return CM_ERROR_NOSUCHVOLUME;
! }
}
/* if we get here we are holding the mutex */
--- 839,852 ----
lock_ReleaseWrite(&cm_volumeLock);
}
else {
! if (volp)
cm_GetVolume(volp);
! lock_ReleaseRead(&cm_volumeLock);
!
! if (!volp)
return CM_ERROR_NOSUCHVOLUME;
!
! lock_ObtainMutex(&volp->mx);
}
/* if we get here we are holding the mutex */
***************
*** 803,817 ****
code = CM_ERROR_NOSUCHVOLUME;
if (code == 0) {
! *outVolpp = volp;
! if (!(flags & CM_GETVOL_FLAG_NO_LRU_UPDATE)) {
! lock_ObtainWrite(&cm_volumeLock);
! cm_AdjustVolumeLRU(volp);
! lock_ReleaseWrite(&cm_volumeLock);
! }
} else
! cm_PutVolume(volp);
return code;
}
--- 862,876 ----
code = CM_ERROR_NOSUCHVOLUME;
if (code == 0) {
! *outVolpp = volp;
! if (!(flags & CM_GETVOL_FLAG_NO_LRU_UPDATE)) {
! lock_ObtainWrite(&cm_volumeLock);
! cm_AdjustVolumeLRU(volp);
! lock_ReleaseWrite(&cm_volumeLock);
! }
} else
! cm_PutVolume(volp);
return code;
}
***************
*** 869,881 ****
#ifdef SEARCH_ALL_VOLUMES
osi_assertx(volp == volp2, "unexpected cm_vol_t");
#endif
-
- lock_ReleaseRead(&cm_volumeLock);
-
/* hold the volume if we found it */
if (volp)
cm_GetVolume(volp);
/* update it */
cm_data.mountRootGen = time(NULL);
lock_ObtainMutex(&volp->mx);
--- 928,939 ----
#ifdef SEARCH_ALL_VOLUMES
osi_assertx(volp == volp2, "unexpected cm_vol_t");
#endif
/* hold the volume if we found it */
if (volp)
cm_GetVolume(volp);
+ lock_ReleaseRead(&cm_volumeLock);
+
/* update it */
cm_data.mountRootGen = time(NULL);
lock_ObtainMutex(&volp->mx);
***************
*** 927,935 ****
void cm_PutVolume(cm_volume_t *volp)
{
! lock_ObtainWrite(&cm_volumeLock);
! osi_assertx(volp->refCount-- > 0, "cm_volume_t refCount 0");
! lock_ReleaseWrite(&cm_volumeLock);
}
/* return the read-only volume, if there is one, or the read-write volume if
--- 985,992 ----
void cm_PutVolume(cm_volume_t *volp)
{
! afs_int32 refCount = InterlockedDecrement(&volp->refCount);
! osi_assertx(refCount >= 0, "cm_volume_t refCount underflow has occurred");
}
/* return the read-only volume, if there is one, or the read-write volume if
***************
*** 953,975 ****
{
cm_volume_t *volp;
cm_scache_t *scp;
cm_data.mountRootGen = time(NULL);
/* force a re-loading of volume data from the vldb */
! lock_ObtainWrite(&cm_volumeLock);
for (volp = cm_data.allVolumesp; volp; volp=volp->allNextp) {
! volp->refCount++;
! lock_ReleaseWrite(&cm_volumeLock);
lock_ObtainMutex(&volp->mx);
volp->flags |= CM_VOLUMEFLAG_RESET;
lock_ReleaseMutex(&volp->mx);
! lock_ObtainWrite(&cm_volumeLock);
! osi_assertx(volp->refCount-- > 0, "cm_volume_t refCount 0");
}
! lock_ReleaseWrite(&cm_volumeLock);
/* force mount points to be re-evaluated so that
* if the volume location has changed we will pick
--- 1010,1034 ----
{
cm_volume_t *volp;
cm_scache_t *scp;
+ afs_int32 refCount;
cm_data.mountRootGen = time(NULL);
/* force a re-loading of volume data from the vldb */
! lock_ObtainRead(&cm_volumeLock);
for (volp = cm_data.allVolumesp; volp; volp=volp->allNextp) {
! InterlockedIncrement(&volp->refCount);
! lock_ReleaseRead(&cm_volumeLock);
lock_ObtainMutex(&volp->mx);
volp->flags |= CM_VOLUMEFLAG_RESET;
lock_ReleaseMutex(&volp->mx);
! lock_ObtainRead(&cm_volumeLock);
! refCount = InterlockedDecrement(&volp->refCount);
! osi_assertx(refCount >= 0, "cm_volume_t refCount underflow");
}
! lock_ReleaseRead(&cm_volumeLock);
/* force mount points to be re-evaluated so that
* if the volume location has changed we will pick
***************
*** 983,991 ****
&& !(scp->fid.cell == AFS_FAKE_ROOT_CELL_ID && scp->fid.volume == AFS_FAKE_ROOT_VOL_ID)
#endif
) {
! lock_ObtainMutex(&scp->mx);
scp->mountPointStringp[0] = '\0';
! lock_ReleaseMutex(&scp->mx);
}
}
--- 1042,1050 ----
&& !(scp->fid.cell == AFS_FAKE_ROOT_CELL_ID && scp->fid.volume == AFS_FAKE_ROOT_VOL_ID)
#endif
) {
! lock_ObtainWrite(&scp->rw);
scp->mountPointStringp[0] = '\0';
! lock_ReleaseWrite(&scp->rw);
}
}
***************
*** 1142,1159 ****
void cm_CheckOfflineVolumes(void)
{
cm_volume_t *volp;
! lock_ObtainWrite(&cm_volumeLock);
for (volp = cm_data.allVolumesp; volp; volp=volp->allNextp) {
! volp->refCount++;
! lock_ReleaseWrite(&cm_volumeLock);
!
! cm_CheckOfflineVolume(volp, 0);
!
! lock_ObtainWrite(&cm_volumeLock);
! osi_assertx(volp->refCount-- > 0, "cm_volume_t refCount 0");
}
! lock_ReleaseWrite(&cm_volumeLock);
}
--- 1201,1220 ----
void cm_CheckOfflineVolumes(void)
{
cm_volume_t *volp;
+ afs_int32 refCount;
! lock_ObtainRead(&cm_volumeLock);
for (volp = cm_data.allVolumesp; volp; volp=volp->allNextp) {
! if (volp->flags & CM_VOLUMEFLAG_IN_HASH) {
! InterlockedIncrement(&volp->refCount);
! lock_ReleaseRead(&cm_volumeLock);
! cm_CheckOfflineVolume(volp, 0);
! lock_ObtainRead(&cm_volumeLock);
! refCount = InterlockedDecrement(&volp->refCount);
! osi_assertx(refCount >= 0, "cm_volume_t refCount underflow");
! }
}
! lock_ReleaseRead(&cm_volumeLock);
}
***************
*** 1243,1256 ****
{
int code;
cm_volume_t* volp;
/* find volumes which might have RO copy on server*/
! lock_ObtainWrite(&cm_volumeLock);
for(volp = cm_data.allVolumesp; volp; volp=volp->allNextp)
{
code = 1 ; /* assume that list is unchanged */
! volp->refCount++;
! lock_ReleaseWrite(&cm_volumeLock);
lock_ObtainMutex(&volp->mx);
if ((tsp->cellp==volp->cellp) && (volp->ro.serversp))
--- 1304,1318 ----
{
int code;
cm_volume_t* volp;
+ afs_int32 refCount;
/* find volumes which might have RO copy on server*/
! lock_ObtainRead(&cm_volumeLock);
for(volp = cm_data.allVolumesp; volp; volp=volp->allNextp)
{
code = 1 ; /* assume that list is unchanged */
! InterlockedIncrement(&volp->refCount);
! lock_ReleaseRead(&cm_volumeLock);
lock_ObtainMutex(&volp->mx);
if ((tsp->cellp==volp->cellp) && (volp->ro.serversp))
***************
*** 1261,1270 ****
cm_RandomizeServer(&volp->ro.serversp);
lock_ReleaseMutex(&volp->mx);
! lock_ObtainWrite(&cm_volumeLock);
! osi_assertx(volp->refCount-- > 0, "cm_volume_t refCount 0");
}
! lock_ReleaseWrite(&cm_volumeLock);
}
/* dump all volumes that have reference count > 0 to a file.
--- 1323,1333 ----
cm_RandomizeServer(&volp->ro.serversp);
lock_ReleaseMutex(&volp->mx);
! lock_ObtainRead(&cm_volumeLock);
! refCount = InterlockedDecrement(&volp->refCount);
! osi_assertx(refCount >= 0, "cm_volume_t refCount underflow");
}
! lock_ReleaseRead(&cm_volumeLock);
}
/* dump all volumes that have reference count > 0 to a file.
***************
*** 1287,1305 ****
for (volp = cm_data.allVolumesp; volp; volp=volp->allNextp)
{
! cm_scache_t *scp;
! int scprefs = 0;
!
! for (scp = cm_data.allSCachesp; scp; scp = scp->allNextp)
! {
! if (scp->volp == volp)
! scprefs++;
! }
!
! sprintf(output, "%s - volp=0x%p cell=%s name=%s rwID=%u roID=%u bkID=%u flags=0x%x fid (cell=%d, volume=%d, vnode=%d, unique=%d) refCount=%u scpRefs=%u\r\n",
cookie, volp, volp->cellp->name, volp->namep, volp->rw.ID, volp->ro.ID, volp->bk.ID, volp->flags,
! volp->dotdotFid.cell, volp->dotdotFid.volume, volp->dotdotFid.vnode, volp->dotdotFid.unique,
! volp->refCount, scprefs);
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
}
sprintf(output, "%s - Done dumping volumes.\r\n", cookie);
--- 1350,1358 ----
for (volp = cm_data.allVolumesp; volp; volp=volp->allNextp)
{
! sprintf(output, "%s - volp=0x%p cell=%s name=%s rwID=%u roID=%u bkID=%u flags=0x%x refCount=%u\r\n",
cookie, volp, volp->cellp->name, volp->namep, volp->rw.ID, volp->ro.ID, volp->bk.ID, volp->flags,
! volp->refCount);
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
}
sprintf(output, "%s - Done dumping volumes.\r\n", cookie);
***************
*** 1495,1500 ****
--- 1548,1569 ----
}
/* must be called with cm_volumeLock write-locked! */
+ void cm_MoveVolumeToLRULast(cm_volume_t *volp)
+ {
+ if (volp == cm_data.volumeLRULastp)
+ return;
+
+ if (volp == cm_data.volumeLRUFirstp)
+ cm_data.volumeLRUFirstp = (cm_volume_t *) osi_QNext(&volp->q);
+ if (volp->flags & CM_VOLUMEFLAG_IN_LRU_QUEUE)
+ osi_QRemoveHT((osi_queue_t **) &cm_data.volumeLRUFirstp, (osi_queue_t **) &cm_data.volumeLRULastp, &volp->q);
+ osi_QAddT((osi_queue_t **) &cm_data.volumeLRUFirstp, (osi_queue_t **) &cm_data.volumeLRULastp, &volp->q);
+ volp->flags |= CM_VOLUMEFLAG_IN_LRU_QUEUE;
+ if (!cm_data.volumeLRULastp)
+ cm_data.volumeLRULastp = volp;
+ }
+
+ /* must be called with cm_volumeLock write-locked! */
void cm_RemoveVolumeFromLRU(cm_volume_t *volp)
{
if (volp->flags & CM_VOLUMEFLAG_IN_LRU_QUEUE) {
***************
*** 1577,1585 ****
lock_ReleaseRead(&cm_volumeLock);
if (cm_GetSCache(&fid, &scp, cm_rootUserp, &req) == 0) {
! lock_ObtainMutex(&scp->mx);
cm_GetCallback(scp, cm_rootUserp, &req, 1);
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
}
lock_ObtainRead(&cm_volumeLock);
--- 1646,1654 ----
lock_ReleaseRead(&cm_volumeLock);
if (cm_GetSCache(&fid, &scp, cm_rootUserp, &req) == 0) {
! lock_ObtainWrite(&scp->rw);
cm_GetCallback(scp, cm_rootUserp, &req, 1);
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
}
lock_ObtainRead(&cm_volumeLock);
Index: openafs/src/WINNT/afsd/cm_volume.h
diff -c openafs/src/WINNT/afsd/cm_volume.h:1.5.6.8 openafs/src/WINNT/afsd/cm_volume.h:1.5.6.12
*** openafs/src/WINNT/afsd/cm_volume.h:1.5.6.8 Thu Jan 24 10:31:13 2008
--- openafs/src/WINNT/afsd/cm_volume.h Wed Mar 19 16:18:37 2008
***************
*** 15,22 ****
#define CM_VOLUME_MAGIC ('V' | 'O' <<8 | 'L'<<16 | 'M'<<24)
typedef struct cm_vol_state {
- afs_uint32 ID; /* by mx */
struct cm_volume *nextp; /* volumeIDHashTable; by cm_volumeLock */
cm_serverRef_t *serversp; /* by mx */
enum volstatus state; /* by mx */
afs_uint32 flags; /* by mx */
--- 15,23 ----
#define CM_VOLUME_MAGIC ('V' | 'O' <<8 | 'L'<<16 | 'M'<<24)
typedef struct cm_vol_state {
struct cm_volume *nextp; /* volumeIDHashTable; by cm_volumeLock */
+ afs_uint32 ID; /* by mx */
+ struct cm_fid dotdotFid; /* parent of volume root */
cm_serverRef_t *serversp; /* by mx */
enum volstatus state; /* by mx */
afs_uint32 flags; /* by mx */
***************
*** 33,42 ****
struct cm_vol_state rw; /* by cm_volumeLock */
struct cm_vol_state ro; /* by cm_volumeLock */
struct cm_vol_state bk; /* by cm_volumeLock */
- struct cm_fid dotdotFid; /* parent of volume root */
osi_mutex_t mx;
afs_uint32 flags; /* by mx */
! afs_uint32 refCount; /* by cm_volumeLock */
time_t cbExpiresRO; /* latest RO expiration time; by cm_scacheLock */
} cm_volume_t;
--- 34,42 ----
struct cm_vol_state rw; /* by cm_volumeLock */
struct cm_vol_state ro; /* by cm_volumeLock */
struct cm_vol_state bk; /* by cm_volumeLock */
osi_mutex_t mx;
afs_uint32 flags; /* by mx */
! afs_int32 refCount; /* by Interlocked operations */
time_t cbExpiresRO; /* latest RO expiration time; by cm_scacheLock */
} cm_volume_t;
***************
*** 52,62 ****
extern void cm_InitVolume(int newFile, long maxVols);
! extern long cm_GetVolumeByName(struct cm_cell *cellp, char *volNamep,
struct cm_user *userp, struct cm_req *reqp,
afs_uint32 flags, cm_volume_t **outVolpp);
! extern long cm_GetVolumeByID(struct cm_cell *cellp, afs_uint32 volumeID,
cm_user_t *userp, cm_req_t *reqp,
afs_uint32 flags, cm_volume_t **outVolpp);
--- 52,62 ----
extern void cm_InitVolume(int newFile, long maxVols);
! extern long cm_FindVolumeByName(struct cm_cell *cellp, char *volNamep,
struct cm_user *userp, struct cm_req *reqp,
afs_uint32 flags, cm_volume_t **outVolpp);
! extern long cm_FindVolumeByID(struct cm_cell *cellp, afs_uint32 volumeID,
cm_user_t *userp, cm_req_t *reqp,
afs_uint32 flags, cm_volume_t **outVolpp);
***************
*** 77,82 ****
--- 77,84 ----
extern void cm_GetVolume(cm_volume_t *volp);
+ extern cm_volume_t *cm_GetVolumeByFID(cm_fid_t *);
+
extern void cm_PutVolume(cm_volume_t *volp);
extern long cm_GetROVolumeID(cm_volume_t *volp);
***************
*** 108,113 ****
--- 110,117 ----
extern void cm_AdjustVolumeLRU(cm_volume_t *volp);
+ extern void cm_MoveVolumeToLRULast(cm_volume_t *volp);
+
extern void cm_RemoveVolumeFromLRU(cm_volume_t *volp);
extern void cm_CheckOfflineVolumes(void);
***************
*** 121,124 ****
--- 125,130 ----
extern enum volstatus cm_GetVolumeStatus(cm_volume_t *volp, afs_uint32 volID);
extern void cm_VolumeRenewROCallbacks(void);
+
+ extern osi_rwlock_t cm_volumeLock;
#endif /* __CM_VOLUME_H_ENV__ */
Index: openafs/src/WINNT/afsd/fs.c
diff -c openafs/src/WINNT/afsd/fs.c:1.32.4.19 openafs/src/WINNT/afsd/fs.c:1.32.4.20
*** openafs/src/WINNT/afsd/fs.c:1.32.4.19 Fri Feb 8 21:32:19 2008
--- openafs/src/WINNT/afsd/fs.c Wed Mar 19 09:24:00 2008
***************
*** 535,558 ****
tp->nplus = tp->nminus = 0;
tp->pluslist = tp->minuslist = 0;
tp->dfs = 0;
! sscanf(astr, "%d dfs:%d %s", &junk, &tp->dfs, tp->cell);
return tp;
}
static struct Acl *
ParseAcl (char *astr)
{
! int nplus, nminus, i, trights;
char tname[MAXNAME];
! struct AclEntry *first, *last, *tl;
struct Acl *ta;
! ta = (struct Acl *) malloc (sizeof (struct Acl));
! assert(ta);
! ta->dfs = 0;
! sscanf(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell);
astr = SkipLine(astr);
! sscanf(astr, "%d", &ta->nminus);
astr = SkipLine(astr);
nplus = ta->nplus;
--- 535,570 ----
tp->nplus = tp->nminus = 0;
tp->pluslist = tp->minuslist = 0;
tp->dfs = 0;
! if (astr == NULL || sscanf(astr, "%d dfs:%d %s", &junk, &tp->dfs, tp->cell) <= 0) {
! tp->dfs = 0;
! tp->cell[0] = '\0';
! }
return tp;
}
static struct Acl *
ParseAcl (char *astr)
{
! int nplus, nminus, i, trights, ret;
char tname[MAXNAME];
! struct AclEntry *first, *next, *last, *tl;
struct Acl *ta;
! ta = EmptyAcl(NULL);
! if (astr == NULL || strlen(astr) == 0)
! return ta;
!
! ret = sscanf(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell);
! if (ret <= 0) {
! free(ta);
! return NULL;
! }
astr = SkipLine(astr);
! ret = sscanf(astr, "%d", &ta->nminus);
! if (ret <= 0) {
! free(ta);
! return NULL;
! }
astr = SkipLine(astr);
nplus = ta->nplus;
***************
*** 561,570 ****
last = 0;
first = 0;
for(i=0;iname, tname);
--- 573,585 ----
last = 0;
first = 0;
for(i=0;iname, tname);
***************
*** 579,588 ****
last = 0;
first = 0;
for(i=0;iname, tname);
--- 594,606 ----
last = 0;
first = 0;
for(i=0;iname, tname);
***************
*** 594,600 ****
--- 612,634 ----
}
ta->minuslist = first;
+ exit:
return ta;
+
+ nminus_err:
+ for (;first; first = next) {
+ next = first->next;
+ free(first);
+ }
+ first = ta->pluslist;
+
+ nplus_err:
+ for (;first; first = next) {
+ next = first->next;
+ free(first);
+ }
+ free(ta);
+ return NULL;
}
static int
***************
*** 904,909 ****
--- 938,950 ----
if (ta)
ZapAcl(ta);
ta = ParseAcl(space);
+ if (!ta) {
+ fprintf(stderr,
+ "fs: %s: invalid acl data returned from VIOCGETAL\n",
+ ti->data);
+ error = 1;
+ continue;
+ }
if (!plusp && ta->dfs) {
fprintf(stderr,
"fs: %s: you may not use the -negative switch with DFS acl's.\n%s",
***************
*** 918,923 ****
--- 959,971 ----
ta = EmptyAcl(space);
else
ta = ParseAcl(space);
+ if (!ta) {
+ fprintf(stderr,
+ "fs: %s: invalid acl data returned from VIOCGETAL\n",
+ ti->data);
+ error = 1;
+ continue;
+ }
CleanAcl(ta, ti->data);
for(ui=as->parms[1].items; ui; ui=ui->next->next) {
enum rtype rtype;
***************
*** 1027,1032 ****
--- 1075,1086 ----
return 1;
}
fa = ParseAcl(space);
+ if (!fa) {
+ fprintf(stderr,
+ "fs: %s: invalid acl data returned from VIOCGETAL\n",
+ as->parms[0].items->data);
+ return 1;
+ }
CleanAcl(fa, as->parms[0].items->data);
for (ti=as->parms[1].items; ti;ti=ti->next) {
blob.out_size = MAXSIZE;
***************
*** 1044,1049 ****
--- 1098,1110 ----
ta = EmptyAcl(space);
else
ta = ParseAcl(space);
+ if (!ta) {
+ fprintf(stderr,
+ "fs: %s: invalid acl data returned from VIOCGETAL\n",
+ ti->data);
+ error = 1;
+ continue;
+ }
CleanAcl(ta, ti->data);
if (ta->dfs != fa->dfs) {
fprintf(stderr,
***************
*** 1206,1212 ****
if (ta)
ZapAcl(ta);
ta = ParseAcl(space);
!
if (ta->dfs) {
fprintf(stderr,
"%s: cleanacl is not supported for DFS access lists.\n",
--- 1267,1279 ----
if (ta)
ZapAcl(ta);
ta = ParseAcl(space);
! if (!ta) {
! fprintf(stderr,
! "fs: %s: invalid acl data returned from VIOCGETAL\n",
! ti->data);
! error = 1;
! continue;
! }
if (ta->dfs) {
fprintf(stderr,
"%s: cleanacl is not supported for DFS access lists.\n",
***************
*** 1292,1297 ****
--- 1359,1371 ----
continue;
}
ta = ParseAcl(space);
+ if (!ta) {
+ fprintf(stderr,
+ "fs: %s: invalid acl data returned from VIOCGETAL\n",
+ ti->data);
+ error = 1;
+ continue;
+ }
switch (ta->dfs) {
case 0:
printf("Access list for %s is\n", ti->data);
Index: openafs/src/WINNT/afsd/rawops.c
diff -c openafs/src/WINNT/afsd/rawops.c:1.2.4.4 openafs/src/WINNT/afsd/rawops.c:1.2.4.6
*** openafs/src/WINNT/afsd/rawops.c:1.2.4.4 Fri Feb 22 19:17:35 2008
--- openafs/src/WINNT/afsd/rawops.c Wed Mar 19 11:36:27 2008
***************
*** 10,17 ****
#include
#include "afsd.h"
- #include "afsdifs.h"
-
#define CM_BUF_SIZE 4096
long buf_bufferSize = CM_BUF_SIZE;
--- 10,15 ----
***************
*** 33,39 ****
bufferp = NULL;
! lock_ObtainMutex(&scp->mx);
/* start by looking up the file's end */
code = cm_SyncOp(scp, NULL, userp, &req, 0,
--- 31,37 ----
bufferp = NULL;
! lock_ObtainWrite(&scp->rw);
/* start by looking up the file's end */
code = cm_SyncOp(scp, NULL, userp, &req, 0,
***************
*** 82,92 ****
buf_Release(bufferp);
bufferp = NULL;
}
! lock_ReleaseMutex(&scp->mx);
code = buf_Get(scp, &thyper, &bufferp);
! lock_ObtainMutex(&scp->mx);
if (code) goto done;
bufferOffset = thyper;
--- 80,90 ----
buf_Release(bufferp);
bufferp = NULL;
}
! lock_ReleaseWrite(&scp->rw);
code = buf_Get(scp, &thyper, &bufferp);
! lock_ObtainWrite(&scp->rw);
if (code) goto done;
bufferOffset = thyper;
***************
*** 134,140 ****
} /* while 1 */
done:
! lock_ReleaseMutex(&scp->mx);
//lock_ReleaseMutex(&fidp->mx);
if (bufferp)
buf_Release(bufferp);
--- 132,138 ----
} /* while 1 */
done:
! lock_ReleaseWrite(&scp->rw);
//lock_ReleaseMutex(&fidp->mx);
if (bufferp)
buf_Release(bufferp);
***************
*** 169,175 ****
bufferp = NULL;
doWriteBack = 0;
! lock_ObtainMutex(&scp->mx);
/* start by looking up the file's end */
code = cm_SyncOp(scp, NULL, userp, &req, 0,
--- 167,173 ----
bufferp = NULL;
doWriteBack = 0;
! lock_ObtainWrite(&scp->rw);
/* start by looking up the file's end */
code = cm_SyncOp(scp, NULL, userp, &req, 0,
***************
*** 243,254 ****
buf_Release(bufferp);
bufferp = NULL;
}
! lock_ReleaseMutex(&scp->mx);
code = buf_Get(scp, &thyper, &bufferp);
lock_ObtainMutex(&bufferp->mx);
! lock_ObtainMutex(&scp->mx);
if (code)
goto done;
--- 241,252 ----
buf_Release(bufferp);
bufferp = NULL;
}
! lock_ReleaseWrite(&scp->rw);
code = buf_Get(scp, &thyper, &bufferp);
lock_ObtainMutex(&bufferp->mx);
! lock_ObtainWrite(&scp->rw);
if (code)
goto done;
***************
*** 298,306 ****
lock_ReleaseMutex(&bufferp->mx);
code = cm_GetBuffer(scp, bufferp, NULL, userp,
&req);
! lock_ReleaseMutex(&scp->mx);
lock_ObtainMutex(&bufferp->mx);
! lock_ObtainMutex(&scp->mx);
if (code)
break;
}
--- 296,304 ----
lock_ReleaseMutex(&bufferp->mx);
code = cm_GetBuffer(scp, bufferp, NULL, userp,
&req);
! lock_ReleaseWrite(&scp->rw);
lock_ObtainMutex(&bufferp->mx);
! lock_ObtainWrite(&scp->rw);
if (code)
break;
}
***************
*** 349,364 ****
} /* while 1 */
done:
! lock_ReleaseMutex(&scp->mx);
if (bufferp) {
lock_ReleaseMutex(&bufferp->mx);
buf_Release(bufferp);
}
if (code == 0 && doWriteBack) {
! lock_ObtainMutex(&scp->mx);
cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE);
! lock_ReleaseMutex(&scp->mx);
cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart,
writeBackOffset.HighPart, cm_chunkSize, 0, userp);
}
--- 347,362 ----
} /* while 1 */
done:
! lock_ReleaseWrite(&scp->rw);
if (bufferp) {
lock_ReleaseMutex(&bufferp->mx);
buf_Release(bufferp);
}
if (code == 0 && doWriteBack) {
! lock_ObtainWrite(&scp->rw);
cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE);
! lock_ReleaseWrite(&scp->rw);
cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart,
writeBackOffset.HighPart, cm_chunkSize, 0, userp);
}
Index: openafs/src/WINNT/afsd/smb.c
diff -c openafs/src/WINNT/afsd/smb.c:1.118.2.63 openafs/src/WINNT/afsd/smb.c:1.118.2.70
*** openafs/src/WINNT/afsd/smb.c:1.118.2.63 Mon Feb 25 00:36:46 2008
--- openafs/src/WINNT/afsd/smb.c Sun Mar 9 11:25:01 2008
***************
*** 83,91 ****
smb_packet_t *smb_packetFreeListp;
smb_ncb_t *smb_ncbFreeListp;
! int smb_NumServerThreads;
! int numNCBs, numSessions, numVCs;
int smb_maxVCPerServer;
int smb_maxMpxRequests;
--- 83,91 ----
smb_packet_t *smb_packetFreeListp;
smb_ncb_t *smb_ncbFreeListp;
! afs_uint32 smb_NumServerThreads;
! afs_uint32 numNCBs, numSessions, numVCs;
int smb_maxVCPerServer;
int smb_maxMpxRequests;
***************
*** 246,252 ****
time_t now = osi_Time();
/* Give one priority boost for each 15 seconds */
! SetThreadPriority(GetCurrentThread(), (now - *tp) / 15);
}
}
--- 246,252 ----
time_t now = osi_Time();
/* Give one priority boost for each 15 seconds */
! SetThreadPriority(GetCurrentThread(), (int)((now - *tp) / 15));
}
}
***************
*** 1582,1590 ****
fidp->vcp = NULL;
scp = fidp->scp; /* release after lock is released */
if (scp) {
! lock_ObtainMutex(&scp->mx);
scp->flags &= ~CM_SCACHEFLAG_SMB_FID;
! lock_ReleaseMutex(&scp->mx);
osi_Log2(smb_logp,"smb_ReleaseFID fidp 0x%p scp 0x%p", fidp, scp);
fidp->scp = NULL;
}
--- 1582,1590 ----
fidp->vcp = NULL;
scp = fidp->scp; /* release after lock is released */
if (scp) {
! lock_ObtainWrite(&scp->rw);
scp->flags &= ~CM_SCACHEFLAG_SMB_FID;
! lock_ReleaseWrite(&scp->rw);
osi_Log2(smb_logp,"smb_ReleaseFID fidp 0x%p scp 0x%p", fidp, scp);
fidp->scp = NULL;
}
***************
*** 1828,1834 ****
snprintf(pathstr, sizeof(pathstr)/sizeof(char),
"/" CM_PREFIX_VOL "%s", shareName);
pathstr[sizeof(pathstr)/sizeof(char) - 1] = '\0';
! len = strlen(pathstr) + 1;
*pathNamep = malloc(len);
if (*pathNamep) {
--- 1828,1834 ----
snprintf(pathstr, sizeof(pathstr)/sizeof(char),
"/" CM_PREFIX_VOL "%s", shareName);
pathstr[sizeof(pathstr)/sizeof(char) - 1] = '\0';
! len = (DWORD)(strlen(pathstr) + 1);
*pathNamep = malloc(len);
if (*pathNamep) {
***************
*** 2057,2069 ****
dsp->cookie, dsp, dsp->scp);
dsp->flags |= SMB_DIRSEARCH_DELETE;
if (dsp->scp != NULL) {
! lock_ObtainMutex(&dsp->scp->mx);
if (dsp->flags & SMB_DIRSEARCH_BULKST) {
dsp->flags &= ~SMB_DIRSEARCH_BULKST;
dsp->scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING;
dsp->scp->bulkStatProgress = hzero;
}
! lock_ReleaseMutex(&dsp->scp->mx);
}
lock_ReleaseMutex(&dsp->mx);
lock_ReleaseWrite(&smb_globalLock);
--- 2057,2069 ----
dsp->cookie, dsp, dsp->scp);
dsp->flags |= SMB_DIRSEARCH_DELETE;
if (dsp->scp != NULL) {
! lock_ObtainWrite(&dsp->scp->rw);
if (dsp->flags & SMB_DIRSEARCH_BULKST) {
dsp->flags &= ~SMB_DIRSEARCH_BULKST;
dsp->scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING;
dsp->scp->bulkStatProgress = hzero;
}
! lock_ReleaseWrite(&dsp->scp->rw);
}
lock_ReleaseMutex(&dsp->mx);
lock_ReleaseWrite(&smb_globalLock);
***************
*** 2887,2893 ****
else if (code == CM_ERROR_RANGE_NOT_LOCKED) {
NTStatus = 0xC000007EL; /* Range Not Locked */
}
! else {
NTStatus = 0xC0982001L; /* SMB non-specific error */
}
--- 2887,2898 ----
else if (code == CM_ERROR_RANGE_NOT_LOCKED) {
NTStatus = 0xC000007EL; /* Range Not Locked */
}
! else if (code == CM_ERROR_NOSUCHDEVICE) {
! NTStatus = 0xC000000EL; /* No Such Device */
! }
! else if (code == CM_ERROR_LOCK_NOT_GRANTED) {
! NTStatus = 0xC0000055L; /* Lock Not Granted */
! } else {
NTStatus = 0xC0982001L; /* SMB non-specific error */
}
***************
*** 3099,3104 ****
--- 3104,3110 ----
unsigned short fd;
unsigned pid;
smb_fid_t *fidp;
+ smb_t *smbp = (smb_t*) inp;
long code = 0;
cm_user_t *userp = NULL;
NCB *ncbp;
***************
*** 3154,3160 ****
}
! pid = ((smb_t *) inp)->pid;
{
LARGE_INTEGER LOffset, LLength;
cm_key_t key;
--- 3160,3166 ----
}
! pid = smbp->pid;
{
LARGE_INTEGER LOffset, LLength;
cm_key_t key;
***************
*** 3166,3174 ****
LLength.HighPart = 0;
LLength.LowPart = count;
! lock_ObtainMutex(&fidp->scp->mx);
code = cm_LockCheckRead(fidp->scp, LOffset, LLength, key);
! lock_ReleaseMutex(&fidp->scp->mx);
}
if (code) {
goto send1a;
--- 3172,3180 ----
LLength.HighPart = 0;
LLength.LowPart = count;
! lock_ObtainWrite(&fidp->scp->rw);
code = cm_LockCheckRead(fidp->scp, LOffset, LLength, key);
! lock_ReleaseWrite(&fidp->scp->rw);
}
if (code) {
goto send1a;
***************
*** 3676,3681 ****
--- 3682,3692 ----
if (wl->state == SMB_WAITINGLOCKSTATE_DONE)
continue;
+ if (wl->state == SMB_WAITINGLOCKSTATE_CANCELLED) {
+ code = CM_ERROR_LOCK_NOT_GRANTED;
+ break;
+ }
+
osi_assertx(wl->state != SMB_WAITINGLOCKSTATE_ERROR, "!SMB_WAITINGLOCKSTATE_ERROR");
/* wl->state is either _DONE or _WAITING. _ERROR
***************
*** 3694,3701 ****
if (code == CM_ERROR_WOULDBLOCK) {
/* no progress */
! if (wlRequest->timeRemaining != 0xffffffff
! && (wlRequest->timeRemaining -= 1000) < 0)
goto endWait;
continue;
--- 3705,3712 ----
if (code == CM_ERROR_WOULDBLOCK) {
/* no progress */
! if (wlRequest->msTimeout != 0xffffffff
! && ((osi_Time() - wlRequest->start_t) * 1000 > wlRequest->msTimeout))
goto endWait;
continue;
***************
*** 3715,3734 ****
cm_InitReq(&req);
! lock_ObtainMutex(&scp->mx);
for (wl = wlRequest->locks; wl; wl = wlNext) {
wlNext = (smb_waitingLock_t *) osi_QNext(&wl->q);
!
! cm_Unlock(scp, wlRequest->lockType, wl->LOffset,
! wl->LLength, wl->key, NULL, &req);
osi_QRemove((osi_queue_t **) &wlRequest->locks, &wl->q);
free(wl);
}
! lock_ReleaseMutex(&scp->mx);
} else {
--- 3726,3746 ----
cm_InitReq(&req);
! lock_ObtainWrite(&scp->rw);
for (wl = wlRequest->locks; wl; wl = wlNext) {
wlNext = (smb_waitingLock_t *) osi_QNext(&wl->q);
!
! if (wl->state == SMB_WAITINGLOCKSTATE_DONE)
! cm_Unlock(scp, wlRequest->lockType, wl->LOffset,
! wl->LLength, wl->key, NULL, &req);
osi_QRemove((osi_queue_t **) &wlRequest->locks, &wl->q);
free(wl);
}
! lock_ReleaseWrite(&scp->rw);
} else {
***************
*** 4079,4089 ****
*dptr++ = SMB_ATTR_HIDDEN;
continue;
}
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
if (patchp->flags & SMB_DIRLISTPATCH_DOTFILE)
*dptr++ = SMB_ATTR_HIDDEN;
--- 4091,4101 ----
*dptr++ = SMB_ATTR_HIDDEN;
continue;
}
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
if (patchp->flags & SMB_DIRLISTPATCH_DOTFILE)
*dptr++ = SMB_ATTR_HIDDEN;
***************
*** 4092,4097 ****
--- 4104,4110 ----
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ lock_ConvertWToR(&scp->rw);
attr = smb_Attributes(scp);
/* check hidden attribute (the flag is only ON when dot file hiding is on ) */
if (patchp->flags & SMB_DIRLISTPATCH_DOTFILE)
***************
*** 4114,4120 ****
/* copy out file length */
*((u_long *)dptr) = scp->length.LowPart;
dptr += 4;
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
}
--- 4127,4133 ----
/* copy out file length */
*((u_long *)dptr) = scp->length.LowPart;
dptr += 4;
! lock_ReleaseRead(&scp->rw);
cm_ReleaseSCache(scp);
}
***************
*** 4309,4322 ****
* now.
*/
cm_HoldSCache(scp);
! lock_ObtainMutex(&scp->mx);
if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0
&& LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) {
scp->flags |= CM_SCACHEFLAG_BULKSTATTING;
dsp->flags |= SMB_DIRSEARCH_BULKST;
dsp->scp->bulkStatProgress = hzero;
}
! lock_ReleaseMutex(&scp->mx);
}
}
lock_ReleaseMutex(&dsp->mx);
--- 4322,4335 ----
* now.
*/
cm_HoldSCache(scp);
! lock_ObtainWrite(&scp->rw);
if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0
&& LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) {
scp->flags |= CM_SCACHEFLAG_BULKSTATTING;
dsp->flags |= SMB_DIRSEARCH_BULKST;
dsp->scp->bulkStatProgress = hzero;
}
! lock_ReleaseWrite(&scp->rw);
}
}
lock_ReleaseMutex(&dsp->mx);
***************
*** 4334,4344 ****
smb_SetSMBParm(outp, 0, 0);
/* get the directory size */
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_DeleteDirSearch(dsp);
--- 4347,4357 ----
smb_SetSMBParm(outp, 0, 0);
/* get the directory size */
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_DeleteDirSearch(dsp);
***************
*** 4407,4413 ****
buf_Release(bufferp);
bufferp = NULL;
}
! lock_ReleaseMutex(&scp->mx);
code = buf_Get(scp, &thyper, &bufferp);
lock_ObtainMutex(&dsp->mx);
--- 4420,4426 ----
buf_Release(bufferp);
bufferp = NULL;
}
! lock_ReleaseWrite(&scp->rw);
code = buf_Get(scp, &thyper, &bufferp);
lock_ObtainMutex(&dsp->mx);
***************
*** 4416,4422 ****
*/
if (starPattern) {
smb_ApplyDirListPatches(&dirListPatchesp, dsp->tidPath, dsp->relPath, userp, &req);
! lock_ObtainMutex(&scp->mx);
if ((dsp->flags & SMB_DIRSEARCH_BULKST) &&
LargeIntegerGreaterThanOrEqualTo(thyper,
scp->bulkStatProgress)) {
--- 4429,4435 ----
*/
if (starPattern) {
smb_ApplyDirListPatches(&dirListPatchesp, dsp->tidPath, dsp->relPath, userp, &req);
! lock_ObtainWrite(&scp->rw);
if ((dsp->flags & SMB_DIRSEARCH_BULKST) &&
LargeIntegerGreaterThanOrEqualTo(thyper,
scp->bulkStatProgress)) {
***************
*** 4431,4437 ****
code = cm_TryBulkStat(scp, &thyper, userp, &req);
}
} else {
! lock_ObtainMutex(&scp->mx);
}
lock_ReleaseMutex(&dsp->mx);
if (code) {
--- 4444,4450 ----
code = cm_TryBulkStat(scp, &thyper, userp, &req);
}
} else {
! lock_ObtainWrite(&scp->rw);
}
lock_ReleaseMutex(&dsp->mx);
if (code) {
***************
*** 4623,4629 ****
} /* while copying data for dir listing */
/* release the mutex */
! lock_ReleaseMutex(&scp->mx);
if (bufferp) {
buf_Release(bufferp);
bufferp = NULL;
--- 4636,4642 ----
} /* while copying data for dir listing */
/* release the mutex */
! lock_ReleaseWrite(&scp->rw);
if (bufferp) {
buf_Release(bufferp);
bufferp = NULL;
***************
*** 4730,4741 ****
#endif /* DFS_SUPPORT */
/* now lock the vnode with a callback; returns with newScp locked */
! lock_ObtainMutex(&newScp->mx);
code = cm_SyncOp(newScp, NULL, userp, &req, PRSFS_LOOKUP,
CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
if (code != CM_ERROR_NOACCESS) {
! lock_ReleaseMutex(&newScp->mx);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
return code;
--- 4743,4754 ----
#endif /* DFS_SUPPORT */
/* now lock the vnode with a callback; returns with newScp locked */
! lock_ObtainWrite(&newScp->rw);
code = cm_SyncOp(newScp, NULL, userp, &req, PRSFS_LOOKUP,
CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
if (code != CM_ERROR_NOACCESS) {
! lock_ReleaseWrite(&newScp->rw);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
return code;
***************
*** 4749,4755 ****
if (!(attrs & SMB_ATTR_DIRECTORY))
code = CM_ERROR_NOTDIR;
! lock_ReleaseMutex(&newScp->mx);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
--- 4762,4768 ----
if (!(attrs & SMB_ATTR_DIRECTORY))
code = CM_ERROR_NOTDIR;
! lock_ReleaseWrite(&newScp->rw);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
***************
*** 4821,4831 ****
* need the current status to determine what the new status is, in some
* cases.
*/
! lock_ObtainMutex(&newScp->mx);
code = cm_SyncOp(newScp, NULL, userp, &req, 0,
CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
! lock_ReleaseMutex(&newScp->mx);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
return code;
--- 4834,4844 ----
* need the current status to determine what the new status is, in some
* cases.
*/
! lock_ObtainWrite(&newScp->rw);
code = cm_SyncOp(newScp, NULL, userp, &req, 0,
CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
! lock_ReleaseWrite(&newScp->rw);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
return code;
***************
*** 4835,4841 ****
/* Check for RO volume */
if (newScp->flags & CM_SCACHEFLAG_RO) {
! lock_ReleaseMutex(&newScp->mx);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
return CM_ERROR_READONLY;
--- 4848,4854 ----
/* Check for RO volume */
if (newScp->flags & CM_SCACHEFLAG_RO) {
! lock_ReleaseWrite(&newScp->rw);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
return CM_ERROR_READONLY;
***************
*** 4857,4863 ****
attr.unixModeBits = newScp->unixModeBits | 0222;
attr.mask |= CM_ATTRMASK_UNIXMODEBITS;
}
! lock_ReleaseMutex(&newScp->mx);
/* now call setattr */
if (attr.mask)
--- 4870,4876 ----
attr.unixModeBits = newScp->unixModeBits | 0222;
attr.mask |= CM_ATTRMASK_UNIXMODEBITS;
}
! lock_ReleaseWrite(&newScp->rw);
/* now call setattr */
if (attr.mask)
***************
*** 4988,4998 ****
#endif /* DFS_SUPPORT */
/* now lock the vnode with a callback; returns with newScp locked */
! lock_ObtainMutex(&newScp->mx);
code = cm_SyncOp(newScp, NULL, userp, &req, 0,
CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
! lock_ReleaseMutex(&newScp->mx);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
return code;
--- 5001,5011 ----
#endif /* DFS_SUPPORT */
/* now lock the vnode with a callback; returns with newScp locked */
! lock_ObtainWrite(&newScp->rw);
code = cm_SyncOp(newScp, NULL, userp, &req, 0,
CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
! lock_ReleaseWrite(&newScp->rw);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
return code;
***************
*** 5029,5035 ****
smb_SetSMBParm(outp, 8, 0);
smb_SetSMBParm(outp, 9, 0);
smb_SetSMBDataLength(outp, 0);
! lock_ReleaseMutex(&newScp->mx);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
--- 5042,5048 ----
smb_SetSMBParm(outp, 8, 0);
smb_SetSMBParm(outp, 9, 0);
smb_SetSMBDataLength(outp, 0);
! lock_ReleaseWrite(&newScp->rw);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
***************
*** 5166,5174 ****
/* save a pointer to the vnode */
fidp->scp = scp;
osi_Log2(smb_logp,"smb_ReceiveCoreOpen fidp 0x%p scp 0x%p", fidp, scp);
! lock_ObtainMutex(&scp->mx);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
! lock_ReleaseMutex(&scp->mx);
/* and the user */
cm_HoldUser(userp);
--- 5179,5187 ----
/* save a pointer to the vnode */
fidp->scp = scp;
osi_Log2(smb_logp,"smb_ReceiveCoreOpen fidp 0x%p scp 0x%p", fidp, scp);
! lock_ObtainWrite(&scp->rw);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
! lock_ReleaseWrite(&scp->rw);
/* and the user */
cm_HoldUser(userp);
***************
*** 5183,5189 ****
fidp->flags |= (SMB_FID_OPENREAD_LISTDIR | SMB_FID_OPENWRITE);
lock_ReleaseMutex(&fidp->mx);
! lock_ObtainMutex(&scp->mx);
smb_SetSMBParm(outp, 0, fidp->fid);
smb_SetSMBParm(outp, 1, smb_Attributes(scp));
smb_DosUTimeFromUnixTime(&dosTime, scp->clientModTime);
--- 5196,5202 ----
fidp->flags |= (SMB_FID_OPENREAD_LISTDIR | SMB_FID_OPENWRITE);
lock_ReleaseMutex(&fidp->mx);
! lock_ObtainRead(&scp->rw);
smb_SetSMBParm(outp, 0, fidp->fid);
smb_SetSMBParm(outp, 1, smb_Attributes(scp));
smb_DosUTimeFromUnixTime(&dosTime, scp->clientModTime);
***************
*** 5194,5200 ****
/* pass the open mode back; XXXX add access checks */
smb_SetSMBParm(outp, 6, (share & 0xf));
smb_SetSMBDataLength(outp, 0);
! lock_ReleaseMutex(&scp->mx);
/* notify open */
cm_Open(scp, 0, userp);
--- 5207,5213 ----
/* pass the open mode back; XXXX add access checks */
smb_SetSMBParm(outp, 6, (share & 0xf));
smb_SetSMBDataLength(outp, 0);
! lock_ReleaseRead(&scp->rw);
/* notify open */
cm_Open(scp, 0, userp);
***************
*** 6000,6006 ****
userp = smb_GetUserFromVCP(vcp, inp);
lock_ObtainMutex(&fidp->mx);
! if (fidp->flags & SMB_FID_OPENWRITE) {
cm_scache_t * scp = fidp->scp;
cm_HoldSCache(scp);
lock_ReleaseMutex(&fidp->mx);
--- 6013,6019 ----
userp = smb_GetUserFromVCP(vcp, inp);
lock_ObtainMutex(&fidp->mx);
! if ((fidp->flags & SMB_FID_OPENWRITE) && smb_AsyncStore != 2) {
cm_scache_t * scp = fidp->scp;
cm_HoldSCache(scp);
lock_ReleaseMutex(&fidp->mx);
***************
*** 6135,6143 ****
CompensateForSmbClientLastWriteTimeBugs(&dosTime);
smb_UnixTimeFromDosUTime(&fidp->scp->clientModTime, dosTime);
}
! lock_ReleaseMutex(&fidp->mx);
! code = cm_FSync(scp, userp, &req);
! lock_ObtainMutex(&fidp->mx);
}
else
code = 0;
--- 6148,6158 ----
CompensateForSmbClientLastWriteTimeBugs(&dosTime);
smb_UnixTimeFromDosUTime(&fidp->scp->clientModTime, dosTime);
}
! if (smb_AsyncStore != 2) {
! lock_ReleaseMutex(&fidp->mx);
! code = cm_FSync(scp, userp, &req);
! lock_ObtainMutex(&fidp->mx);
! }
}
else
code = 0;
***************
*** 6153,6159 ****
/* CM_UNLOCK_BY_FID doesn't look at the process ID. We pass
in zero. */
key = cm_GenerateKey(vcp->vcID, 0, fidp->fid);
! lock_ObtainMutex(&scp->mx);
tcode = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK
--- 6168,6174 ----
/* CM_UNLOCK_BY_FID doesn't look at the process ID. We pass
in zero. */
key = cm_GenerateKey(vcp->vcID, 0, fidp->fid);
! lock_ObtainWrite(&scp->rw);
tcode = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK
***************
*** 6172,6178 ****
post_syncopdone:
! lock_ReleaseMutex(&scp->mx);
lock_ObtainMutex(&fidp->mx);
}
--- 6187,6193 ----
post_syncopdone:
! lock_ReleaseWrite(&scp->rw);
lock_ObtainMutex(&fidp->mx);
}
***************
*** 6245,6264 ****
if (delscp) {
if (deleted) {
! lock_ObtainMutex(&delscp->mx);
if (deleted)
delscp->flags |= CM_SCACHEFLAG_DELETED;
! lock_ReleaseMutex(&delscp->mx);
}
cm_ReleaseSCache(delscp);
}
if (scp) {
! lock_ObtainMutex(&scp->mx);
if (nullcreator && scp->creator == userp)
scp->creator = NULL;
scp->flags &= ~CM_SCACHEFLAG_SMB_FID;
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
}
--- 6260,6279 ----
if (delscp) {
if (deleted) {
! lock_ObtainWrite(&delscp->rw);
if (deleted)
delscp->flags |= CM_SCACHEFLAG_DELETED;
! lock_ReleaseWrite(&delscp->rw);
}
cm_ReleaseSCache(delscp);
}
if (scp) {
! lock_ObtainWrite(&scp->rw);
if (nullcreator && scp->creator == userp)
scp->creator = NULL;
scp->flags &= ~CM_SCACHEFLAG_SMB_FID;
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
}
***************
*** 6300,6309 ****
* smb_ReadData -- common code for Read, Read And X, and Raw Read
*/
#ifndef DJGPP
! long smb_ReadData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
cm_user_t *userp, long *readp)
#else /* DJGPP */
! long smb_ReadData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
cm_user_t *userp, long *readp, int dosflag)
#endif /* !DJGPP */
{
--- 6315,6324 ----
* smb_ReadData -- common code for Read, Read And X, and Raw Read
*/
#ifndef DJGPP
! long smb_ReadData(smb_fid_t *fidp, osi_hyper_t *offsetp, afs_uint32 count, char *op,
cm_user_t *userp, long *readp)
#else /* DJGPP */
! long smb_ReadData(smb_fid_t *fidp, osi_hyper_t *offsetp, afs_uint32 count, char *op,
cm_user_t *userp, long *readp, int dosflag)
#endif /* !DJGPP */
{
***************
*** 6315,6334 ****
osi_hyper_t thyper;
osi_hyper_t lastByte;
osi_hyper_t bufferOffset;
! long bufIndex, nbytes;
int chunk;
int sequential = (fidp->flags & SMB_FID_SEQUENTIAL);
cm_req_t req;
cm_InitReq(&req);
bufferp = NULL;
offset = *offsetp;
- lock_ObtainMutex(&fidp->mx);
scp = fidp->scp;
cm_HoldSCache(scp);
! lock_ObtainMutex(&scp->mx);
if (offset.HighPart == 0) {
chunk = offset.LowPart >> cm_logChunkSize;
--- 6330,6364 ----
osi_hyper_t thyper;
osi_hyper_t lastByte;
osi_hyper_t bufferOffset;
! long bufIndex;
! afs_uint32 nbytes;
int chunk;
int sequential = (fidp->flags & SMB_FID_SEQUENTIAL);
cm_req_t req;
+ osi_Log3(smb_logp, "smb_ReadData fid %d, off 0x%x, size 0x%x",
+ fidp->fid, offsetp->LowPart, count);
+
+ *readp = 0;
+
+ lock_ObtainMutex(&fidp->mx);
+ /* make sure we have a readable FD */
+ if (!(fidp->flags & SMB_FID_OPENREAD_LISTDIR)) {
+ osi_Log2(smb_logp, "smb_ReadData fid %d not OPENREAD_LISTDIR flags 0x%x",
+ fidp->fid, fidp->flags);
+ lock_ReleaseMutex(&fidp->mx);
+ code = CM_ERROR_BADFDOP;
+ goto done2;
+ }
+
cm_InitReq(&req);
bufferp = NULL;
offset = *offsetp;
scp = fidp->scp;
cm_HoldSCache(scp);
! lock_ObtainWrite(&scp->rw);
if (offset.HighPart == 0) {
chunk = offset.LowPart >> cm_logChunkSize;
***************
*** 6388,6398 ****
buf_Release(bufferp);
bufferp = NULL;
}
! lock_ReleaseMutex(&scp->mx);
code = buf_Get(scp, &thyper, &bufferp);
! lock_ObtainMutex(&scp->mx);
if (code) goto done;
bufferOffset = thyper;
--- 6418,6428 ----
buf_Release(bufferp);
bufferp = NULL;
}
! lock_ReleaseWrite(&scp->rw);
code = buf_Get(scp, &thyper, &bufferp);
! lock_ObtainWrite(&scp->rw);
if (code) goto done;
bufferOffset = thyper;
***************
*** 6445,6451 ****
} /* while 1 */
done:
! lock_ReleaseMutex(&scp->mx);
if (bufferp)
buf_Release(bufferp);
--- 6475,6481 ----
} /* while 1 */
done:
! lock_ReleaseWrite(&scp->rw);
if (bufferp)
buf_Release(bufferp);
***************
*** 6454,6459 ****
--- 6484,6492 ----
cm_ReleaseSCache(scp);
+ done2:
+ osi_Log3(smb_logp, "smb_ReadData fid %d returns 0x%x read %d bytes",
+ fidp->fid, code, *readp);
return code;
}
***************
*** 6461,6477 ****
* smb_WriteData -- common code for Write and Raw Write
*/
#ifndef DJGPP
! long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
cm_user_t *userp, long *writtenp)
#else /* DJGPP */
! long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
cm_user_t *userp, long *writtenp, int dosflag)
#endif /* !DJGPP */
{
osi_hyper_t offset = *offsetp;
long code = 0;
long written = 0;
! cm_scache_t *scp;
osi_hyper_t fileLength; /* file's length at start of write */
osi_hyper_t minLength; /* don't read past this */
afs_uint32 nbytes; /* # of bytes to transfer this iteration */
--- 6494,6510 ----
* smb_WriteData -- common code for Write and Raw Write
*/
#ifndef DJGPP
! long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, afs_uint32 count, char *op,
cm_user_t *userp, long *writtenp)
#else /* DJGPP */
! long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, afs_uint32 count, char *op,
cm_user_t *userp, long *writtenp, int dosflag)
#endif /* !DJGPP */
{
osi_hyper_t offset = *offsetp;
long code = 0;
long written = 0;
! cm_scache_t *scp = NULL;
osi_hyper_t fileLength; /* file's length at start of write */
osi_hyper_t minLength; /* don't read past this */
afs_uint32 nbytes; /* # of bytes to transfer this iteration */
***************
*** 6489,6496 ****
*writtenp = 0;
- cm_InitReq(&req);
-
lock_ObtainMutex(&fidp->mx);
/* make sure we have a writable FD */
if (!(fidp->flags & SMB_FID_OPENWRITE)) {
--- 6522,6527 ----
***************
*** 6498,6511 ****
fidp->fid, fidp->flags);
lock_ReleaseMutex(&fidp->mx);
code = CM_ERROR_BADFDOP;
! goto done;
}
scp = fidp->scp;
cm_HoldSCache(scp);
lock_ReleaseMutex(&fidp->mx);
! lock_ObtainMutex(&scp->mx);
/* start by looking up the file's end */
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK
--- 6529,6544 ----
fidp->fid, fidp->flags);
lock_ReleaseMutex(&fidp->mx);
code = CM_ERROR_BADFDOP;
! goto done2;
}
+ cm_InitReq(&req);
+
scp = fidp->scp;
cm_HoldSCache(scp);
lock_ReleaseMutex(&fidp->mx);
! lock_ObtainWrite(&scp->rw);
/* start by looking up the file's end */
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK
***************
*** 6545,6553 ****
* based upon cm_chunkSize but we desire cm_chunkSize to be large
* so that we can read larger amounts of data at a time.
*/
! if (smb_AsyncStore &&
! (thyper.LowPart & ~(cm_data.buf_blockSize-1)) !=
! (offset.LowPart & ~(cm_data.buf_blockSize-1))) {
/* they're different */
doWriteBack = 1;
writeBackOffset.HighPart = offset.HighPart;
--- 6578,6586 ----
* based upon cm_chunkSize but we desire cm_chunkSize to be large
* so that we can read larger amounts of data at a time.
*/
! if (smb_AsyncStore == 1 &&
! (thyper.LowPart & ~(smb_AsyncStoreSize-1)) !=
! (offset.LowPart & ~(smb_AsyncStoreSize-1))) {
/* they're different */
doWriteBack = 1;
writeBackOffset.HighPart = offset.HighPart;
***************
*** 6580,6591 ****
buf_Release(bufferp);
bufferp = NULL;
}
! lock_ReleaseMutex(&scp->mx);
code = buf_Get(scp, &thyper, &bufferp);
lock_ObtainMutex(&bufferp->mx);
! lock_ObtainMutex(&scp->mx);
if (code) goto done;
bufferOffset = thyper;
--- 6613,6624 ----
buf_Release(bufferp);
bufferp = NULL;
}
! lock_ReleaseWrite(&scp->rw);
code = buf_Get(scp, &thyper, &bufferp);
lock_ObtainMutex(&bufferp->mx);
! lock_ObtainWrite(&scp->rw);
if (code) goto done;
bufferOffset = thyper;
***************
*** 6624,6630 ****
ConvertLongToLargeInteger(count)),
minLength))) {
if (count < cm_data.buf_blockSize
! && bufferp->dataVersion == -1)
memset(bufferp->datap, 0,
cm_data.buf_blockSize);
bufferp->dataVersion = scp->dataVersion;
--- 6657,6663 ----
ConvertLongToLargeInteger(count)),
minLength))) {
if (count < cm_data.buf_blockSize
! && bufferp->dataVersion == CM_BUF_VERSION_BAD)
memset(bufferp->datap, 0,
cm_data.buf_blockSize);
bufferp->dataVersion = scp->dataVersion;
***************
*** 6636,6644 ****
lock_ReleaseMutex(&bufferp->mx);
code = cm_GetBuffer(scp, bufferp, NULL, userp,
&req);
! lock_ReleaseMutex(&scp->mx);
lock_ObtainMutex(&bufferp->mx);
! lock_ObtainMutex(&scp->mx);
if (code) break;
}
if (code) {
--- 6669,6677 ----
lock_ReleaseMutex(&bufferp->mx);
code = cm_GetBuffer(scp, bufferp, NULL, userp,
&req);
! lock_ReleaseWrite(&scp->rw);
lock_ObtainMutex(&bufferp->mx);
! lock_ObtainWrite(&scp->rw);
if (code) break;
}
if (code) {
***************
*** 6686,6692 ****
} /* while 1 */
done:
! lock_ReleaseMutex(&scp->mx);
if (bufferp) {
lock_ReleaseMutex(&bufferp->mx);
--- 6719,6725 ----
} /* while 1 */
done:
! lock_ReleaseWrite(&scp->rw);
if (bufferp) {
lock_ReleaseMutex(&bufferp->mx);
***************
*** 6703,6722 ****
lock_ReleaseMutex(&fidp->mx);
if (code == 0) {
! if (smb_AsyncStore) {
if (doWriteBack) {
long code2;
! lock_ObtainMutex(&scp->mx);
osi_Log1(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE",
fidp->fid);
code2 = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE);
osi_Log2(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE returns 0x%x",
fidp->fid, code2);
! lock_ReleaseMutex(&scp->mx);
cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart,
writeBackOffset.HighPart,
! *writtenp & ~(cm_data.blockSize-1), 0, userp);
/* cm_SyncOpDone is called at the completion of cm_BkgStore */
}
} else {
--- 6736,6755 ----
lock_ReleaseMutex(&fidp->mx);
if (code == 0) {
! if (smb_AsyncStore > 0) {
if (doWriteBack) {
long code2;
! lock_ObtainWrite(&scp->rw);
osi_Log1(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE",
fidp->fid);
code2 = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE);
osi_Log2(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE returns 0x%x",
fidp->fid, code2);
! lock_ReleaseWrite(&scp->rw);
cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart,
writeBackOffset.HighPart,
! smb_AsyncStoreSize, 0, userp);
/* cm_SyncOpDone is called at the completion of cm_BkgStore */
}
} else {
***************
*** 6726,6731 ****
--- 6759,6765 ----
cm_ReleaseSCache(scp);
+ done2:
osi_Log3(smb_logp, "smb_WriteData fid %d returns 0x%x written %d bytes",
fidp->fid, code, *writtenp);
return code;
***************
*** 6740,6745 ****
--- 6774,6780 ----
long written = 0, total_written = 0;
unsigned pid;
smb_fid_t *fidp;
+ smb_t* smbp = (smb_t*) inp;
long code = 0;
cm_user_t *userp;
cm_attr_t truncAttr; /* attribute struct used for truncating file */
***************
*** 6787,6793 ****
LARGE_INTEGER LOffset;
LARGE_INTEGER LLength;
! pid = ((smb_t *) inp)->pid;
key = cm_GenerateKey(vcp->vcID, pid, fd);
LOffset.HighPart = offset.HighPart;
--- 6822,6828 ----
LARGE_INTEGER LOffset;
LARGE_INTEGER LLength;
! pid = smbp->pid;
key = cm_GenerateKey(vcp->vcID, pid, fd);
LOffset.HighPart = offset.HighPart;
***************
*** 6795,6803 ****
LLength.HighPart = 0;
LLength.LowPart = count;
! lock_ObtainMutex(&fidp->scp->mx);
code = cm_LockCheckWrite(fidp->scp, LOffset, LLength, key);
! lock_ReleaseMutex(&fidp->scp->mx);
if (code) {
osi_Log1(smb_logp, "smb_ReceiveCoreWrite lock check failure 0x%x", code);
--- 6830,6838 ----
LLength.HighPart = 0;
LLength.LowPart = count;
! lock_ObtainWrite(&fidp->scp->rw);
code = cm_LockCheckWrite(fidp->scp, LOffset, LLength, key);
! lock_ReleaseWrite(&fidp->scp->rw);
if (code) {
osi_Log1(smb_logp, "smb_ReceiveCoreWrite lock check failure 0x%x", code);
***************
*** 6961,6966 ****
--- 6996,7002 ----
long totalCount;
unsigned short fd;
smb_fid_t *fidp;
+ smb_t *smbp = (smb_t*) inp;
long code = 0;
cm_user_t *userp;
char *op;
***************
*** 7031,7037 ****
LARGE_INTEGER LOffset;
LARGE_INTEGER LLength;
! pid = ((smb_t *) inp)->pid;
key = cm_GenerateKey(vcp->vcID, pid, fd);
LOffset.HighPart = offset.HighPart;
--- 7067,7073 ----
LARGE_INTEGER LOffset;
LARGE_INTEGER LLength;
! pid = smbp->pid;
key = cm_GenerateKey(vcp->vcID, pid, fd);
LOffset.HighPart = offset.HighPart;
***************
*** 7039,7047 ****
LLength.HighPart = 0;
LLength.LowPart = count;
! lock_ObtainMutex(&fidp->scp->mx);
code = cm_LockCheckWrite(fidp->scp, LOffset, LLength, key);
! lock_ReleaseMutex(&fidp->scp->mx);
if (code) {
smb_ReleaseFID(fidp);
--- 7075,7083 ----
LLength.HighPart = 0;
LLength.LowPart = count;
! lock_ObtainWrite(&fidp->scp->rw);
code = cm_LockCheckWrite(fidp->scp, LOffset, LLength, key);
! lock_ReleaseWrite(&fidp->scp->rw);
if (code) {
smb_ReleaseFID(fidp);
***************
*** 7151,7156 ****
--- 7187,7193 ----
unsigned short fd;
unsigned pid;
smb_fid_t *fidp;
+ smb_t *smbp = (smb_t*) inp;
long code = 0;
cm_user_t *userp;
char *op;
***************
*** 7187,7193 ****
LARGE_INTEGER LOffset, LLength;
cm_key_t key;
! pid = ((smb_t *) inp)->pid;
key = cm_GenerateKey(vcp->vcID, pid, fd);
LOffset.HighPart = 0;
--- 7224,7230 ----
LARGE_INTEGER LOffset, LLength;
cm_key_t key;
! pid = smbp->pid;
key = cm_GenerateKey(vcp->vcID, pid, fd);
LOffset.HighPart = 0;
***************
*** 7195,7203 ****
LLength.HighPart = 0;
LLength.LowPart = count;
! lock_ObtainMutex(&fidp->scp->mx);
code = cm_LockCheckRead(fidp->scp, LOffset, LLength, key);
! lock_ReleaseMutex(&fidp->scp->mx);
}
if (code) {
smb_ReleaseFID(fidp);
--- 7232,7240 ----
LLength.HighPart = 0;
LLength.LowPart = count;
! lock_ObtainWrite(&fidp->scp->rw);
code = cm_LockCheckRead(fidp->scp, LOffset, LLength, key);
! lock_ReleaseWrite(&fidp->scp->rw);
}
if (code) {
smb_ReleaseFID(fidp);
***************
*** 7543,7551 ****
/* save a pointer to the vnode */
fidp->scp = scp;
! lock_ObtainMutex(&scp->mx);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
! lock_ReleaseMutex(&scp->mx);
/* and the user */
fidp->userp = userp;
--- 7580,7588 ----
/* save a pointer to the vnode */
fidp->scp = scp;
! lock_ObtainWrite(&scp->rw);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
! lock_ReleaseWrite(&scp->rw);
/* and the user */
fidp->userp = userp;
***************
*** 7606,7612 ****
scp = fidp->scp;
cm_HoldSCache(scp);
lock_ReleaseMutex(&fidp->mx);
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code == 0) {
--- 7643,7649 ----
scp = fidp->scp;
cm_HoldSCache(scp);
lock_ReleaseMutex(&fidp->mx);
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code == 0) {
***************
*** 7629,7635 ****
smb_SetSMBParm(outp, 1, (new_offset.LowPart>>16) & 0xffff);
smb_SetSMBDataLength(outp, 0);
}
! lock_ReleaseMutex(&scp->mx);
smb_ReleaseFID(fidp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
--- 7666,7672 ----
smb_SetSMBParm(outp, 1, (new_offset.LowPart>>16) & 0xffff);
smb_SetSMBDataLength(outp, 0);
}
! lock_ReleaseWrite(&scp->rw);
smb_ReleaseFID(fidp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
***************
*** 8406,8412 ****
{
struct smb_packet *bufp;
EVENT_HANDLE retHandle;
! int i;
char eventName[MAX_PATH];
osi_assertx( idx < (sizeof(NCBs) / sizeof(NCBs[0])), "invalid index" );
--- 8443,8449 ----
{
struct smb_packet *bufp;
EVENT_HANDLE retHandle;
! afs_uint32 i;
char eventName[MAX_PATH];
osi_assertx( idx < (sizeof(NCBs) / sizeof(NCBs[0])), "invalid index" );
***************
*** 8440,8446 ****
long code = 0;
long len;
long i;
! int session, thread;
smb_vc_t *vcp = NULL;
int flags = 0;
char rname[NCBNAMSZ+1];
--- 8477,8483 ----
long code = 0;
long len;
long i;
! afs_uint32 session, thread;
smb_vc_t *vcp = NULL;
int flags = 0;
char rname[NCBNAMSZ+1];
***************
*** 9632,9638 ****
dos_ptr dos_ncb;
#endif
long code = 0;
! int i;
smb_vc_t *vcp;
/*fprintf(stderr, "Entering smb_Shutdown\n");*/
--- 9669,9675 ----
dos_ptr dos_ncb;
#endif
long code = 0;
! afs_uint32 i;
smb_vc_t *vcp;
/*fprintf(stderr, "Entering smb_Shutdown\n");*/
***************
*** 9729,9737 ****
if (fidp->scp != NULL) {
scp = fidp->scp;
fidp->scp = NULL;
! lock_ObtainMutex(&scp->mx);
scp->flags &= ~CM_SCACHEFLAG_SMB_FID;
! lock_ReleaseMutex(&scp->mx);
osi_Log2(smb_logp,"smb_Shutdown fidp 0x%p scp 0x%p", fidp, scp);
cm_ReleaseSCache(scp);
}
--- 9766,9774 ----
if (fidp->scp != NULL) {
scp = fidp->scp;
fidp->scp = NULL;
! lock_ObtainWrite(&scp->rw);
scp->flags &= ~CM_SCACHEFLAG_SMB_FID;
! lock_ReleaseWrite(&scp->rw);
osi_Log2(smb_logp,"smb_Shutdown fidp 0x%p scp 0x%p", fidp, scp);
cm_ReleaseSCache(scp);
}
Index: openafs/src/WINNT/afsd/smb.h
diff -c openafs/src/WINNT/afsd/smb.h:1.41.2.26 openafs/src/WINNT/afsd/smb.h:1.41.2.27
*** openafs/src/WINNT/afsd/smb.h:1.41.2.26 Mon Feb 25 00:36:47 2008
--- openafs/src/WINNT/afsd/smb.h Thu Feb 28 12:17:16 2008
***************
*** 495,503 ****
int state;
} smb_waitingLock_t;
! #define SMB_WAITINGLOCKSTATE_WAITING 0
! #define SMB_WAITINGLOCKSTATE_DONE 1
! #define SMB_WAITINGLOCKSTATE_ERROR 2
/* waiting lock request */
typedef struct smb_waitingLockRequest {
--- 495,504 ----
int state;
} smb_waitingLock_t;
! #define SMB_WAITINGLOCKSTATE_WAITING 0
! #define SMB_WAITINGLOCKSTATE_DONE 1
! #define SMB_WAITINGLOCKSTATE_ERROR 2
! #define SMB_WAITINGLOCKSTATE_CANCELLED 3
/* waiting lock request */
typedef struct smb_waitingLockRequest {
***************
*** 507,513 ****
smb_packet_t *inp;
smb_packet_t *outp;
int lockType;
! time_t timeRemaining;
smb_waitingLock_t * locks;
} smb_waitingLockRequest_t;
--- 508,515 ----
smb_packet_t *inp;
smb_packet_t *outp;
int lockType;
! time_t start_t; /* osi_Time */
! afs_uint32 msTimeout; /* msecs, 0xFFFFFFFF = wait forever */
smb_waitingLock_t * locks;
} smb_waitingLockRequest_t;
***************
*** 729,746 ****
extern int smb_SUser(cm_user_t *userp);
#ifndef DJGPP
! long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
cm_user_t *userp, long *writtenp);
#else /* DJGPP */
! long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
cm_user_t *userp, long *writtenp, int dosflag);
#endif /* !DJGPP */
#ifndef DJGPP
! extern long smb_ReadData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count,
char *op, cm_user_t *userp, long *readp);
#else /* DJGPP */
! extern long smb_ReadData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count,
char *op, cm_user_t *userp, long *readp, int dosflag);
#endif /* !DJGPP */
--- 731,748 ----
extern int smb_SUser(cm_user_t *userp);
#ifndef DJGPP
! long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, afs_uint32 count, char *op,
cm_user_t *userp, long *writtenp);
#else /* DJGPP */
! long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, afs_uint32 count, char *op,
cm_user_t *userp, long *writtenp, int dosflag);
#endif /* !DJGPP */
#ifndef DJGPP
! extern long smb_ReadData(smb_fid_t *fidp, osi_hyper_t *offsetp, afs_uint32 count,
char *op, cm_user_t *userp, long *readp);
#else /* DJGPP */
! extern long smb_ReadData(smb_fid_t *fidp, osi_hyper_t *offsetp, afs_uint32 count,
char *op, cm_user_t *userp, long *readp, int dosflag);
#endif /* !DJGPP */
Index: openafs/src/WINNT/afsd/smb3.c
diff -c openafs/src/WINNT/afsd/smb3.c:1.95.2.55 openafs/src/WINNT/afsd/smb3.c:1.95.2.58
*** openafs/src/WINNT/afsd/smb3.c:1.95.2.55 Fri Feb 22 19:17:35 2008
--- openafs/src/WINNT/afsd/smb3.c Sun Mar 9 11:25:02 2008
***************
*** 75,84 ****
if ( smb_ExecutableExtensions == NULL || name == NULL)
return 0;
! len = strlen(name);
for ( i=0; smb_ExecutableExtensions[i]; i++) {
! j = len - strlen(smb_ExecutableExtensions[i]);
if (_stricmp(smb_ExecutableExtensions[i], &name[j]) == 0)
return 1;
}
--- 75,84 ----
if ( smb_ExecutableExtensions == NULL || name == NULL)
return 0;
! len = (int)strlen(name);
for ( i=0; smb_ExecutableExtensions[i]; i++) {
! j = len - (int)strlen(smb_ExecutableExtensions[i]);
if (_stricmp(smb_ExecutableExtensions[i], &name[j]) == 0)
return 1;
}
***************
*** 2421,2429 ****
/* save a pointer to the vnode */
osi_Log2(smb_logp,"smb_ReceiveTran2Open fidp 0x%p scp 0x%p", fidp, scp);
fidp->scp = scp;
! lock_ObtainMutex(&scp->mx);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
! lock_ReleaseMutex(&scp->mx);
/* and the user */
fidp->userp = userp;
--- 2421,2429 ----
/* save a pointer to the vnode */
osi_Log2(smb_logp,"smb_ReceiveTran2Open fidp 0x%p scp 0x%p", fidp, scp);
fidp->scp = scp;
! lock_ObtainWrite(&scp->rw);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
! lock_ReleaseWrite(&scp->rw);
/* and the user */
fidp->userp = userp;
***************
*** 2447,2453 ****
/* copy out remainder of the parms */
parmSlot = 0;
outp->parmsp[parmSlot++] = fidp->fid;
! lock_ObtainMutex(&scp->mx);
if (extraInfo) {
outp->parmsp[parmSlot++] = smb_Attributes(scp);
smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
--- 2447,2453 ----
/* copy out remainder of the parms */
parmSlot = 0;
outp->parmsp[parmSlot++] = fidp->fid;
! lock_ObtainRead(&scp->rw);
if (extraInfo) {
outp->parmsp[parmSlot++] = smb_Attributes(scp);
smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
***************
*** 2469,2475 ****
outp->parmsp[parmSlot++] = 0;
outp->parmsp[parmSlot++] = 0;
}
! lock_ReleaseMutex(&scp->mx);
outp->totalData = 0; /* total # of data bytes */
outp->totalParms = parmSlot * 2; /* shorts are two bytes */
--- 2469,2475 ----
outp->parmsp[parmSlot++] = 0;
outp->parmsp[parmSlot++] = 0;
}
! lock_ReleaseRead(&scp->rw);
outp->totalData = 0; /* total # of data bytes */
outp->totalParms = parmSlot * 2; /* shorts are two bytes */
***************
*** 2863,2869 ****
}
#endif /* DFS_SUPPORT */
! lock_ObtainMutex(&scp->mx);
scp_mx_held = 1;
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
--- 2863,2869 ----
}
#endif /* DFS_SUPPORT */
! lock_ObtainWrite(&scp->rw);
scp_mx_held = 1;
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
***************
*** 2871,2876 ****
--- 2871,2878 ----
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ lock_ConvertWToR(&scp->rw);
+
/* now we have the status in the cache entry, and everything is locked.
* Marshall the output data.
*/
***************
*** 2889,2895 ****
goto done;
}
else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) {
! len = strlen(lastComp);
qpi.u.QPfileNameInfo.fileNameLength = (len + 1) * 2;
mbstowcs((unsigned short *)qpi.u.QPfileNameInfo.fileName, lastComp, len + 1);
--- 2891,2897 ----
goto done;
}
else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) {
! len = (unsigned int)strlen(lastComp);
qpi.u.QPfileNameInfo.fileNameLength = (len + 1) * 2;
mbstowcs((unsigned short *)qpi.u.QPfileNameInfo.fileName, lastComp, len + 1);
***************
*** 2929,2935 ****
qpi.u.QPfileStandardInfo.reserved = 0;
if (fidp) {
! lock_ReleaseMutex(&scp->mx);
scp_mx_held = 0;
lock_ObtainMutex(&fidp->mx);
delonclose = fidp->flags & SMB_FID_DELONCLOSE;
--- 2931,2937 ----
qpi.u.QPfileStandardInfo.reserved = 0;
if (fidp) {
! lock_ReleaseRead(&scp->rw);
scp_mx_held = 0;
lock_ObtainMutex(&fidp->mx);
delonclose = fidp->flags & SMB_FID_DELONCLOSE;
***************
*** 2967,2973 ****
qpi.u.QPfileAllInfo.currentByteOffset.LowPart = 0;
qpi.u.QPfileAllInfo.mode = 0;
qpi.u.QPfileAllInfo.alignmentRequirement = 0;
! len = strlen(lastComp);
qpi.u.QPfileAllInfo.fileNameLength = (len + 1) * 2;
mbstowcs((unsigned short *)qpi.u.QPfileAllInfo.fileName, lastComp, len + 1);
}
--- 2969,2975 ----
qpi.u.QPfileAllInfo.currentByteOffset.LowPart = 0;
qpi.u.QPfileAllInfo.mode = 0;
qpi.u.QPfileAllInfo.alignmentRequirement = 0;
! len = (unsigned int)strlen(lastComp);
qpi.u.QPfileAllInfo.fileNameLength = (len + 1) * 2;
mbstowcs((unsigned short *)qpi.u.QPfileAllInfo.fileName, lastComp, len + 1);
}
***************
*** 2975,2981 ****
/* send and free the packets */
done:
if (scp_mx_held)
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
if (code == 0) {
--- 2977,2983 ----
/* send and free the packets */
done:
if (scp_mx_held)
! lock_ReleaseRead(&scp->rw);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
if (code == 0) {
***************
*** 3149,3167 ****
/* lock the vnode with a callback; we need the current status
* to determine what the new status is, in some cases.
*/
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_GETSTATUS
| CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
! lock_ReleaseMutex(&scp->mx);
goto done;
}
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
! lock_ReleaseMutex(&scp->mx);
lock_ObtainMutex(&fidp->mx);
! lock_ObtainMutex(&scp->mx);
/* prepare for setattr call */
attr.mask = CM_ATTRMASK_LENGTH;
--- 3151,3169 ----
/* lock the vnode with a callback; we need the current status
* to determine what the new status is, in some cases.
*/
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_GETSTATUS
| CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
! lock_ReleaseWrite(&scp->rw);
goto done;
}
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
! lock_ReleaseWrite(&scp->rw);
lock_ObtainMutex(&fidp->mx);
! lock_ObtainRead(&scp->rw);
/* prepare for setattr call */
attr.mask = CM_ATTRMASK_LENGTH;
***************
*** 3188,3194 ****
attr.unixModeBits = scp->unixModeBits | 0222;
}
}
! lock_ReleaseMutex(&scp->mx);
lock_ReleaseMutex(&fidp->mx);
/* call setattr */
--- 3190,3196 ----
attr.unixModeBits = scp->unixModeBits | 0222;
}
}
! lock_ReleaseRead(&scp->rw);
lock_ReleaseMutex(&fidp->mx);
/* call setattr */
***************
*** 3230,3235 ****
--- 3232,3238 ----
cm_scache_t *scp;
smb_tran2QFileInfo_t qfi;
long code = 0;
+ int readlock = 0;
cm_req_t req;
cm_InitReq(&req);
***************
*** 3288,3294 ****
osi_Log2(smb_logp,"smb_ReleaseTran2QFileInfo fidp 0x%p scp 0x%p", fidp, scp);
cm_HoldSCache(scp);
lock_ReleaseMutex(&fidp->mx);
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code)
--- 3291,3297 ----
osi_Log2(smb_logp,"smb_ReleaseTran2QFileInfo fidp 0x%p scp 0x%p", fidp, scp);
cm_HoldSCache(scp);
lock_ReleaseMutex(&fidp->mx);
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code)
***************
*** 3296,3301 ****
--- 3299,3307 ----
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ lock_ConvertWToR(&scp->rw);
+ readlock = 1;
+
/* now we have the status in the cache entry, and everything is locked.
* Marshall the output data.
*/
***************
*** 3325,3333 ****
unsigned long len;
char *name;
! lock_ReleaseMutex(&scp->mx);
lock_ObtainMutex(&fidp->mx);
! lock_ObtainMutex(&scp->mx);
if (fidp->NTopen_wholepathp)
name = fidp->NTopen_wholepathp;
else
--- 3331,3339 ----
unsigned long len;
char *name;
! lock_ReleaseRead(&scp->rw);
lock_ObtainMutex(&fidp->mx);
! lock_ObtainRead(&scp->rw);
if (fidp->NTopen_wholepathp)
name = fidp->NTopen_wholepathp;
else
***************
*** 3341,3347 ****
/* send and free the packets */
done:
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_ReleaseFID(fidp);
--- 3347,3356 ----
/* send and free the packets */
done:
! if (readlock)
! lock_ReleaseRead(&scp->rw);
! else
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_ReleaseFID(fidp);
***************
*** 3443,3462 ****
/* lock the vnode with a callback; we need the current status
* to determine what the new status is, in some cases.
*/
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_GETSTATUS
| CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
! lock_ReleaseMutex(&scp->mx);
goto done;
}
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
! lock_ReleaseMutex(&scp->mx);
lock_ObtainMutex(&fidp->mx);
! lock_ObtainMutex(&scp->mx);
/* prepare for setattr call */
attr.mask = 0;
--- 3452,3471 ----
/* lock the vnode with a callback; we need the current status
* to determine what the new status is, in some cases.
*/
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_GETSTATUS
| CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
! lock_ReleaseWrite(&scp->rw);
goto done;
}
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
! lock_ReleaseWrite(&scp->rw);
lock_ObtainMutex(&fidp->mx);
! lock_ObtainRead(&scp->rw);
/* prepare for setattr call */
attr.mask = 0;
***************
*** 3488,3494 ****
attr.unixModeBits = scp->unixModeBits | 0222;
}
}
! lock_ReleaseMutex(&scp->mx);
lock_ReleaseMutex(&fidp->mx);
/* call setattr */
--- 3497,3503 ----
attr.unixModeBits = scp->unixModeBits | 0222;
}
}
! lock_ReleaseRead(&scp->rw);
lock_ReleaseMutex(&fidp->mx);
/* call setattr */
***************
*** 3633,3640 ****
osi_Log2(smb_logp,"ReceiveTran2GetDfsReferral [%d][%s]",
maxReferralLevel, osi_LogSaveString(smb_logp, requestFileName));
! nbnLen = strlen(cm_NetbiosName);
! reqLen = strlen(requestFileName);
if (reqLen > nbnLen + 2 && requestFileName[0] == '\\' &&
!_strnicmp(cm_NetbiosName,&requestFileName[1],nbnLen) &&
--- 3642,3649 ----
osi_Log2(smb_logp,"ReceiveTran2GetDfsReferral [%d][%s]",
maxReferralLevel, osi_LogSaveString(smb_logp, requestFileName));
! nbnLen = (int)strlen(cm_NetbiosName);
! reqLen = (int)strlen(requestFileName);
if (reqLen > nbnLen + 2 && requestFileName[0] == '\\' &&
!_strnicmp(cm_NetbiosName,&requestFileName[1],nbnLen) &&
***************
*** 3711,3720 ****
/* scp should now be the DfsLink we are looking for */
if (scp) {
/* figure out how much of the input path was used */
! reqLen = nbnLen+2 + strlen(pathName) + 1 + strlen(lastComponent);
strcpy(referralPath, &scp->mountPointStringp[strlen("msdfs:")]);
! refLen = strlen(referralPath);
found = 1;
}
} else {
--- 3720,3729 ----
/* scp should now be the DfsLink we are looking for */
if (scp) {
/* figure out how much of the input path was used */
! reqLen = (int)(nbnLen+2 + strlen(pathName) + 1 + strlen(lastComponent));
strcpy(referralPath, &scp->mountPointStringp[strlen("msdfs:")]);
! refLen = (int)strlen(referralPath);
found = 1;
}
} else {
***************
*** 3798,3804 ****
return 0;
#else /* DFS_SUPPORT */
osi_Log0(smb_logp,"ReceiveTran2GetDfsReferral - NOT_SUPPORTED");
! return CM_ERROR_BADOP;
#endif /* DFS_SUPPORT */
}
--- 3807,3813 ----
return 0;
#else /* DFS_SUPPORT */
osi_Log0(smb_logp,"ReceiveTran2GetDfsReferral - NOT_SUPPORTED");
! return CM_ERROR_NOSUCHDEVICE;
#endif /* DFS_SUPPORT */
}
***************
*** 3843,3852 ****
if (code == 0 && !(rights & PRSFS_READ))
mustFake = 1;
else if (code == -1) {
! lock_ObtainMutex(&dscp->mx);
code = cm_SyncOp(dscp, NULL, userp, reqp, PRSFS_READ,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
! lock_ReleaseMutex(&dscp->mx);
if (code == CM_ERROR_NOACCESS) {
mustFake = 1;
code = 0;
--- 3852,3861 ----
if (code == 0 && !(rights & PRSFS_READ))
mustFake = 1;
else if (code == -1) {
! lock_ObtainWrite(&dscp->rw);
code = cm_SyncOp(dscp, NULL, userp, reqp, PRSFS_READ,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
! lock_ReleaseWrite(&dscp->rw);
if (code == CM_ERROR_NOACCESS) {
mustFake = 1;
code = 0;
***************
*** 3866,3877 ****
if (code)
continue;
! lock_ObtainMutex(&scp->mx);
if (mustFake == 0)
code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (mustFake || code) {
! lock_ReleaseMutex(&scp->mx);
dptr = patchp->dptr;
--- 3875,3886 ----
if (code)
continue;
! lock_ObtainWrite(&scp->rw);
if (mustFake == 0)
code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (mustFake || code) {
! lock_ReleaseWrite(&scp->rw);
dptr = patchp->dptr;
***************
*** 3985,3991 ****
/* now watch for a symlink */
code = 0;
while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) {
! lock_ReleaseMutex(&scp->mx);
snprintf(path, AFSPATHMAX, "%s\\%s", relPathp ? relPathp : "", patchp->dep->name);
reqp->relPathp = path;
reqp->tidPathp = tidPathp;
--- 3994,4000 ----
/* now watch for a symlink */
code = 0;
while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) {
! lock_ReleaseWrite(&scp->rw);
snprintf(path, AFSPATHMAX, "%s\\%s", relPathp ? relPathp : "", patchp->dep->name);
reqp->relPathp = path;
reqp->tidPathp = tidPathp;
***************
*** 4001,4009 ****
cm_ReleaseSCache(scp);
scp = targetScp;
}
! lock_ObtainMutex(&scp->mx);
}
dptr = patchp->dptr;
if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) {
--- 4010,4020 ----
cm_ReleaseSCache(scp);
scp = targetScp;
}
! lock_ObtainWrite(&scp->rw);
}
+ lock_ConvertWToR(&scp->rw);
+
dptr = patchp->dptr;
if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) {
***************
*** 4105,4111 ****
*dptr++ = (attr >> 8) & 0xff;
}
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
}
--- 4116,4122 ----
*dptr++ = (attr >> 8) & 0xff;
}
! lock_ReleaseRead(&scp->rw);
cm_ReleaseSCache(scp);
}
***************
*** 4536,4542 ****
ohbytes += 4; /* EASIZE */
/* add header to name & term. null */
! onbytes = strlen(maskp);
orbytes = ohbytes + onbytes + 1;
/* now, we round up the record to a 4 byte alignment, and we make
--- 4547,4553 ----
ohbytes += 4; /* EASIZE */
/* add header to name & term. null */
! onbytes = (int)strlen(maskp);
orbytes = ohbytes + onbytes + 1;
/* now, we round up the record to a 4 byte alignment, and we make
***************
*** 4924,4936 ****
* and so we do another hold now.
*/
cm_HoldSCache(scp);
! lock_ObtainMutex(&scp->mx);
if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 &&
LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) {
scp->flags |= CM_SCACHEFLAG_BULKSTATTING;
dsp->flags |= SMB_DIRSEARCH_BULKST;
}
! lock_ReleaseMutex(&scp->mx);
}
}
lock_ReleaseMutex(&dsp->mx);
--- 4935,4947 ----
* and so we do another hold now.
*/
cm_HoldSCache(scp);
! lock_ObtainWrite(&scp->rw);
if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 &&
LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) {
scp->flags |= CM_SCACHEFLAG_BULKSTATTING;
dsp->flags |= SMB_DIRSEARCH_BULKST;
}
! lock_ReleaseWrite(&scp->rw);
}
}
lock_ReleaseMutex(&dsp->mx);
***************
*** 4943,4953 ****
}
/* get the directory size */
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_FreeTran2Packet(outp);
--- 4954,4964 ----
}
/* get the directory size */
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_FreeTran2Packet(outp);
***************
*** 5029,5035 ****
buf_Release(bufferp);
bufferp = NULL;
}
! lock_ReleaseMutex(&scp->mx);
code = buf_Get(scp, &thyper, &bufferp);
lock_ObtainMutex(&dsp->mx);
--- 5040,5046 ----
buf_Release(bufferp);
bufferp = NULL;
}
! lock_ReleaseWrite(&scp->rw);
code = buf_Get(scp, &thyper, &bufferp);
lock_ObtainMutex(&dsp->mx);
***************
*** 5039,5045 ****
if (starPattern) {
code2 = smb_ApplyV3DirListPatches(scp, &dirListPatchesp, dsp->tidPath, dsp->relPath, infoLevel, userp, &req);
! lock_ObtainMutex(&scp->mx);
if ((dsp->flags & SMB_DIRSEARCH_BULKST) &&
LargeIntegerGreaterThanOrEqualTo(thyper, scp->bulkStatProgress)) {
/* Don't bulk stat if risking timeout */
--- 5050,5056 ----
if (starPattern) {
code2 = smb_ApplyV3DirListPatches(scp, &dirListPatchesp, dsp->tidPath, dsp->relPath, infoLevel, userp, &req);
! lock_ObtainWrite(&scp->rw);
if ((dsp->flags & SMB_DIRSEARCH_BULKST) &&
LargeIntegerGreaterThanOrEqualTo(thyper, scp->bulkStatProgress)) {
/* Don't bulk stat if risking timeout */
***************
*** 5052,5058 ****
code = cm_TryBulkStat(scp, &thyper, userp, &req);
}
} else {
! lock_ObtainMutex(&scp->mx);
}
lock_ReleaseMutex(&dsp->mx);
if (code) {
--- 5063,5069 ----
code = cm_TryBulkStat(scp, &thyper, userp, &req);
}
} else {
! lock_ObtainWrite(&scp->rw);
}
lock_ReleaseMutex(&dsp->mx);
if (code) {
***************
*** 5333,5339 ****
}
/* release the mutex */
! lock_ReleaseMutex(&scp->mx);
if (bufferp) {
buf_Release(bufferp);
bufferp = NULL;
--- 5344,5350 ----
}
/* release the mutex */
! lock_ReleaseWrite(&scp->rw);
if (bufferp) {
buf_Release(bufferp);
bufferp = NULL;
***************
*** 5698,5706 ****
lock_ObtainMutex(&fidp->mx);
/* save a pointer to the vnode */
fidp->scp = scp;
! lock_ObtainMutex(&scp->mx);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
! lock_ReleaseMutex(&scp->mx);
osi_Log2(smb_logp,"smb_ReceiveV3OpenX fidp 0x%p scp 0x%p", fidp, scp);
/* also the user */
fidp->userp = userp;
--- 5709,5717 ----
lock_ObtainMutex(&fidp->mx);
/* save a pointer to the vnode */
fidp->scp = scp;
! lock_ObtainWrite(&scp->rw);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
! lock_ReleaseWrite(&scp->rw);
osi_Log2(smb_logp,"smb_ReceiveV3OpenX fidp 0x%p scp 0x%p", fidp, scp);
/* also the user */
fidp->userp = userp;
***************
*** 5726,5732 ****
/* copy out remainder of the parms */
parmSlot = 2;
smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++;
! lock_ObtainMutex(&scp->mx);
if (extraInfo) {
smb_SetSMBParm(outp, parmSlot, smb_Attributes(scp)); parmSlot++;
smb_DosUTimeFromUnixTime(&dosTime, scp->clientModTime);
--- 5737,5743 ----
/* copy out remainder of the parms */
parmSlot = 2;
smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++;
! lock_ObtainRead(&scp->rw);
if (extraInfo) {
smb_SetSMBParm(outp, parmSlot, smb_Attributes(scp)); parmSlot++;
smb_DosUTimeFromUnixTime(&dosTime, scp->clientModTime);
***************
*** 5744,5750 ****
smb_SetSMBParm(outp, parmSlot, scp->fid.vnode & 0xffff); parmSlot++;
smb_SetSMBParm(outp, parmSlot, scp->fid.volume & 0xffff); parmSlot++;
smb_SetSMBParm(outp, parmSlot, 0); parmSlot++;
! lock_ReleaseMutex(&scp->mx);
smb_SetSMBDataLength(outp, 0);
osi_Log1(smb_logp, "SMB OpenX opening fid %d", fidp->fid);
--- 5755,5761 ----
smb_SetSMBParm(outp, parmSlot, scp->fid.vnode & 0xffff); parmSlot++;
smb_SetSMBParm(outp, parmSlot, scp->fid.volume & 0xffff); parmSlot++;
smb_SetSMBParm(outp, parmSlot, 0); parmSlot++;
! lock_ReleaseRead(&scp->rw);
smb_SetSMBDataLength(outp, 0);
osi_Log1(smb_logp, "SMB OpenX opening fid %d", fidp->fid);
***************
*** 5789,5795 ****
cm_scache_t *scp;
unsigned char LockType;
unsigned short NumberOfUnlocks, NumberOfLocks;
! long Timeout;
char *op;
char *op_locks;
LARGE_INTEGER LOffset, LLength;
--- 5800,5806 ----
cm_scache_t *scp;
unsigned char LockType;
unsigned short NumberOfUnlocks, NumberOfLocks;
! afs_uint32 Timeout;
char *op;
char *op_locks;
LARGE_INTEGER LOffset, LLength;
***************
*** 5833,5839 ****
userp = smb_GetUserFromVCP(vcp, inp);
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK
| CM_SCACHESYNC_GETSTATUS
--- 5844,5850 ----
userp = smb_GetUserFromVCP(vcp, inp);
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK
| CM_SCACHESYNC_GETSTATUS
***************
*** 5856,5873 ****
LockType |= LOCKING_ANDX_SHARED_LOCK;
}
! if ((LockType & LOCKING_ANDX_CANCEL_LOCK) ||
! (LockType & LOCKING_ANDX_CHANGE_LOCKTYPE)) {
!
! /* We don't support these requests. Apparently, we can safely
! not deal with them too. */
! osi_Log1(smb_logp, "smb_ReceiveV3Locking received unsupported request [%s]",
! ((LockType & LOCKING_ANDX_CANCEL_LOCK)?
! "LOCKING_ANDX_CANCEL_LOCK":
! "LOCKING_ANDX_CHANGE_LOCKTYPE"));
! /* No need to call osi_LogSaveString since these are string
! constants.*/
!
code = CM_ERROR_BADOP;
goto done;
--- 5867,5875 ----
LockType |= LOCKING_ANDX_SHARED_LOCK;
}
! if (LockType & LOCKING_ANDX_CHANGE_LOCKTYPE) {
! /* AFS does not support atomic changes of lock types from read or write and vice-versa */
! osi_Log0(smb_logp, "smb_ReceiveV3Locking received unsupported request [LOCKING_ANDX_CHANGE_LOCKTYPE]");
code = CM_ERROR_BADOP;
goto done;
***************
*** 5875,5880 ****
--- 5877,5911 ----
op = smb_GetSMBData(inp, NULL);
+ if (LockType & LOCKING_ANDX_CANCEL_LOCK) {
+ /* Cancel outstanding lock requests */
+ smb_waitingLock_t * wl;
+
+ for (i=0; ivcID, pid, fidp->fid);
+
+ lock_ObtainWrite(&smb_globalLock);
+ for (wlRequest = smb_allWaitingLocks; wlRequest; wlRequest = (smb_waitingLockRequest_t *) osi_QNext(&wlRequest->q))
+ {
+ for (wl = wlRequest->locks; wl; wl = (smb_waitingLock_t *) osi_QNext(&wl->q)) {
+ if (wl->key == key && LargeIntegerEqualTo(wl->LOffset, LOffset) &&
+ LargeIntegerEqualTo(wl->LLength, LLength)) {
+ wl->state = SMB_WAITINGLOCKSTATE_CANCELLED;
+ goto found_lock_request;
+ }
+ }
+ }
+ found_lock_request:
+ lock_ReleaseWrite(&smb_globalLock);
+ }
+ code = 0;
+ smb_SetSMBDataLength(outp, 0);
+ goto done;
+ }
+
+
for (i=0; iinp = smb_CopyPacket(inp);
wlRequest->outp = smb_CopyPacket(outp);
wlRequest->lockType = LockType;
! wlRequest->timeRemaining = Timeout;
wlRequest->locks = NULL;
/* The waiting lock request needs to have enough
--- 5956,5963 ----
wlRequest->inp = smb_CopyPacket(inp);
wlRequest->outp = smb_CopyPacket(outp);
wlRequest->lockType = LockType;
! wlRequest->msTimeout = Timeout;
! wlRequest->start_t = osi_Time();
wlRequest->locks = NULL;
/* The waiting lock request needs to have enough
***************
*** 6045,6051 ****
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
doneSync:
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_ReleaseFID(fidp);
--- 6077,6083 ----
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
doneSync:
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_ReleaseFID(fidp);
***************
*** 6062,6067 ****
--- 6094,6100 ----
afs_uint32 searchTime;
cm_user_t *userp;
cm_req_t req;
+ int readlock = 0;
cm_InitReq(&req);
***************
*** 6093,6099 ****
/* otherwise, stat the file */
! lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code)
--- 6126,6132 ----
/* otherwise, stat the file */
! lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code)
***************
*** 6101,6106 ****
--- 6134,6141 ----
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ lock_ConvertWToR(&scp->rw);
+
/* decode times. We need a search time, but the response to this
* call provides the date first, not the time, as returned in the
* searchTime variable. So we take the high-order bits first.
***************
*** 6127,6133 ****
code = 0;
done:
! lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_ReleaseFID(fidp);
--- 6162,6171 ----
code = 0;
done:
! if (readlock)
! lock_ReleaseRead(&scp->rw);
! else
! lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_ReleaseFID(fidp);
***************
*** 6210,6215 ****
--- 6248,6254 ----
unsigned short fd;
unsigned pid;
smb_fid_t *fidp;
+ smb_t *smbp = (smb_t*) inp;
long code = 0;
cm_user_t *userp;
char *op;
***************
*** 6274,6280 ****
LARGE_INTEGER LLength;
cm_scache_t * scp;
! pid = ((smb_t *) inp)->pid;
key = cm_GenerateKey(vcp->vcID, pid, fd);
LOffset.HighPart = offset.HighPart;
--- 6313,6319 ----
LARGE_INTEGER LLength;
cm_scache_t * scp;
! pid = smbp->pid;
key = cm_GenerateKey(vcp->vcID, pid, fd);
LOffset.HighPart = offset.HighPart;
***************
*** 6283,6291 ****
LLength.LowPart = count;
scp = fidp->scp;
! lock_ObtainMutex(&scp->mx);
code = cm_LockCheckWrite(scp, LOffset, LLength, key);
! lock_ReleaseMutex(&scp->mx);
if (code)
goto done;
--- 6322,6330 ----
LLength.LowPart = count;
scp = fidp->scp;
! lock_ObtainWrite(&scp->rw);
code = cm_LockCheckWrite(scp, LOffset, LLength, key);
! lock_ReleaseWrite(&scp->rw);
if (code)
goto done;
***************
*** 6325,6332 ****
written = 0;
}
- done_writing:
-
/* slots 0 and 1 are reserved for request chaining and will be
filled in when we return. */
smb_SetSMBParm(outp, 2, total_written);
--- 6364,6369 ----
***************
*** 6350,6355 ****
--- 6387,6393 ----
unsigned short fd;
unsigned pid;
smb_fid_t *fidp;
+ smb_t *smbp = (smb_t*) inp;
long code = 0;
cm_user_t *userp;
cm_key_t key;
***************
*** 6396,6402 ****
return CM_ERROR_NOSUCHFILE;
}
! pid = ((smb_t *) inp)->pid;
key = cm_GenerateKey(vcp->vcID, pid, fd);
{
LARGE_INTEGER LOffset, LLength;
--- 6434,6440 ----
return CM_ERROR_NOSUCHFILE;
}
! pid = smbp->pid;
key = cm_GenerateKey(vcp->vcID, pid, fd);
{
LARGE_INTEGER LOffset, LLength;
***************
*** 6408,6416 ****
LLength.LowPart = count;
scp = fidp->scp;
! lock_ObtainMutex(&scp->mx);
code = cm_LockCheckRead(scp, LOffset, LLength, key);
! lock_ReleaseMutex(&scp->mx);
}
if (code) {
--- 6446,6454 ----
LLength.LowPart = count;
scp = fidp->scp;
! lock_ObtainWrite(&scp->rw);
code = cm_LockCheckRead(scp, LOffset, LLength, key);
! lock_ReleaseWrite(&scp->rw);
}
if (code) {
***************
*** 6712,6718 ****
fidflags = 0;
if (desiredAccess & DELETE)
fidflags |= SMB_FID_OPENDELETE;
! if (desiredAccess & AFS_ACCESS_READ)
fidflags |= SMB_FID_OPENREAD_LISTDIR;
if (desiredAccess & AFS_ACCESS_WRITE)
fidflags |= SMB_FID_OPENWRITE;
--- 6750,6756 ----
fidflags = 0;
if (desiredAccess & DELETE)
fidflags |= SMB_FID_OPENDELETE;
! if (desiredAccess & (AFS_ACCESS_READ|AFS_ACCESS_EXECUTE))
fidflags |= SMB_FID_OPENREAD_LISTDIR;
if (desiredAccess & AFS_ACCESS_WRITE)
fidflags |= SMB_FID_OPENWRITE;
***************
*** 7213,7219 ****
LLength.LowPart = SMB_FID_QLOCK_LENGTH;
/* If we are not opening the file for writing, then we don't
! try to get an exclusive lock. Noone else should be able to
get an exclusive lock on the file anyway, although someone
else can get a shared lock. */
if ((fidflags & SMB_FID_SHARE_READ) ||
--- 7251,7257 ----
LLength.LowPart = SMB_FID_QLOCK_LENGTH;
/* If we are not opening the file for writing, then we don't
! try to get an exclusive lock. No one else should be able to
get an exclusive lock on the file anyway, although someone
else can get a shared lock. */
if ((fidflags & SMB_FID_SHARE_READ) ||
***************
*** 7225,7233 ****
key = cm_GenerateKey(vcp->vcID, SMB_FID_QLOCK_PID, fidp->fid);
! lock_ObtainMutex(&scp->mx);
code = cm_Lock(scp, sLockType, LOffset, LLength, key, 0, userp, &req, NULL);
! lock_ReleaseMutex(&scp->mx);
if (code) {
if (ldp)
--- 7263,7271 ----
key = cm_GenerateKey(vcp->vcID, SMB_FID_QLOCK_PID, fidp->fid);
! lock_ObtainWrite(&scp->rw);
code = cm_Lock(scp, sLockType, LOffset, LLength, key, 0, userp, &req, NULL);
! lock_ReleaseWrite(&scp->rw);
if (code) {
if (ldp)
***************
*** 7251,7259 ****
lock_ObtainMutex(&fidp->mx);
/* save a pointer to the vnode */
fidp->scp = scp; /* Hold transfered to fidp->scp and no longer needed */
! lock_ObtainMutex(&scp->mx);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
! lock_ReleaseMutex(&scp->mx);
osi_Log2(smb_logp,"smb_ReceiveNTCreateX fidp 0x%p scp 0x%p", fidp, scp);
fidp->flags = fidflags;
--- 7289,7297 ----
lock_ObtainMutex(&fidp->mx);
/* save a pointer to the vnode */
fidp->scp = scp; /* Hold transfered to fidp->scp and no longer needed */
! lock_ObtainWrite(&scp->rw);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
! lock_ReleaseWrite(&scp->rw);
osi_Log2(smb_logp,"smb_ReceiveNTCreateX fidp 0x%p scp 0x%p", fidp, scp);
fidp->flags = fidflags;
***************
*** 7286,7292 ****
/* out parms */
parmSlot = 2;
! lock_ObtainMutex(&scp->mx);
smb_SetSMBParmByte(outp, parmSlot, 0); /* oplock */
smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++;
smb_SetSMBParmLong(outp, parmSlot, openAction); parmSlot += 2;
--- 7324,7330 ----
/* out parms */
parmSlot = 2;
! lock_ObtainRead(&scp->rw);
smb_SetSMBParmByte(outp, parmSlot, 0); /* oplock */
smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++;
smb_SetSMBParmLong(outp, parmSlot, openAction); parmSlot += 2;
***************
*** 7314,7320 ****
fidp->scp->length.LowPart, fidp->scp->length.HighPart,
userp);
}
! lock_ReleaseMutex(&scp->mx);
osi_Log2(smb_logp, "SMB NT CreateX opening fid %d path %s", fidp->fid,
osi_LogSaveString(smb_logp, realPathp));
--- 7352,7358 ----
fidp->scp->length.LowPart, fidp->scp->length.HighPart,
userp);
}
! lock_ReleaseRead(&scp->rw);
osi_Log2(smb_logp, "SMB NT CreateX opening fid %d path %s", fidp->fid,
osi_LogSaveString(smb_logp, realPathp));
***************
*** 7516,7522 ****
fidflags = 0;
if (desiredAccess & DELETE)
fidflags |= SMB_FID_OPENDELETE;
! if (desiredAccess & AFS_ACCESS_READ)
fidflags |= SMB_FID_OPENREAD_LISTDIR;
if (desiredAccess & AFS_ACCESS_WRITE)
fidflags |= SMB_FID_OPENWRITE;
--- 7554,7560 ----
fidflags = 0;
if (desiredAccess & DELETE)
fidflags |= SMB_FID_OPENDELETE;
! if (desiredAccess & (AFS_ACCESS_READ|AFS_ACCESS_EXECUTE))
fidflags |= SMB_FID_OPENREAD_LISTDIR;
if (desiredAccess & AFS_ACCESS_WRITE)
fidflags |= SMB_FID_OPENWRITE;
***************
*** 7893,7901 ****
key = cm_GenerateKey(vcp->vcID, SMB_FID_QLOCK_PID, fidp->fid);
! lock_ObtainMutex(&scp->mx);
code = cm_Lock(scp, sLockType, LOffset, LLength, key, 0, userp, &req, NULL);
! lock_ReleaseMutex(&scp->mx);
if (code) {
if (ldp)
--- 7931,7939 ----
key = cm_GenerateKey(vcp->vcID, SMB_FID_QLOCK_PID, fidp->fid);
! lock_ObtainWrite(&scp->rw);
code = cm_Lock(scp, sLockType, LOffset, LLength, key, 0, userp, &req, NULL);
! lock_ReleaseWrite(&scp->rw);
if (code) {
if (ldp)
***************
*** 7917,7925 ****
lock_ObtainMutex(&fidp->mx);
/* save a pointer to the vnode */
fidp->scp = scp;
! lock_ObtainMutex(&scp->mx);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
! lock_ReleaseMutex(&scp->mx);
osi_Log2(smb_logp,"smb_ReceiveNTTranCreate fidp 0x%p scp 0x%p", fidp, scp);
fidp->flags = fidflags;
--- 7955,7963 ----
lock_ObtainMutex(&fidp->mx);
/* save a pointer to the vnode */
fidp->scp = scp;
! lock_ObtainWrite(&scp->rw);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
! lock_ReleaseWrite(&scp->rw);
osi_Log2(smb_logp,"smb_ReceiveNTTranCreate fidp 0x%p scp 0x%p", fidp, scp);
fidp->flags = fidflags;
***************
*** 7976,7982 ****
smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */
smb_SetSMBDataLength(outp, 70);
! lock_ObtainMutex(&scp->mx);
outData = smb_GetSMBData(outp, NULL);
outData++; /* round to get to parmOffset */
*outData = 0; outData++; /* oplock */
--- 8014,8020 ----
smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */
smb_SetSMBDataLength(outp, 70);
! lock_ObtainRead(&scp->rw);
outData = smb_GetSMBData(outp, NULL);
outData++; /* round to get to parmOffset */
*outData = 0; outData++; /* oplock */
***************
*** 7998,8004 ****
scp->fileType == CM_SCACHETYPE_MOUNTPOINT ||
scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0);
outData += 2; /* is a dir? */
- lock_ReleaseMutex(&scp->mx);
} else {
/* out parms */
parmOffset = 8*4 + 39;
--- 8036,8041 ----
***************
*** 8026,8032 ****
smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */
smb_SetSMBDataLength(outp, 105);
! lock_ObtainMutex(&scp->mx);
outData = smb_GetSMBData(outp, NULL);
outData++; /* round to get to parmOffset */
*outData = 0; outData++; /* oplock */
--- 8063,8069 ----
smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */
smb_SetSMBDataLength(outp, 105);
! lock_ObtainRead(&scp->rw);
outData = smb_GetSMBData(outp, NULL);
outData++; /* round to get to parmOffset */
*outData = 0; outData++; /* oplock */
***************
*** 8051,8060 ****
memset(outData,0,24); outData += 24; /* Volume ID and file ID */
*((ULONG *)outData) = 0x001f01ffL; outData += 4; /* Maxmimal access rights */
*((ULONG *)outData) = 0; outData += 4; /* Guest Access rights */
- lock_ReleaseMutex(&scp->mx);
}
- lock_ObtainMutex(&scp->mx);
if ((fidp->flags & SMB_FID_EXECUTABLE) &&
LargeIntegerGreaterThanZero(fidp->scp->length) &&
!(scp->flags & CM_SCACHEFLAG_PREFETCHING)) {
--- 8088,8095 ----
***************
*** 8062,8068 ****
fidp->scp->length.LowPart, fidp->scp->length.HighPart,
userp);
}
! lock_ReleaseMutex(&scp->mx);
osi_Log1(smb_logp, "SMB NTTranCreate opening fid %d", fidp->fid);
--- 8097,8103 ----
fidp->scp->length.LowPart, fidp->scp->length.HighPart,
userp);
}
! lock_ReleaseRead(&scp->rw);
osi_Log1(smb_logp, "SMB NTTranCreate opening fid %d", fidp->fid);
***************
*** 8145,8156 ****
if (filter & FILE_NOTIFY_CHANGE_STREAM_WRITE)
osi_Log0(smb_logp, " Notify Change Stream Write");
! lock_ObtainMutex(&scp->mx);
if (watchtree)
scp->flags |= CM_SCACHEFLAG_WATCHEDSUBTREE;
else
scp->flags |= CM_SCACHEFLAG_WATCHED;
! lock_ReleaseMutex(&scp->mx);
smb_ReleaseFID(fidp);
outp->flags |= SMB_PACKETFLAG_NOSEND;
--- 8180,8191 ----
if (filter & FILE_NOTIFY_CHANGE_STREAM_WRITE)
osi_Log0(smb_logp, " Notify Change Stream Write");
! lock_ObtainWrite(&scp->rw);
if (watchtree)
scp->flags |= CM_SCACHEFLAG_WATCHEDSUBTREE;
else
scp->flags |= CM_SCACHEFLAG_WATCHED;
! lock_ReleaseWrite(&scp->rw);
smb_ReleaseFID(fidp);
outp->flags |= SMB_PACKETFLAG_NOSEND;
***************
*** 8268,8273 ****
--- 8303,8314 ----
break;
case 6:
return smb_ReceiveNTTranQuerySecurityDesc(vcp, inp, outp);
+ case 7:
+ osi_Log0(smb_logp, "SMB NT Transact Query Quota - not implemented");
+ break;
+ case 8:
+ osi_Log0(smb_logp, "SMB NT Transact Set Quota - not implemented");
+ break;
}
return CM_ERROR_INVAL;
}
***************
*** 8392,8403 ****
lastWatch->nextp = nextWatch;
/* Turn off WATCHED flag in dscp */
! lock_ObtainMutex(&dscp->mx);
if (wtree)
dscp->flags &= ~CM_SCACHEFLAG_WATCHEDSUBTREE;
else
dscp->flags &= ~CM_SCACHEFLAG_WATCHED;
! lock_ReleaseMutex(&dscp->mx);
/* Convert to response packet */
((smb_t *) watch)->reb = SMB_FLAGS_SERVER_TO_CLIENT;
--- 8433,8444 ----
lastWatch->nextp = nextWatch;
/* Turn off WATCHED flag in dscp */
! lock_ObtainWrite(&dscp->rw);
if (wtree)
dscp->flags &= ~CM_SCACHEFLAG_WATCHEDSUBTREE;
else
dscp->flags &= ~CM_SCACHEFLAG_WATCHED;
! lock_ReleaseWrite(&dscp->rw);
/* Convert to response packet */
((smb_t *) watch)->reb = SMB_FLAGS_SERVER_TO_CLIENT;
***************
*** 8542,8553 ****
scp = fidp->scp;
osi_Log2(smb_logp,"smb_ReceiveNTCancel fidp 0x%p scp 0x%p", fidp, scp);
! lock_ObtainMutex(&scp->mx);
if (watchtree)
scp->flags &= ~CM_SCACHEFLAG_WATCHEDSUBTREE;
else
scp->flags &= ~CM_SCACHEFLAG_WATCHED;
! lock_ReleaseMutex(&scp->mx);
smb_ReleaseFID(fidp);
} else {
osi_Log2(smb_logp,"NTCancel unable to resolve fid [%d] in vcp[%x]", fid,vcp);
--- 8583,8594 ----
scp = fidp->scp;
osi_Log2(smb_logp,"smb_ReceiveNTCancel fidp 0x%p scp 0x%p", fidp, scp);
! lock_ObtainWrite(&scp->rw);
if (watchtree)
scp->flags &= ~CM_SCACHEFLAG_WATCHEDSUBTREE;
else
scp->flags &= ~CM_SCACHEFLAG_WATCHED;
! lock_ReleaseWrite(&scp->rw);
smb_ReleaseFID(fidp);
} else {
osi_Log2(smb_logp,"NTCancel unable to resolve fid [%d] in vcp[%x]", fid,vcp);
Index: openafs/src/WINNT/afsrdr/afsrdr.c
diff -c openafs/src/WINNT/afsrdr/afsrdr.c:1.3.4.2 openafs/src/WINNT/afsrdr/afsrdr.c:removed
*** openafs/src/WINNT/afsrdr/afsrdr.c:1.3.4.2 Thu Jul 20 17:46:21 2006
--- openafs/src/WINNT/afsrdr/afsrdr.c Sat Mar 22 21:01:36 2008
***************
*** 1,2648 ****
- /* copyright (c) 2005
- * the regents of the university of michigan
- * all rights reserved
- *
- * permission is granted to use, copy, create derivative works and
- * redistribute this software and such derivative works for any purpose,
- * so long as the name of the university of michigan is not used in
- * any advertising or publicity pertaining to the use or distribution
- * of this software without specific, written prior authorization. if
- * the above copyright notice or any other identification of the
- * university of michigan is included in any copy of any portion of
- * this software, then the disclaimer below must also be included.
- *
- * this software is provided as is, without representation from the
- * university of michigan as to its fitness for any purpose, and without
- * warranty by the university of michigan of any kind, either express
- * or implied, including without limitation the implied warranties of
- * merchantability and fitness for a particular purpose. the regents
- * of the university of michigan shall not be liable for any damages,
- * including special, indirect, incidental, or consequential damages,
- * with respect to any claim arising out or in connection with the use
- * of the software, even if it has been or is hereafter advised of the
- * possibility of such damages.
- */
-
- /* versioning history
- *
- * 03-jun 2005 (eric williams) entered into versioning
- */
-
- /* developer: eric williams,
- * center for information technology integration,
- * university of michigan, ann arbor
- *
- * comments: nativeafs@citi.umich.edu
- */
-
- #define IRPMJFUNCDESC /* pull in text strings of the names of irp codes */
- #define RPC_SRV /* which half of the rpc library to use */
-
- #include
- #include
- #include
- #include
- #include "ifs_rpc.h"
- #include "afsrdr.h"
- #include "kif.h"
-
-
- /*** notes ***/
- /* flag pooltag Io(sp)(sp) to check queryinfo requests for buffer overrun */
-
- NTKERNELAPI
- NTSTATUS
- IoAllocateDriverObjectExtension(
- IN PDRIVER_OBJECT DriverObject,
- IN PVOID ClientIdentificationAddress,
- IN ULONG DriverObjectExtensionSize,
- OUT PVOID *DriverObjectExtension
- );
-
- /*** local structs ***/
- /* represents a specific file */
- struct afs_fcb
- {
- FSRTL_COMMON_FCB_HEADER; /* needed to interface with cache manager, etc. */
- SECTION_OBJECT_POINTERS sectionPtrs;
- ERESOURCE _resource; /* pointed to by fcb_header->Resource */
- ERESOURCE _pagingIoResource;
- unsigned long fid; /* a courtesy from the userland daemon (a good hash function) */
- UCHAR delPending;
- struct afs_ccb *ccb_list; /* list of open instances */
- SHARE_ACCESS share_access; /* common access control */
- PFILE_LOCK lock;
- };
- typedef struct afs_fcb afs_fcb_t;
-
- /* represents an open instance of a file */
- struct afs_ccb
- {
- struct afs_ccb *next; /* these are chained as siblings, non-circularly */
- ULONG access; /* how this instance is opened */
- wchar_t *name; /* ptr to name buffer */
- UNICODE_STRING str; /* full name struct, for notification fns */
- FILE_OBJECT *fo; /* can get parent fcb from this */
- LARGE_INTEGER cookie; /* on enum ops, where we are */
- wchar_t *filter; /* on enum ops, what we are filtering on */
- PACCESS_TOKEN token; /* security data of opening app */
- ULONG attribs; /* is dir, etc. */
- };
- typedef struct afs_ccb afs_ccb_t;
-
-
- /*** globals ***/
- /* use wisely -- should be set by each thread in an arbitrary context */
- /* here mostly as a development convenience */
- DEVICE_OBJECT *RdrDevice, *ComDevice;
- struct AfsRdrExtension *rdrExt;
- struct ComExtension *comExt;
-
-
- /*** error and return handling ***/
- /* current code is stable without, but these should wrap all operations */
- /*#define TRY try{
- #define EXCEPT(x, y) } except(EXCEPTION_EXECUTE_HANDLER) \
- { \
- KdBreakPoint(); \
- rpt4(("exception", "occurred")); \
- Irp->IoStatus.Status = x; \
- Irp->IoStatus.Information = y; \
- }*/
- #define TRY
- #define EXCEPT(x, y)
-
- #define STATUS(st, in) Irp->IoStatus.Information = (in), Irp->IoStatus.Status = (st)
- #define SYNC_FAIL(st) \
- { \
- STATUS(st, 0); \
- COMPLETE_NO_BOOST; \
- return st; \
- }
- #define SYNC_FAIL2(st, in) \
- { \
- STATUS(st, in); \
- COMPLETE_NO_BOOST; \
- return st; \
- }
- #define SYNC_RET(st) \
- { \
- STATUS(st, 0); \
- COMPLETE; \
- return st; \
- }
- #define SYNC_RET2(st, in) \
- { \
- STATUS(st, in); \
- COMPLETE; \
- return st; \
- }
- #define SYNC_FAIL_RPC_TIMEOUT SYNC_FAIL(STATUS_NETWORK_BUSY)
-
- #define LOCK_FCB_LIST FsRtlEnterFileSystem(); ExAcquireFastMutex(&rdrExt->fcbLock);
- #define UNLOCK_FCB_LIST ExReleaseFastMutex(&rdrExt->fcbLock); FsRtlExitFileSystem();
-
- #define LOCK_FCB ExAcquireResourceExclusiveLite(fcb->Resource, TRUE)
- #define SLOCK_FCB ExAcquireResourceSharedLite(fcb->Resource, TRUE)
- #define UNLOCK_FCB if (fcb) ExReleaseResourceLite(fcb->Resource)
-
- #define LOCK_PAGING_FCB ExAcquireResourceExclusiveLite(fcb->PagingIoResource, TRUE)
- #define SLOCK_PAGING_FCB ExAcquireResourceSharedLite(fcb->PagingIoResource, TRUE)
- #define UNLOCK_PAGING_FCB if (fcb) ExReleaseResourceLite(fcb->PagingIoResource)
-
- /*** constants ***/
- #define AFS_RDR_TAG (0x73666440)//@dfs//0x482ac230//0x3029a4f2
- #define MAX_PATH 700
- #define AFS_FS_NAME L"Andrew File System"
-
- #define COMM_IOCTL (void*)0x01
- #define COMM_DOWNCALL (void*)0x02
- #define COMM_UPCALLHOOK (void*)0x03
-
- /* flag to use caching kernel service. needs to handle cache invalidation in more places. */
- #define EXPLICIT_CACHING
-
- /* dates from afs are time_t style -- seconds since 1970 */ /* 11644505691.6384 */
- #define AfsTimeToWindowsTime(x) (((x)+11644505692L)*10000000L) /*(1970L-1601L)*365.242199*24L*3600L)*/
- #define WindowsTimeToAfsTime(x) ((x)/10000000L-11644505692L) /*(1970L-1601L)*365.242199*24L*3600L)*/
- #define IsDeviceFile(fo) (!fo->FsContext)
-
-
- /*** auxiliary functions ***/
- #define COMPLETE_NO_BOOST IoCompleteRequest(Irp, IO_NO_INCREMENT)
- #define COMPLETE IoCompleteRequest(Irp, IO_NETWORK_INCREMENT)
-
- afs_fcb_t *FindFcb(FILE_OBJECT *fo)
- {
- if (fo)
- return fo->FsContext;
- return NULL;
- }
-
- void *AfsFindBuffer(IRP *Irp)
- {
- void *outPtr;
- if (Irp->MdlAddress)
- {
- outPtr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
- if (outPtr)
- return outPtr;
- }
- outPtr = Irp->AssociatedIrp.SystemBuffer;
- return outPtr;
- }
-
- /* we do Resource locking because we don't want to figure out when to pull MainResource */
- BOOLEAN lazyWriteLock(PVOID context, BOOLEAN wait)
- {
- afs_fcb_t *fcb = context;
- ASSERT(fcb);
- return ExAcquireResourceExclusiveLite(fcb->Resource, wait);
- }
-
- void lazyWriteUnlock(PVOID context)
- {
- afs_fcb_t *fcb = context;
- ASSERT(fcb);
- ExReleaseResourceLite(fcb->Resource);
- }
-
- BOOLEAN readAheadLock(PVOID context, BOOLEAN wait)
- {
- afs_fcb_t *fcb = context;
- ASSERT(fcb);
- return ExAcquireResourceSharedLite(fcb->Resource, wait);
- }
-
- void readAheadUnlock(PVOID context)
- {
- afs_fcb_t *fcb = context;
- ASSERT(fcb);
- ExReleaseResourceLite(fcb->Resource);
- }
-
- afs_fcb_t *find_fcb(ULONG fid)
- {
- afs_fcb_t compare, *compare_ptr, **fcbp;
-
- compare.fid = fid;
- compare_ptr = &compare;
- fcbp = RtlLookupElementGenericTable(&rdrExt->fcbTable, (void*)&compare_ptr);
-
- if (fcbp)
- return (*fcbp);
- return NULL;
- }
-
-
- /**********************************************************
- * AfsRdrCreate
- * - handle open and create requests
- * - on success
- * - FsContext of file object points to FCB
- * - FsContext2 of file object is usermode handle of file instance
- * - beginning failure codes and conditions came from ifstest
- **********************************************************/
- NTSTATUS AfsRdrCreate(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *_fcb)
- {
- afs_fcb_t *pfcb, *fcb, **fcbp;
- afs_ccb_t *ccb, *pccb, *curr_ccb;
- ULONG len;
- LONG x, y;
- wchar_t *str, *ptr;
- ULONG fid, access, granted, disp;
- LARGE_INTEGER size, creation, accesst, change, written, zero, wait;
- ULONG attribs;
- ULONG share;
- CC_FILE_SIZES sizes;
- NTSTATUS status;
- char created;
- PACCESS_TOKEN acc_token;
-
- /* set rpc security context for current thread */
- acc_token = SeQuerySubjectContextToken(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
- ASSERT(acc_token);
-
- wait.QuadPart = -1000;
- while (rpc_set_context(acc_token) != 0) /* if there are no open thread spots... */
- KeDelayExecutionThread(KernelMode, FALSE, &wait); /* ...wait */
-
- /* attempt to open afs volume directly */
- if (IrpSp->FileObject->FileName.Length == 0)
- SYNC_FAIL(STATUS_SHARING_VIOLATION);
-
- if (IrpSp->FileObject->FileName.Length > MAX_PATH*sizeof(wchar_t))
- SYNC_FAIL(STATUS_OBJECT_NAME_INVALID);
-
- if (IrpSp->Parameters.Create.FileAttributes & FILE_ATTRIBUTE_TEMPORARY &&
- IrpSp->Parameters.Create.Options & FILE_DIRECTORY_FILE)
- SYNC_FAIL(STATUS_INVALID_PARAMETER);
-
- /* relative opens cannot start with \ */
- if (IrpSp->FileObject->RelatedFileObject &&
- IrpSp->FileObject->FileName.Length &&
- IrpSp->FileObject->FileName.Buffer[0] == L'\\')
- SYNC_FAIL(STATUS_INVALID_PARAMETER);/*STATUS_OBJECT_PATH_SYNTAX_BAD);*/
-
- /* a create request can be relative to a prior file. build filename here */
- pccb = NULL;
- if (IrpSp->FileObject->RelatedFileObject)
- pccb = IrpSp->FileObject->RelatedFileObject->FsContext2;
- len = IrpSp->FileObject->FileName.Length + (pccb?wcslen(pccb->name):0)*sizeof(wchar_t) + 6;
- str = ExAllocatePoolWithTag(NonPagedPool, len, AFS_RDR_TAG);
- RtlZeroMemory(str, len);
- if (pccb)
- {
- StringCbCatN(str, len, IrpSp->FileObject->RelatedFileObject->FileName.Buffer, IrpSp->FileObject->RelatedFileObject->FileName.Length);
- StringCbCat(str, len, L"\\");
- }
- StringCbCatN(str, len, IrpSp->FileObject->FileName.Buffer, IrpSp->FileObject->FileName.Length);
-
- /* request to open hierarchical parent of specified path */
- /* remove last path component */
- if (IrpSp->Flags & SL_OPEN_TARGET_DIRECTORY)
- {
- y = x = wcslen(str);
- if (x)
- x--, y--;
- for (x; x >= 0; x--)
- {
- if (str[x] == L'\\')
- {
- if (y == x && x != 0)
- str[x] = L'\0';
- else if (x != 0)
- {
- str[x] = L'\0';
- break;
- }
- else
- {
- str[x+1] = L'\0';
- break;
- }
- }
- }
- }
-
- /* first two characters are \%01d . %d is number of path components immediately
- * following that should not be returned in file name queries.
- * EX: \3\mount\path\start\fname.ext is mapped to :\fname.ext
- */
- if (wcslen(str) <= 2)
- {
- ExFreePoolWithTag(str, AFS_RDR_TAG);
- SYNC_FAIL(STATUS_OBJECT_NAME_INVALID);
- }
-
- fid = 0;
- disp = (unsigned char)((IrpSp->Parameters.Create.Options >> 24) & 0xff);
- access = IrpSp->Parameters.Create.SecurityContext->DesiredAccess;
- share = IrpSp->Parameters.Create.ShareAccess;
- size.QuadPart = 0;
- created = 0;
-
- open:
- /* check for file existance. we jump to creating it if needed */
- if (disp == FILE_OPEN || disp == FILE_OPEN_IF || disp == FILE_OVERWRITE ||
- disp == FILE_OVERWRITE_IF || disp == FILE_SUPERSEDE)
- {
- /* chop our internal mount flagging from the beginning */
- status = uc_namei(str+2, &fid);
- if (status == IFSL_DOES_NOT_EXIST &&
- (disp == FILE_OPEN_IF ||
- disp == FILE_OVERWRITE_IF ||
- disp == FILE_SUPERSEDE))
- goto create;
-
- if (status != IFSL_SUCCESS)
- {
- ExFreePoolWithTag(str, AFS_RDR_TAG);
- switch (status)
- {
- case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT;
- case IFSL_NO_ACCESS: SYNC_FAIL(STATUS_ACCESS_DENIED);
- case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER);
- case IFSL_DOES_NOT_EXIST: SYNC_FAIL2(STATUS_OBJECT_NAME_NOT_FOUND, FILE_DOES_NOT_EXIST);
- case IFSL_PATH_DOES_NOT_EXIST: SYNC_FAIL2(STATUS_OBJECT_PATH_NOT_FOUND, FILE_DOES_NOT_EXIST);
- default: SYNC_FAIL(STATUS_UNSUCCESSFUL);
- }
- }
-
- /* make upcall to get ACL in afs. we specify our requested level to
- * keep it from hitting the network on a public volume.
- */
- status = uc_check_access(fid, access, &granted);
- if (status != IFSL_SUCCESS)
- {
- ExFreePoolWithTag(str, AFS_RDR_TAG);
- switch (status)
- {
- case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT;
- case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER);
- default: SYNC_FAIL(STATUS_UNSUCCESSFUL);
- }
- }
-
- /* make sure daemon approved access */
- if ((access & granted) != access)
- {
- ExFreePoolWithTag(str, AFS_RDR_TAG);
- SYNC_FAIL(STATUS_ACCESS_DENIED);
- }
-
- /* we depend on this information for caching, etc. */
- status = uc_stat(fid, &attribs, &size, &creation, &accesst, &change, &written);
- if (status != IFSL_SUCCESS)
- {
- ExFreePoolWithTag(str, AFS_RDR_TAG);
- switch (status)
- {
- case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT;
- case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER);
- default: SYNC_FAIL(STATUS_UNSUCCESSFUL);
- }
- }
-
- /* afsd does not maintain instance-specific data, so we adjust here */
- if (granted & FILE_READ_DATA && !(granted & FILE_WRITE_DATA))
- attribs |= FILE_ATTRIBUTE_READONLY;
-
- if (IrpSp->Parameters.Create.Options & FILE_DIRECTORY_FILE &&
- !(attribs & FILE_ATTRIBUTE_DIRECTORY))
- {
- ExFreePoolWithTag(str, AFS_RDR_TAG);
- SYNC_FAIL(STATUS_NOT_A_DIRECTORY);
- }
- if (IrpSp->Parameters.Create.Options & FILE_NON_DIRECTORY_FILE &&
- attribs & FILE_ATTRIBUTE_DIRECTORY)
- {
- ExFreePoolWithTag(str, AFS_RDR_TAG);
- SYNC_FAIL(STATUS_FILE_IS_A_DIRECTORY);
- }
-
- /* check for previous open instance(s) of file. it will be in the fcb chain.
- * when we have this locked, we cannot make upcalls -- running at APC_LEVEL.
- * lock here (not later) to prevent possible truncation races.
- */
- LOCK_FCB_LIST;
- fcb = find_fcb(fid);
- if (fcb)
- {
- LOCK_PAGING_FCB;
- LOCK_FCB;
- }
-
- /* if we found it, check to make sure open disposition and sharing
- * are not in conflict with previous opens. then, make new file
- * instance entry and, if necessary, file entry.
- */
- if (fcb)
- {
- /* file contents cannot be cached for a successful delete */
- if (access & FILE_WRITE_DATA)
- if (!MmFlushImageSection(&(fcb->sectionPtrs), MmFlushForWrite))
- {
- UNLOCK_FCB;
- UNLOCK_PAGING_FCB;
- UNLOCK_FCB_LIST;
- ExFreePoolWithTag(str, AFS_RDR_TAG);
- SYNC_FAIL(STATUS_SHARING_VIOLATION);
- }
- if (access & DELETE)
- if (!MmFlushImageSection(&(fcb->sectionPtrs), MmFlushForWrite))//Delete))
- {
- UNLOCK_FCB;
- UNLOCK_PAGING_FCB;
- UNLOCK_FCB_LIST;
- ExFreePoolWithTag(str, AFS_RDR_TAG);
- SYNC_FAIL(STATUS_SHARING_VIOLATION);
- }
-
- /* check common sharing flags, but do not change */
- if (IoCheckShareAccess(access, share, IrpSp->FileObject, &fcb->share_access, FALSE) != STATUS_SUCCESS)
- {
- rpt0(("create", "sharing violation for %ws", str));
- UNLOCK_FCB;
- UNLOCK_PAGING_FCB;
- UNLOCK_FCB_LIST;
- ExFreePoolWithTag(str, AFS_RDR_TAG);
- SYNC_FAIL(STATUS_SHARING_VIOLATION);
- }
-
- zero.QuadPart = 0;
- if (access & DELETE)
- if (!MmCanFileBeTruncated(&(fcb->sectionPtrs), &zero))
- {
- UNLOCK_FCB;
- UNLOCK_PAGING_FCB;
- UNLOCK_FCB_LIST;
- ExFreePoolWithTag(str, AFS_RDR_TAG);
- SYNC_FAIL(STATUS_SHARING_VIOLATION);
- }
- }
-
- /* do overwrite/supersede tasks */
- if (disp == FILE_OVERWRITE ||
- disp == FILE_OVERWRITE_IF ||
- disp == FILE_SUPERSEDE)
- {
- zero.QuadPart = 0;
- if (fcb && !MmCanFileBeTruncated(&(fcb->sectionPtrs), &zero))
- {
- UNLOCK_FCB;
- UNLOCK_PAGING_FCB;
- UNLOCK_FCB_LIST;
- ExFreePoolWithTag(str, AFS_RDR_TAG);
- SYNC_FAIL(STATUS_SHARING_VIOLATION);
- }
- if (size.QuadPart != 0)
- {
- size.QuadPart = 0;
- status = uc_trunc(fid, size);
- if (status != IFSL_SUCCESS)
- {
- UNLOCK_FCB;
- UNLOCK_PAGING_FCB;
- UNLOCK_FCB_LIST;
- ExFreePoolWithTag(str, AFS_RDR_TAG);
- SYNC_FAIL(STATUS_ACCESS_DENIED);
- }
- if (fcb)
- {
- fcb->AllocationSize = fcb->FileSize = fcb->ValidDataLength = size;
- curr_ccb = fcb->ccb_list;
- while (curr_ccb && curr_ccb->fo)
- {
- if (CcIsFileCached(curr_ccb->fo))
- {
- CcSetFileSizes(curr_ccb->fo, (CC_FILE_SIZES*)&fcb->AllocationSize);
- break;
- }
- curr_ccb = curr_ccb->next;
- }
- }
- }
- if (Irp->Overlay.AllocationSize.QuadPart)
- {
- status = uc_trunc(fid, Irp->Overlay.AllocationSize);
- size = Irp->Overlay.AllocationSize;
- if (status != IFSL_SUCCESS)
- {
- UNLOCK_FCB;
- UNLOCK_PAGING_FCB;
- UNLOCK_FCB_LIST;
- ExFreePoolWithTag(str, AFS_RDR_TAG);
- SYNC_FAIL(STATUS_DISK_FULL);
- }
- if (fcb)
- {
- fcb->AllocationSize = fcb->FileSize = fcb->ValidDataLength = size;
- curr_ccb = fcb->ccb_list;
- while (curr_ccb && curr_ccb->fo)
- {
- if (CcIsFileCached(curr_ccb->fo))
- {
- CcSetFileSizes(curr_ccb->fo, (CC_FILE_SIZES*)&fcb->AllocationSize);
- break;
- }
- curr_ccb = curr_ccb->next;
- }
- }
- }
- }
-
- if (fcb)
- {
- /* make actual change in common sharing flags */
- IoUpdateShareAccess(IrpSp->FileObject, &fcb->share_access);
- goto makeccb;
- }
-
- goto makefcb;
- }
-
-
- /* if disposition was to create the file, or its non-existance necessitates this */
- create:
- if (disp == FILE_CREATE ||
- status == IFSL_DOES_NOT_EXIST && (disp == FILE_OPEN_IF || disp == FILE_OVERWRITE_IF || disp == FILE_SUPERSEDE))
- {
- attribs = IrpSp->Parameters.Create.FileAttributes;
- if (IrpSp->Parameters.Create.Options & FILE_DIRECTORY_FILE)
- attribs |= FILE_ATTRIBUTE_DIRECTORY;
- if (IrpSp->Parameters.Create.Options & FILE_NON_DIRECTORY_FILE)
- attribs &= ~FILE_ATTRIBUTE_DIRECTORY;
- status = uc_create(str+2, attribs, Irp->Overlay.AllocationSize, access, &granted, &fid);
- if (status != IFSL_SUCCESS)
- {
- ExFreePoolWithTag(str, AFS_RDR_TAG);
- switch (status)
- {
- case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT;
- case IFSL_NO_ACCESS: SYNC_FAIL(STATUS_ACCESS_DENIED);
- case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER);
- case IFSL_PATH_DOES_NOT_EXIST: SYNC_FAIL2(STATUS_OBJECT_PATH_NOT_FOUND, FILE_DOES_NOT_EXIST);
- case IFSL_OPEN_EXISTS: SYNC_FAIL2(STATUS_OBJECT_NAME_COLLISION, FILE_EXISTS);
- case IFSL_OVERQUOTA: SYNC_FAIL(STATUS_DISK_FULL);//STATUS_QUOTA_EXCEEDED);
- default: SYNC_FAIL(STATUS_UNSUCCESSFUL);
- }
- }
-
- /* lock list like above. check again just to make sure it isn't in the list.
- * if it is, we should process like above. depending on how we follow symlinks
- * (same fid for multiple files), we cannot expect serialized create requests.
- */
- LOCK_FCB_LIST;
- fcb = find_fcb(fid);
- if (fcb) /* none of these should happen */
- if (disp == FILE_CREATE)
- {
- UNLOCK_FCB_LIST;
- SYNC_FAIL2(STATUS_OBJECT_NAME_COLLISION, FILE_EXISTS);
- }
- else
- {
- fcb = NULL;
- UNLOCK_FCB_LIST;
- goto open;
- }
-
- if (size.QuadPart != 0)
- {
- size.QuadPart = 0;
- uc_trunc(fid, size);
- if (status != IFSL_SUCCESS)
- {
- UNLOCK_FCB_LIST;
- ExFreePoolWithTag(str, AFS_RDR_TAG);
- SYNC_FAIL(STATUS_DISK_FULL);
- }
- }
- if (Irp->Overlay.AllocationSize.QuadPart)
- {
- uc_trunc(fid, Irp->Overlay.AllocationSize);
- size = Irp->Overlay.AllocationSize;
- if (status != IFSL_SUCCESS)
- {
- UNLOCK_FCB_LIST;
- ExFreePoolWithTag(str, AFS_RDR_TAG);
- SYNC_FAIL(STATUS_ACCESS_DENIED);
- }
- }
-
- created = 1;
- goto makefcb;
- }
-
- /* OS passed unexpected disposition */
- ExFreePoolWithTag(str, AFS_RDR_TAG);
- SYNC_FAIL(STATUS_NOT_IMPLEMENTED);
-
-
- /* allocate nonpaged struct to track this file and all open instances */
- makefcb:
- fcb = ExAllocateFromNPagedLookasideList(&rdrExt->fcbMemList);
- ASSERT(fcb);
- RtlZeroMemory(fcb, sizeof(afs_fcb_t));
-
- fcb->fid = fid;
- /*fcb->refs = 0;*/
- fcb->ccb_list = NULL;
- fcb->IsFastIoPossible = FastIoIsPossible;
-
- ExInitializeResourceLite(&fcb->_resource);
- ExInitializeResourceLite(&fcb->_pagingIoResource);
- fcb->Resource = &fcb->_resource;
- fcb->PagingIoResource = &fcb->_pagingIoResource;
- LOCK_PAGING_FCB;
- LOCK_FCB;
-
- fcb->sectionPtrs.DataSectionObject = NULL;
- fcb->sectionPtrs.SharedCacheMap = NULL;
- fcb->sectionPtrs.ImageSectionObject = NULL;
- fcb->AllocationSize = fcb->FileSize = fcb->ValidDataLength = size;
-
- IoSetShareAccess(access, share, IrpSp->FileObject, &fcb->share_access);
- fcb->lock = NULL;
-
- /* we store a pointer to the fcb. the table would want to store a copy otherwise. */
- fcbp = &fcb;
- RtlInsertElementGenericTable(&rdrExt->fcbTable, fcbp, sizeof(fcbp), NULL);
-
- sizes.AllocationSize = sizes.FileSize = sizes.ValidDataLength = size;
- rpt1(("create", "created size %d name %ws", size.LowPart, str));
-
- /* allocate nonpaged struct tracking information specific to (file, open instance) pair,
- * and link from parent. is put at head of parent's list.
- */
- makeccb:
- /* there are two different types of pending deletes. we return different
- * errors in places depending on a) delete specified on call to open,
- * or b) file specifically deleted
- */
- /* need to check for DELETE perms too? */
- if (IrpSp->Parameters.Create.Options & FILE_DELETE_ON_CLOSE)
- fcb->delPending = 2;
-
- ccb = ExAllocateFromNPagedLookasideList(&rdrExt->ccbMemList);
- ccb->name = str;
- ccb->access = granted;
- ccb->fo = IrpSp->FileObject;
- ccb->cookie.QuadPart = 0;
- ccb->filter = NULL;
- ccb->attribs = attribs;
-
- /* save security context information. we never change this ccb attribute. */
- ObReferenceObjectByPointer(acc_token, TOKEN_QUERY, NULL, KernelMode);
- ccb->token = acc_token;
- /*ObOpenObjectByPointer(acc_token, OBJ_KERNEL_HANDLE, NULL, TOKEN_QUERY, NULL, KernelMode, &ccb->token);*/
-
- if (!fcb->ccb_list)
- {
- ccb->next = NULL;
- fcb->ccb_list = ccb;
- }
- else
- {
- ccb->next = fcb->ccb_list;
- fcb->ccb_list = ccb;
- }
- UNLOCK_FCB;
- UNLOCK_PAGING_FCB;
- UNLOCK_FCB_LIST;
-
- /* how we pack (what the cache manager needs): a) fscontext same for all open instances
- * of a file, b) fscontext2 unique among each instance, c) private cache map pointer set
- * by cache manager upon caching, d) so pointers are per-file, as in (a).
- */
- IrpSp->FileObject->FsContext = fcb;
- IrpSp->FileObject->FsContext2 = ccb;
- IrpSp->FileObject->PrivateCacheMap = NULL;
- IrpSp->FileObject->SectionObjectPointer = &(fcb->sectionPtrs);
-
- /* customize returns; semantics largely derived from output of ifstest.exe */
- switch (disp)
- {
- case FILE_OPEN:
- SYNC_FAIL2(STATUS_SUCCESS, FILE_OPENED);
-
- case FILE_OPEN_IF:
- if (created) {
- SYNC_FAIL2(STATUS_SUCCESS, FILE_CREATED);
- } else {
- SYNC_FAIL2(STATUS_SUCCESS, FILE_OPENED);
- }
- case FILE_OVERWRITE:
- SYNC_FAIL2(STATUS_SUCCESS, FILE_OVERWRITTEN);
-
- case FILE_OVERWRITE_IF:
- if (created) {
- SYNC_FAIL2(STATUS_SUCCESS, FILE_CREATED);
- } else {
- SYNC_FAIL2(STATUS_SUCCESS, FILE_OVERWRITTEN);
- }
- case FILE_SUPERSEDE:
- if (created) {
- SYNC_FAIL2(STATUS_SUCCESS, FILE_CREATED);
- } else {
- SYNC_FAIL2(STATUS_SUCCESS, FILE_SUPERSEDED);
- }
- case FILE_CREATE:
- SYNC_FAIL2(STATUS_SUCCESS, FILE_CREATED);
- }
- return 0;
- }
-
-
- /**********************************************************
- * AfsRdrRead
- * - handle reads
- **********************************************************/
- NTSTATUS AfsRdrRead(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb)
- {
- struct ReadKOut *p;
- void *ptr;
- LARGE_INTEGER offset, curroff;
- ULONG length, read;
- void *outPtr;
- NTSTATUS status;
- afs_ccb_t *ccb;
- MDL m;
- ULONG currpos, ttlread, toread;
-
- ccb = IrpSp->FileObject->FsContext2;
- if (IsDeviceFile(IrpSp->FileObject) || (ccb->attribs & FILE_ATTRIBUTE_DIRECTORY))
- SYNC_FAIL(STATUS_INVALID_DEVICE_REQUEST);
-
- /* the second line enables read ahead and disables write behind. since our data is
- * already cached in userland, and there are read-ahead parameters there, these are
- * not strictly necessary for decent performance. also, writes-behind may happen on
- * handles that do not have write access, because the i/o manager picks some handle,
- * not necessarily the same one that writing was originally done with. */
- #ifdef EXPLICIT_CACHING
- if (!IrpSp->FileObject->PrivateCacheMap)
- {
- CcInitializeCacheMap(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize, FALSE, &rdrExt->callbacks, IrpSp->FileObject->FsContext);//(PVOID)din->Context1);
- CcSetAdditionalCacheAttributes(IrpSp->FileObject, FALSE, TRUE);
- /* could do a call to CcSetReadAheadGranularity here */
- }
- #endif
-
- if (!(ccb->access & FILE_READ_DATA) && !(Irp->Flags & IRP_PAGING_IO))
- SYNC_FAIL(STATUS_ACCESS_DENIED);
-
- if (!IrpSp->Parameters.Read.Length)
- SYNC_FAIL(STATUS_SUCCESS);
-
- offset = IrpSp->Parameters.Read.ByteOffset;
- length = IrpSp->Parameters.Read.Length;
-
- FsRtlEnterFileSystem();
- SLOCK_FCB;
- if (!(Irp->Flags & IRP_PAGING_IO) && fcb->lock)
- {
- if (!FsRtlCheckLockForReadAccess(fcb->lock, Irp))
- {
- UNLOCK_FCB;
- FsRtlExitFileSystem();
- SYNC_FAIL(STATUS_FILE_LOCK_CONFLICT);
- }
- }
-
- /* fast out for reads starting beyond eof */
- if (offset.QuadPart > fcb->ValidDataLength.QuadPart)
- {
- UNLOCK_FCB;
- FsRtlExitFileSystem();
- SYNC_FAIL(STATUS_END_OF_FILE);
- }
-
- /* pre-truncate reads */
- if (offset.QuadPart + length > fcb->ValidDataLength.QuadPart)
- length = (ULONG)(fcb->ValidDataLength.QuadPart - offset.QuadPart);
- UNLOCK_FCB;
- FsRtlExitFileSystem();
-
- outPtr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
- if (!outPtr)
- SYNC_FAIL(STATUS_INSUFFICIENT_RESOURCES);
-
- #ifdef EXPLICIT_CACHING
- /* this block is used only when a) caching functionality is compiled in,
- * b) this is not a paging i/o request, and c) this is not a no_cache req. */
- if (!(Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO)))
- {
- FsRtlEnterFileSystem();
- SLOCK_PAGING_FCB;
- ttlread = 0;
- try
- {
- if (!CcCopyRead(IrpSp->FileObject, &offset, length, TRUE, outPtr, &Irp->IoStatus))
- {
- UNLOCK_PAGING_FCB;
- FsRtlExitFileSystem();
- SYNC_FAIL(STATUS_UNSUCCESSFUL);
- }
- ttlread = Irp->IoStatus.Information;
- }
- except (EXCEPTION_EXECUTE_HANDLER)
- {
- STATUS(STATUS_UNSUCCESSFUL, 0);
- }
- /* update byteoffset when this is not a paging or async request */
- if (Irp->IoStatus.Status != STATUS_UNSUCCESSFUL && IoIsOperationSynchronous(Irp) && !(Irp->Flags & IRP_PAGING_IO))
- IrpSp->FileObject->CurrentByteOffset.QuadPart = offset.QuadPart + ttlread;
- UNLOCK_PAGING_FCB;
- FsRtlExitFileSystem();
- if (Irp->IoStatus.Status == STATUS_UNSUCCESSFUL)
- SYNC_FAIL(STATUS_UNSUCCESSFUL);
- }
- else
- #endif
- {
- FsRtlEnterFileSystem();
- SLOCK_FCB;
- for (currpos = ttlread = 0; ttlread < length; )
- {
- toread = length - currpos;
- toread = (toread > TRANSFER_CHUNK_SIZE) ? TRANSFER_CHUNK_SIZE : toread;
- curroff.QuadPart = offset.QuadPart + currpos;
- status = uc_read(fcb->fid, curroff, toread, &read, outPtr);
-
- if (status == 0)
- {
- ttlread += read;
- currpos += read;
- if (read < toread)
- goto end;
- continue;
- }
- UNLOCK_FCB;
- FsRtlExitFileSystem();
- switch (status)
- {
- case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT;
- case IFSL_IS_A_DIR: SYNC_FAIL(STATUS_INVALID_DEVICE_REQUEST);
- case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER);
- default: SYNC_FAIL(STATUS_UNSUCCESSFUL);
- }
- }
- end:
- /* update byteoffset when this is not a paging or async request */
- if (IoIsOperationSynchronous(Irp) && !(Irp->Flags & IRP_PAGING_IO))
- IrpSp->FileObject->CurrentByteOffset.QuadPart = offset.QuadPart + ttlread;
- UNLOCK_FCB;
- FsRtlExitFileSystem();
- }
-
- if (ttlread == 0) {
- SYNC_FAIL2(STATUS_END_OF_FILE, ttlread);
- } else {
- SYNC_FAIL2(STATUS_SUCCESS, ttlread);
- }
- }
-
-
-
- /**********************************************************
- * AfsRdrWrite
- * - handle writes
- **********************************************************/
- NTSTATUS AfsRdrWrite(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb)
- {
- struct WriteKOut *p;
- void *ptr, *outPtr;
- ULONG length, written;
- LARGE_INTEGER offset, end;
- NTSTATUS status;
- afs_ccb_t *ccb;
- CC_FILE_SIZES sizes, oldSizes;
- ULONG towrite, ttlwritten, currpos;
- LARGE_INTEGER curroff;
- BOOLEAN change, paging_lock;
-
- ccb = IrpSp->FileObject->FsContext2;
- if (IsDeviceFile(IrpSp->FileObject) || (ccb->attribs & FILE_ATTRIBUTE_DIRECTORY))
- SYNC_FAIL(STATUS_INVALID_DEVICE_REQUEST);
-
- /* since we will be performing io on this instance, start caching (see above). */
- #ifdef EXPLICIT_CACHING
- if (!IrpSp->FileObject->PrivateCacheMap)
- {
- CcInitializeCacheMap(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize, FALSE, &rdrExt->callbacks, IrpSp->FileObject->FsContext);//(PVOID)din->Context1);
- CcSetAdditionalCacheAttributes(IrpSp->FileObject, FALSE, TRUE);
- }
- #endif
-
- if (!(ccb->access & FILE_WRITE_DATA) && !(Irp->Flags & IRP_PAGING_IO))
- SYNC_FAIL(STATUS_ACCESS_DENIED);
-
- /* fast-out for zero-length i/o */
- if (!IrpSp->Parameters.Write.Length)
- SYNC_FAIL(STATUS_SUCCESS);
-
- if (!(outPtr = AfsFindBuffer(Irp)))
- SYNC_FAIL(STATUS_INSUFFICIENT_RESOURCES);
-
- FsRtlEnterFileSystem();
- SLOCK_FCB;
-
- if (!(Irp->Flags & IRP_PAGING_IO) && fcb->lock)
- {
- if (!FsRtlCheckLockForWriteAccess(fcb->lock, Irp))
- {
- UNLOCK_FCB;
- FsRtlExitFileSystem();
- SYNC_FAIL(STATUS_FILE_LOCK_CONFLICT);
- }
- }
-
- if (IrpSp->Parameters.Write.ByteOffset.HighPart == 0xffffffff &&
- IrpSp->Parameters.Write.ByteOffset.LowPart == FILE_WRITE_TO_END_OF_FILE)
- offset.QuadPart = fcb->FileSize.QuadPart;
- else
- offset = IrpSp->Parameters.Write.ByteOffset;
- length = IrpSp->Parameters.Write.Length;
- UNLOCK_FCB;
-
- #ifdef EXPLICIT_CACHING
- if (!(Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO)))
- {
- /* extend file for cached writes */
- LOCK_PAGING_FCB;
- if (offset.QuadPart + length > fcb->FileSize.QuadPart)
- {
- end.QuadPart = offset.QuadPart + length;
- fcb->AllocationSize = fcb->FileSize = fcb->ValidDataLength = end;
- LOCK_FCB;
- CcSetFileSizes(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize);
- UNLOCK_FCB;
- /*ret = *//*CcZeroData(IrpSp->FileObject, &oldSizes.FileSize, &end, FALSE);*/ /* should wait? */
- }
- try
- {
- if (!CcCopyWrite(IrpSp->FileObject, &offset, length, TRUE, outPtr))
- {
- UNLOCK_PAGING_FCB;
- FsRtlExitFileSystem();
- SYNC_FAIL(STATUS_UNSUCCESSFUL);
- }
- }
- except (EXCEPTION_EXECUTE_HANDLER)
- {
- STATUS(STATUS_UNSUCCESSFUL, 0);
- }
-
- ttlwritten = written = length;
- if (Irp->IoStatus.Status != STATUS_UNSUCCESSFUL && IoIsOperationSynchronous(Irp) && !(Irp->Flags & IRP_PAGING_IO))
- IrpSp->FileObject->CurrentByteOffset.QuadPart = offset.QuadPart + ttlwritten;
- UNLOCK_PAGING_FCB;
- FsRtlExitFileSystem();
- if (Irp->IoStatus.Status == STATUS_UNSUCCESSFUL)
- SYNC_FAIL(STATUS_UNSUCCESSFUL);
- }
- else
- #endif
- {
- while (1)
- {
- if (offset.QuadPart + length > fcb->FileSize.QuadPart)
- change = 1;
- else
- change = 0;
- if (change && !(Irp->Flags & IRP_PAGING_IO))
- paging_lock = 1;
- else
- paging_lock = 0;
- if (paging_lock)
- LOCK_PAGING_FCB;
- LOCK_FCB;
- if (change)
- {
- if (Irp->Flags & IRP_PAGING_IO)
- {
- /* the input buffer and length is for a full page. ignore this. */
- if (offset.QuadPart > fcb->FileSize.QuadPart)
- {
- /* paging lock cannot be held here, so no need to release */
- UNLOCK_FCB;
- FsRtlExitFileSystem();
- SYNC_FAIL2(STATUS_SUCCESS, length);
- }
- length = (ULONG)(fcb->FileSize.QuadPart - offset.QuadPart);
- break;
- }
- else
- {
- if (!change)
- {
- /* paging lock cannot be held here, so no need to release */
- UNLOCK_FCB;
- continue;
- }
- end.QuadPart = offset.QuadPart + length;
- fcb->AllocationSize = fcb->FileSize = fcb->ValidDataLength = end;
- CcSetFileSizes(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize);
- if (paging_lock)
- UNLOCK_PAGING_FCB;
- break;
- }
- }
- else
- {
- if (paging_lock)
- UNLOCK_PAGING_FCB;
- break;
- }
- }
-
- for (currpos = ttlwritten = 0; ttlwritten < length; )
- {
- towrite = length - currpos;
- towrite = (towrite > TRANSFER_CHUNK_SIZE) ? TRANSFER_CHUNK_SIZE : towrite;
- curroff.QuadPart = offset.QuadPart + currpos;
- status = uc_write(fcb->fid, curroff, towrite, &written, outPtr);
- if (status == 0)
- {
- ttlwritten += written;
- currpos += written;
- if (written < towrite)
- goto end;
- continue;
- }
- UNLOCK_FCB;
- FsRtlExitFileSystem();
- switch (status)
- {
- case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT;
- case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER);
- case IFSL_OVERQUOTA: SYNC_FAIL(STATUS_DISK_FULL);
- default: SYNC_FAIL(STATUS_UNSUCCESSFUL);
- }
- }
- end:
- if (IoIsOperationSynchronous(Irp) && !(Irp->Flags & IRP_PAGING_IO))
- IrpSp->FileObject->CurrentByteOffset.QuadPart = offset.QuadPart + ttlwritten;
- UNLOCK_FCB;
- FsRtlExitFileSystem();
- }
-
- /* if we failed a write, we would not be here. so, we must
- * tell the vmm that all data was written. */
- if (Irp->Flags & IRP_PAGING_IO)
- SYNC_FAIL2(STATUS_SUCCESS, IrpSp->Parameters.Write.Length);
- SYNC_FAIL2(STATUS_SUCCESS, ttlwritten);
- }
-
-
- static wchar_t *SEARCH_MATCH_ALL = L"**";
-
- /**********************************************************
- * AfsRdrDirCtrl
- * - handle directory notification callbacks
- * - handle directory enumeration
- *
- * TOD: This code must performing globbing - it does not currently do so.
- **********************************************************/
- NTSTATUS AfsRdrDirCtrl(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb)
- {
- struct EnumDirKOut *p;
- LARGE_INTEGER size, creation, access, change, written;
- ULONG attribs, count;
- char buf[2048];
- afs_ccb_t *ccb;
- void *outPtr, *info, *pre_adj_info;
- FILE_BOTH_DIR_INFORMATION *info_both, *info_both_prev;
- FILE_DIRECTORY_INFORMATION *info_dir, *info_dir_prev;
- FILE_NAMES_INFORMATION *info_names, *info_names_prev;
- int info_size;
- readdir_data_t *ii;
- ULONG x, buf_size;
- LARGE_INTEGER last_cookie;
- BOOLEAN overflow;
- NTSTATUS status;
- FILE_NOTIFY_INFORMATION *notify;
-
- if (IsDeviceFile(IrpSp->FileObject))
- SYNC_FAIL(STATUS_INVALID_DEVICE_REQUEST);
-
- if (IrpSp->MinorFunction == IRP_MN_NOTIFY_CHANGE_DIRECTORY)
- {
- ccb = IrpSp->FileObject->FsContext2;
- ccb->str.Length = wcslen(ccb->name)*sizeof(wchar_t);
- ccb->str.MaximumLength = ccb->str.Length + sizeof(wchar_t);
- ccb->str.Buffer = ccb->name;
-
- FsRtlEnterFileSystem();
- LOCK_FCB;
- FsRtlNotifyFullChangeDirectory(rdrExt->notifyList, &rdrExt->listHead,
- ccb,
- (STRING*)&ccb->str,
- IrpSp->Flags & SL_WATCH_TREE,
- FALSE,
- /*FILE_NOTIFY_CHANGE_FILE_NAME,*/IrpSp->Parameters.NotifyDirectory.CompletionFilter,
- Irp, NULL, NULL);
- UNLOCK_FCB;
- FsRtlExitFileSystem();
- /* do NOT complete request; that will be done by fsrtlnotify functions */
- return STATUS_PENDING;
- }
-
- if (IrpSp->MinorFunction != IRP_MN_QUERY_DIRECTORY)
- SYNC_FAIL(STATUS_NOT_IMPLEMENTED);
-
- if ( IrpSp->Parameters.QueryDirectory.FileInformationClass != FileBothDirectoryInformation &&
- IrpSp->Parameters.QueryDirectory.FileInformationClass != FileDirectoryInformation &&
- IrpSp->Parameters.QueryDirectory.FileInformationClass != FileNamesInformation)
- {
- rpt0(("enum", "enum class %d not supported", IrpSp->Parameters.QueryDirectory.FileInformationClass));
- SYNC_FAIL(STATUS_NOT_IMPLEMENTED);
- }
-
- ccb = IrpSp->FileObject->FsContext2;
-
- if (!(outPtr = AfsFindBuffer(Irp)))
- SYNC_FAIL(STATUS_INSUFFICIENT_RESOURCES);
-
- if (IrpSp->Flags & SL_INDEX_SPECIFIED)
- {
- /* we were told where to start our search; afsd should scrub this input */
- ccb->cookie.QuadPart = IrpSp->Parameters.QueryDirectory.FileIndex;
- if (ccb->filter && ccb->filter != SEARCH_MATCH_ALL)
- ExFreePoolWithTag(ccb->filter, AFS_RDR_TAG);
- ccb->filter = SEARCH_MATCH_ALL;
- }
- else if (IrpSp->Flags & SL_RESTART_SCAN ||
- ((IrpSp->Flags & SL_RETURN_SINGLE_ENTRY) && ccb->cookie.QuadPart == 0))
- {
- /* copy new filter string into nonpaged memory */
- ccb->cookie.QuadPart = 0;
- if (ccb->filter && ccb->filter != SEARCH_MATCH_ALL)
- ExFreePoolWithTag(ccb->filter, AFS_RDR_TAG);
- if (IrpSp->Parameters.QueryDirectory.FileName)
- {
- buf_size = IrpSp->Parameters.QueryDirectory.FileName->Length+6;
- ccb->filter = ExAllocatePoolWithTag(NonPagedPool, buf_size, AFS_RDR_TAG);
- RtlCopyMemory(ccb->filter, IrpSp->Parameters.QueryDirectory.FileName->Buffer, buf_size);
- ccb->filter[IrpSp->Parameters.QueryDirectory.FileName->Length / sizeof(WCHAR)] = L'\0';
- }
- else
- ccb->filter = SEARCH_MATCH_ALL;
- }
-
- if (IrpSp->Flags & SL_RETURN_SINGLE_ENTRY)
- count = 1;
- buf_size = 2040;
-
- status = uc_readdir(fcb->fid, ccb->cookie, ccb->filter, &count, buf, &buf_size);
-
- switch (status)
- {
- case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT;
- case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER);
- default: SYNC_FAIL(STATUS_UNSUCCESSFUL);
- case 0: break;
- }
-
- switch (IrpSp->Parameters.QueryDirectory.FileInformationClass)
- {
- case FileBothDirectoryInformation:
- info_size = sizeof(FILE_BOTH_DIR_INFORMATION);
- break;
- case FileDirectoryInformation:
- info_size = sizeof(FILE_DIRECTORY_INFORMATION);
- break;
- case FileNamesInformation:
- info_size = sizeof(FILE_NAMES_INFORMATION);
- break;
- default:
- SYNC_FAIL(STATUS_NOT_IMPLEMENTED);
- }
-
- info = (FILE_BOTH_DIR_INFORMATION *)outPtr;
- ii = (readdir_data_t *)buf;
- Irp->IoStatus.Information = 0;
- if (!count)
- {
- if (IrpSp->Flags & SL_RETURN_SINGLE_ENTRY && ccb->cookie.QuadPart == 0)
- SYNC_FAIL(STATUS_NO_SUCH_FILE);
- SYNC_FAIL(STATUS_NO_MORE_FILES);
- }
-
- info_both_prev = NULL;
- info_dir_prev = NULL;
- info_names_prev = NULL;
- if (IrpSp->Flags & SL_RETURN_SINGLE_ENTRY)
- count = 1;
-
- for (x = 0; x < count; x++)
- {
- pre_adj_info = info;
-
- /* must explicitly align second and subsequent entries on 8-byte boundaries */
- if (((ULONG)info & 0x7) && x)
- info = (void*)(((ULONG)info) + (8-((ULONG)info & 0x7)));
-
- overflow = ((long)info + info_size + (long)ii->name_length >
- (long)outPtr + (long)IrpSp->Parameters.QueryDirectory.Length);
- if (overflow && x != 0)
- {
- ccb->cookie = ii->cookie;
- SYNC_FAIL2(STATUS_SUCCESS, (long)pre_adj_info - (long)outPtr);
- }
-
- memset(info, 0, info_size);
- switch (IrpSp->Parameters.QueryDirectory.FileInformationClass)
- {
- case FileBothDirectoryInformation:
- info_both = info;
- if (info_both_prev)
- info_both_prev->NextEntryOffset = (char*)info_both - (char*)info_both_prev;
-
- info_both->NextEntryOffset = 0;
- info_both->FileIndex = (ULONG)ii->cookie.QuadPart;
- info_both->CreationTime.QuadPart = AfsTimeToWindowsTime(ii->creation.QuadPart);
- info_both->LastAccessTime.QuadPart = AfsTimeToWindowsTime(ii->access.QuadPart);
- info_both->LastWriteTime.QuadPart = AfsTimeToWindowsTime(ii->write.QuadPart);
- info_both->ChangeTime.QuadPart = AfsTimeToWindowsTime(ii->change.QuadPart);
- info_both->EndOfFile = info_both->AllocationSize = ii->size;
- info_both->FileAttributes = ii->attribs;/*| FILE_ATTRIBUTE_READONLY*/;
- info_both->EaSize = 0;
- info_both->ShortNameLength = ii->short_name_length;
- info_both->FileNameLength = ii->name_length;
- RtlCopyMemory(info_both->ShortName, ii->short_name, ii->short_name_length*sizeof(WCHAR));
-
- if (overflow)
- {
- Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
- info_both->FileNameLength = 0;
- info_both->FileName[0] = L'\0';
- goto done;
- }
-
- RtlCopyMemory(info_both->FileName, ii->name, ii->name_length*sizeof(WCHAR));
- info_both_prev = info_both;
- break;
-
- case FileDirectoryInformation:
- info_dir = info;
- if (info_dir_prev)
- info_dir_prev->NextEntryOffset = (char*)info_dir - (char*)info_dir_prev;
-
- info_dir->NextEntryOffset = 0;
- info_dir->FileIndex = (ULONG)ii->cookie.QuadPart;
- info_dir->CreationTime.QuadPart = AfsTimeToWindowsTime(ii->creation.QuadPart);
- info_dir->LastAccessTime.QuadPart = AfsTimeToWindowsTime(ii->access.QuadPart);
- info_dir->LastWriteTime.QuadPart = AfsTimeToWindowsTime(ii->write.QuadPart);
- info_dir->ChangeTime.QuadPart = AfsTimeToWindowsTime(ii->change.QuadPart);
- info_dir->EndOfFile = info_dir->AllocationSize = ii->size;
- info_dir->FileAttributes = ii->attribs /*| FILE_ATTRIBUTE_READONLY*/;
- info_dir->FileNameLength = ii->name_length;
-
- if (overflow)
- {
- Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
- info_dir->FileNameLength = 0;
- info_dir->FileName[0] = L'\0';
- goto done;
- }
-
- RtlCopyMemory(info_dir->FileName, ii->name, ii->name_length*sizeof(WCHAR));
- info_dir_prev = info_dir;
- break;
-
- case FileNamesInformation:
- info_names = info;
- if (info_names_prev)
- info_names_prev->NextEntryOffset = (char*)info_names - (char*)info_names_prev;
-
- info_names->NextEntryOffset = 0;
- info_names->FileIndex = (ULONG)ii->cookie.QuadPart;
- info_names->FileNameLength = ii->name_length;
-
- if (overflow)
- {
- Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
- info_names->FileNameLength = 0;
- info_names->FileName[0] = L'\0';
- goto done;
- }
-
- RtlCopyMemory(info_names->FileName, ii->name, ii->name_length*sizeof(WCHAR));
- info_names_prev = info_names;
- break;
- }
-
- info = (void*)(((ULONG)info) + info_size + (ULONG)ii->name_length*sizeof(WCHAR));
- ii = (readdir_data_t *)(((unsigned char *)ii) + sizeof(readdir_data_t) + ii->name_length);
- last_cookie = ii->cookie;
- }
-
- Irp->IoStatus.Status = STATUS_SUCCESS;
- done:
- ccb->cookie = last_cookie;
-
- SYNC_FAIL2(Irp->IoStatus.Status, (long)info - (long)outPtr);
- }
-
-
-
-
- /**********************************************************
- * AfsRdrQueryInfo
- * - handle stat calls
- **********************************************************/
- NTSTATUS AfsRdrQueryInfo(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb)
- {
- FILE_BASIC_INFORMATION *infoBasic;
- FILE_NAME_INFORMATION *infoName;
- FILE_STANDARD_INFORMATION *infoStandard;
- FILE_POSITION_INFORMATION *infoPosition;
- FILE_ALL_INFORMATION *infoAll;
- FILE_INTERNAL_INFORMATION *infoInternal;
- LARGE_INTEGER size, creation, access, change, written;
- ULONG attribs;
- long count;
- afs_ccb_t *ccb;
- char *outPtr;
- NTSTATUS status;
- wchar_t *start;
-
- if (IsDeviceFile(IrpSp->FileObject))
- SYNC_FAIL(STATUS_UNSUCCESSFUL); // what should happen?
-
- if (!(outPtr = AfsFindBuffer(Irp)))
- SYNC_FAIL(STATUS_INSUFFICIENT_RESOURCES);
-
- ccb = IrpSp->FileObject->FsContext2;
-
- status = uc_stat(fcb->fid, &attribs, &size, &creation, &access, &change, &written);
- switch (status)
- {
- case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT;
- case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER);
- default: SYNC_FAIL(STATUS_UNSUCCESSFUL);
- case 0: break;
- }
-
- /* afsd does not maintain instance-specific data, so we adjust here */
- if (ccb->access & FILE_READ_DATA && !(ccb->access & FILE_WRITE_DATA))
- attribs |= FILE_ATTRIBUTE_READONLY;
-
- (void*)infoBasic = (void*)infoName = (void*)infoPosition = (void*)infoStandard = (void*)infoInternal = NULL;
- switch (IrpSp->Parameters.QueryFile.FileInformationClass)
- {
- case FileBasicInformation:
- infoBasic = (FILE_BASIC_INFORMATION*)outPtr;
- break;
- case FileNameInformation:
- infoName = (FILE_NAME_INFORMATION*)outPtr;
- break;
- case FileStandardInformation:
- infoStandard = (FILE_STANDARD_INFORMATION*)outPtr;
- break;
- case FilePositionInformation:
- infoPosition = (FILE_POSITION_INFORMATION*)outPtr;
- break;
- case FileAllInformation:
- infoAll = (FILE_ALL_INFORMATION*)outPtr;
- infoBasic = &infoAll->BasicInformation;
- infoName = &infoAll->NameInformation;
- infoStandard = &infoAll->StandardInformation;
- infoPosition = &infoAll->PositionInformation;
- break;
- case FileInternalInformation:
- infoInternal = (FILE_INTERNAL_INFORMATION*)outPtr;
- break;
- default:
- STATUS(STATUS_NOT_IMPLEMENTED, 0);
- break;
- }
-
- if (infoBasic)
- {
- memset(infoBasic, 0, sizeof(FILE_BASIC_INFORMATION));
- infoBasic->FileAttributes = attribs;
- infoBasic->CreationTime.QuadPart = AfsTimeToWindowsTime(creation.QuadPart);
- infoBasic->LastAccessTime.QuadPart = AfsTimeToWindowsTime(access.QuadPart);
- infoBasic->LastWriteTime.QuadPart = AfsTimeToWindowsTime(written.QuadPart);
- infoBasic->ChangeTime.QuadPart = AfsTimeToWindowsTime(change.QuadPart);
- STATUS(STATUS_SUCCESS, sizeof(FILE_BASIC_INFORMATION));
- //KdPrint(("query basicinfo %d,%d %x,%I64d,%I64d\n", fcb->fid, (ULONG)IrpSp->FileObject->FsContext2, infoBasic->FileAttributes, infoBasic->CreationTime.QuadPart, infoBasic->ChangeTime.QuadPart));
- }
-
- if (infoName)
- {
- memset(infoName, 0, sizeof(FILE_NAME_INFORMATION));
- start = ccb->name;
- count = (long)(*(start+1) - L'0');
- if (count > 9 || count < 0)
- SYNC_FAIL(STATUS_OBJECT_NAME_INVALID);
- if (count || *start == L'0')
- {
- for ( ; count >= 0 && start; count--)
- start = wcschr(start+1, L'\\');
- if (!start)
- SYNC_FAIL(STATUS_OBJECT_NAME_INVALID);
- }
- infoName->FileNameLength = wcslen(start)*sizeof(WCHAR);
- if (((IrpSp->Parameters.QueryFile.FileInformationClass == FileAllInformation) ? sizeof(*infoAll) : sizeof(*infoName)) +
- infoName->FileNameLength > IrpSp->Parameters.QueryFile.Length)
- {
- infoName->FileNameLength = 0;
- infoName->FileName[0] = L'\0';
- STATUS(STATUS_BUFFER_OVERFLOW, sizeof(FILE_NAME_INFORMATION));
- //KdPrint(("query overflowing buffer %d\n", IrpSp->Parameters.QueryFile.Length));
- }
- else
- { //TODO:check filename is correct/correct format
- StringCbCopy(infoName->FileName, IrpSp->Parameters.QueryFile.Length - sizeof(*infoName), start);
- STATUS(STATUS_SUCCESS, sizeof(FILE_NAME_INFORMATION) + (infoName->FileNameLength - sizeof(WCHAR)));
- }
- //KdPrint(("query nameinfo %ws from %ws\n", infoName->FileName, ccb->name));
- }
-
- if (infoStandard)
- {
- memset(infoStandard, 0, sizeof(FILE_STANDARD_INFORMATION));
- infoStandard->AllocationSize.QuadPart = size.QuadPart;
- infoStandard->EndOfFile.QuadPart = size.QuadPart;
- infoStandard->NumberOfLinks = 1;
- infoStandard->DeletePending = (fcb->delPending == 1);
- infoStandard->Directory = (attribs & FILE_ATTRIBUTE_DIRECTORY)?TRUE:FALSE; //TODO:check if flag is valid at this point
- STATUS(STATUS_SUCCESS, sizeof(FILE_STANDARD_INFORMATION));
- //KdPrint(("query stdinfo %d,%d %I64d,%s\n", fcb->fid, (ULONG)IrpSp->FileObject->FsContext2, infoStandard->EndOfFile.QuadPart, infoStandard->Directory?"dir":"file"));
- }
-
- if (infoPosition)
- {
- infoPosition->CurrentByteOffset = IrpSp->FileObject->CurrentByteOffset;
- STATUS(STATUS_SUCCESS, sizeof(FILE_POSITION_INFORMATION));
- //KdPrint(("query position %d,%d %I64d\n", fcb, (ULONG)IrpSp->FileObject->FsContext2, infoPosition->CurrentByteOffset.QuadPart));
- }
-
- if (IrpSp->Parameters.QueryFile.FileInformationClass == FileAllInformation)
- {
- if (!infoName->FileNameLength)
- STATUS(STATUS_BUFFER_OVERFLOW, sizeof(FILE_ALL_INFORMATION));
- else
- STATUS(STATUS_SUCCESS, sizeof(FILE_ALL_INFORMATION) + (infoName->FileNameLength - sizeof(WCHAR)));
- }
-
- if (infoInternal)
- {
- infoInternal->IndexNumber.QuadPart = fcb->fid;
- STATUS(STATUS_SUCCESS, sizeof(FILE_INTERNAL_INFORMATION));
- }
-
- status = Irp->IoStatus.Status;
- COMPLETE;
- return status;
- }
-
-
-
-
- /**********************************************************
- * AfsRdrSetInfo
- * - handle setting mod time
- * - handle deleting
- * - handle truncation/extension
- * - handle renaming
- **********************************************************/
- NTSTATUS AfsRdrSetInfo(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb)
- {
- struct SetInfoKOut *p;
- afs_fcb_t *fcbt;
- afs_ccb_t *ccb;
- FILE_DISPOSITION_INFORMATION *infoDisp;
- FILE_BASIC_INFORMATION *infoBasic;
- FILE_END_OF_FILE_INFORMATION *infoLength;
- FILE_RENAME_INFORMATION *infoRename;
- FILE_POSITION_INFORMATION *infoPosition;
- NTSTATUS ret;
- wchar_t *buf, *part, *ptr;
- ULONG size, new_fid;
- NTSTATUS status;
-
- if ( IrpSp->FileObject->FileName.Length == 0)
- SYNC_FAIL(STATUS_INVALID_DEVICE_REQUEST);
-
- ccb = IrpSp->FileObject->FsContext2;
-
- switch (IrpSp->Parameters.SetFile.FileInformationClass)
- {
- /* delete disposition */
- case FileDispositionInformation:
- infoDisp = Irp->AssociatedIrp.SystemBuffer;
-
- FsRtlEnterFileSystem();
- LOCK_FCB;
-
- if (infoDisp->DeleteFile)
- {
- if (!MmFlushImageSection(&(fcb->sectionPtrs), MmFlushForDelete))
- {
- UNLOCK_FCB;
- FsRtlExitFileSystem();
- SYNC_FAIL(STATUS_ACCESS_DENIED);
- }
- fcb->delPending |= 0x1;
- }
- else
- fcb->delPending &= ~0x1;
- UNLOCK_FCB;
- FsRtlExitFileSystem();
- SYNC_RET(STATUS_SUCCESS);
-
- /*case FileAllocationInformation:*/
- case FileEndOfFileInformation:
- /* ignore extensions caused by paging requests*/
- if (Irp->Flags & IRP_PAGING_IO)
- SYNC_FAIL(STATUS_SUCCESS);
-
- infoLength = Irp->AssociatedIrp.SystemBuffer;
-
- FsRtlEnterFileSystem();
- LOCK_PAGING_FCB;
- LOCK_FCB;
- if (IrpSp->Parameters.SetFile.AdvanceOnly && (infoLength->EndOfFile.QuadPart > fcb->FileSize.QuadPart) ||
- !IrpSp->Parameters.SetFile.AdvanceOnly && (infoLength->EndOfFile.QuadPart < fcb->FileSize.QuadPart))
- {
- status = uc_trunc(fcb->fid, infoLength->EndOfFile);
- /* because it is not written to the server immediately, this error will not always happen */
- if (status == IFSL_OVERQUOTA)
- {
- UNLOCK_FCB;
- UNLOCK_PAGING_FCB;
- FsRtlExitFileSystem();
- SYNC_FAIL(STATUS_DISK_FULL);
- }
- }
- fcb->FileSize = fcb->AllocationSize = fcb->ValidDataLength = infoLength->EndOfFile;
- CcSetFileSizes(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize);
- //CcPurgeCacheSection(IrpSp->FileObject->SectionObjectPointer, &fcb->AllocationSize, 0, FALSE);
- UNLOCK_FCB;
- UNLOCK_PAGING_FCB;
- FsRtlExitFileSystem();
- SYNC_FAIL(STATUS_SUCCESS);
-
- case FileBasicInformation:
- infoBasic = Irp->AssociatedIrp.SystemBuffer;
- status = uc_setinfo(fcb->fid, infoBasic->FileAttributes, infoBasic->CreationTime, infoBasic->LastAccessTime, infoBasic->ChangeTime, infoBasic->LastWriteTime);
- SYNC_FAIL(STATUS_SUCCESS);
-
- case FileRenameInformation:
- //KdPrint(("set rename %d\n", fcb->fid));
- infoRename = Irp->AssociatedIrp.SystemBuffer;
- new_fid = fcb->fid;
- //rpt1(("setinfo", "rename %d,%d %d,%ws", ExtractFid(fcb), (ULONG)IrpSp->FileObject->FsContext2, infoRename->ReplaceIfExists, infoRename->FileName));
-
- if (IrpSp->Parameters.SetFile.FileObject)
- fcbt = FindFcb(IrpSp->Parameters.SetFile.FileObject);
-
- //null-terminate all strings into uc_rename?
-
- if (IrpSp->Parameters.SetFile.FileObject == NULL &&
- infoRename->RootDirectory == NULL)
- {
- WCHAR fname[MAX_PATH];
- StringCchCopyNW(fname, MAX_PATH-1, infoRename->FileName, infoRename->FileNameLength/sizeof(WCHAR));
- uc_rename(fcb->fid, ccb->name+2, NULL, fname, &new_fid);
- fcb->fid = new_fid;
- }
- else if (IrpSp->Parameters.SetFile.FileObject != NULL &&
- infoRename->RootDirectory == NULL)
- {
- WCHAR fname[300];
- StringCchCopyNW(fname, 300-1, infoRename->FileName, infoRename->FileNameLength/sizeof(WCHAR));
- uc_rename(fcb->fid, ccb->name+2, fcbt->ccb_list->name+2, fname, &new_fid);
- fcb->fid = new_fid;
- }
- else
- {
- /* FIXFIX: implement this case, although we have never seen it called */
- SYNC_RET(STATUS_UNSUCCESSFUL);
-
- /*fcbt = FindFcb(IrpSp->Parameters.SetFile.FileObject);
- p->CurrNameOff = 0;
- StringCbCopyW(buf, size, fcb->name);
- p->NewNameOff = wcslen(buf)+1;
- StringCbCopyNW(buf + p->NewNameOff,
- size - p->NewNameOff,
- infoRename->FileName,
- infoRename->FileNameLength*sizeof(wchar_t));
- buf[p->NewNameOff+infoRename->FileNameLength] = L'\0';
- p->NewDirOff = p->NewNameOff + wcslen(buf + p->NewNameOff)+1;
- StringCbCopyW(buf + p->NewDirOff,
- size - p->NewDirOff,
- fcbt->name);*/
- }
- SYNC_RET(STATUS_SUCCESS);
- break;
-
- case FilePositionInformation:
- infoPosition = Irp->AssociatedIrp.SystemBuffer;
- IrpSp->FileObject->CurrentByteOffset = infoPosition->CurrentByteOffset;
- SYNC_FAIL(STATUS_SUCCESS);
-
- default:
- KdPrint(("set unsupp %d type %d\n", fcb->fid, IrpSp->Parameters.SetFile.FileInformationClass));
- SYNC_FAIL(STATUS_NOT_IMPLEMENTED);
- }
-
- SYNC_FAIL(STATUS_UNSUCCESSFUL);
- }
-
- long
- dc_break_callback(ULONG fid)
- {
- afs_fcb_t *fcb;
- int pos;
- USHORT len;
- UNICODE_STRING *s;
-
- LOCK_FCB_LIST;
-
- fcb = find_fcb(fid);
- if (!fcb)
- {
- UNLOCK_FCB_LIST;
- return 1; /* we are done with this file */
- }
-
- ASSERT(fcb->ccb_list);
-
- len = (wcslen(fcb->ccb_list->name) + 10) * sizeof(wchar_t);
- s = ExAllocatePool(NonPagedPool, sizeof(UNICODE_STRING)+len+sizeof(wchar_t));
- s->Length = len;
- s->MaximumLength = len + sizeof(wchar_t);
- s->Buffer = (PWSTR)(s+1);
-
- /* we are making a bogus change notification for now, because
- * it does what we need.
- */
- StringCbCopyW((PWSTR)(s+1), len, fcb->ccb_list->name);
- if (s->Buffer[wcslen(s->Buffer) - 1] != L'\\')
- StringCbCatW(s->Buffer, len, L"\\");
- pos = wcslen(s->Buffer);
- StringCbCatW(s->Buffer, len, L"jj");
-
- KdPrint(("break callback on %d %ws %ws\n", fid, fcb->ccb_list->name, fcb->ccb_list->name+pos));
-
- FsRtlNotifyFullReportChange(rdrExt->notifyList, &rdrExt->listHead,
- (PSTRING)s, (USHORT)pos*sizeof(wchar_t), NULL, NULL,
- FILE_NOTIFY_CHANGE_FILE_NAME/*FILE_NOTIFY_VALID_MASK/*FILE_NOTIFY_CHANGE_FILE_NAME*/, FILE_ACTION_ADDED, NULL);
-
- ExFreePool(s);
- UNLOCK_FCB_LIST;
- return 0;
- }
-
- long
- dc_release_hooks(void)
- {
- KeSetEvent(&comExt->cancelEvent, 0, FALSE);
- return 0;
- }
-
- /**********************************************************
- * AfsRdrDeviceControl
- * - handle communication requests from fs, etc.
- * - handle ioctls
- **********************************************************/
- NTSTATUS AfsRdrDeviceControl(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb)
- {
- struct KOutEntry *entry;
- NTSTATUS ret;
- struct CbKIn *kin;
- USHORT offset;
- UNICODE_STRING nm;
- void *outPtr;
- ULONG key, code, length;
- LARGE_INTEGER wait;
-
- /* utility ioctls */
- if (DeviceObject == ComDevice &&
- IrpSp->FileObject->FsContext2 == COMM_IOCTL &&
- IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFSRDR_IOCTL)
- {
- outPtr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
- if (!outPtr)
- SYNC_FAIL(STATUS_INSUFFICIENT_RESOURCES);
-
- wait.QuadPart = -1000;
- while (rpc_set_context(IrpSp->FileObject->FsContext) != 0) /* if there are no open thread spots... */
- KeDelayExecutionThread(KernelMode, FALSE, &wait); /* ...wait */
- code = uc_ioctl_write(IrpSp->Parameters.DeviceIoControl.InputBufferLength,
- Irp->AssociatedIrp.SystemBuffer,
- (ULONG*)&key);
- length = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
- if (!code)
- code = uc_ioctl_read(key, &length, outPtr);
- rpc_remove_context();
-
- switch (code)
- {
- case IFSL_SUCCESS:
- STATUS(STATUS_SUCCESS, length);
- break;
- default:
- STATUS(STATUS_UNSUCCESSFUL, 0);
- break;
- }
- }
- /* downcalls by afsd */
- else if (DeviceObject == ComDevice &&
- IrpSp->FileObject->FsContext2 == COMM_DOWNCALL &&
- IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFSRDR_DOWNCALL)
- {
- outPtr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
- if (!outPtr)
- SYNC_FAIL(STATUS_INSUFFICIENT_RESOURCES);
-
- wait.QuadPart = -1000;
- while (rpc_set_context(IrpSp->FileObject->FsContext) != 0) /* if there are no open thread spots... */
- KeDelayExecutionThread(KernelMode, FALSE, &wait); /* ...wait */
- code = rpc_call(IrpSp->Parameters.DeviceIoControl.InputBufferLength,
- Irp->AssociatedIrp.SystemBuffer,
- IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
- outPtr,
- &length);
- rpc_remove_context();
- switch (code)
- {
- case IFSL_SUCCESS:
- STATUS(STATUS_SUCCESS, length);
- break;
- default:
- STATUS(STATUS_UNSUCCESSFUL, 0);
- break;
- }
- }
- /* ioctl to get full file afs path (used by pioctl) */
- else if (DeviceObject == RdrDevice &&
- IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFSRDR_GET_PATH)
- {
- outPtr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
- if (!outPtr)
- SYNC_FAIL(STATUS_INSUFFICIENT_RESOURCES);
-
- StringCbCopyW(outPtr, IrpSp->Parameters.DeviceIoControl.OutputBufferLength, fcb->ccb_list->name+2);
-
- STATUS(STATUS_SUCCESS, (wcslen(outPtr)+1)*sizeof(wchar_t));
- }
- else
- {
- rpt0(("devctl", "devctl %d rejected", IrpSp->Parameters.DeviceIoControl.IoControlCode));
- SYNC_FAIL(STATUS_INVALID_DEVICE_REQUEST);
- }
-
- ret = Irp->IoStatus.Status;
- COMPLETE; /* complete with priority boost */
- return ret;
- }
-
-
-
- /**********************************************************
- * AfsRdrCleanup
- * - called when usermode handle count reaches zero
- **********************************************************/
- NTSTATUS AfsRdrCleanup(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb)
- {
- NTSTATUS ret;
- struct AfsRdrExtension *ext;
-
- #if 0
- try {
- #endif
- if (IrpSp->FileObject->FileName.Length == 0)
- SYNC_FAIL(STATUS_SUCCESS);
-
- ext = ((struct AfsRdrExtension*)RdrDevice->DeviceExtension);
-
- LOCK_FCB_LIST;
- LOCK_PAGING_FCB;
- LOCK_FCB;
-
- FsRtlNotifyCleanup(ext->notifyList, &ext->listHead, IrpSp->FileObject->FsContext2);
-
- IoRemoveShareAccess(IrpSp->FileObject, &fcb->share_access);
-
- CcFlushCache(IrpSp->FileObject->SectionObjectPointer, NULL, 0, NULL);
-
- if (fcb->delPending)
- {
- if (!MmFlushImageSection(&(fcb->sectionPtrs), MmFlushForDelete))
- /* yes, moot at this point */
- STATUS(STATUS_ACCESS_DENIED, 0);
- }
- else
- {
- MmFlushImageSection(IrpSp->FileObject->SectionObjectPointer, MmFlushForWrite);
- STATUS(STATUS_SUCCESS, 0);
- }
-
- CcPurgeCacheSection(IrpSp->FileObject->SectionObjectPointer, NULL, 0, TRUE);
- CcUninitializeCacheMap(IrpSp->FileObject, NULL, NULL);
-
- UNLOCK_FCB;
- UNLOCK_PAGING_FCB;
- UNLOCK_FCB_LIST;
-
- #if 0
- } except(EXCEPTION_EXECUTE_HANDLER)
- {
- STATUS(STATUS_UNSUCCESSFUL, 0);
- ExReleaseResourceLite(&ext->fcbLock);
- FsRtlExitFileSystem();
- }
- #endif
-
- ret = Irp->IoStatus.Status;
- COMPLETE;
- return ret;
- }
-
-
- /**********************************************************
- * AfsRdrClose
- * - handle actual unlinking
- * - handle closing
- **********************************************************/
- NTSTATUS AfsRdrClose(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb)
- {
- ULONG length;
- wchar_t *name;
- char kill;
- KEVENT ev;
- LARGE_INTEGER timeout;
- afs_ccb_t *ccb, *curr;
-
- if (IrpSp->FileObject->FileName.Length == 0)
- SYNC_FAIL(STATUS_SUCCESS);
-
- ccb = IrpSp->FileObject->FsContext2;
- LOCK_FCB_LIST;
-
- ObDereferenceObject(ccb->token);
-
- curr = fcb->ccb_list;
- if (fcb->ccb_list == ccb)
- fcb->ccb_list = fcb->ccb_list->next;
- else
- while (curr->next)
- {
- if (curr->next == ccb)
- {
- curr->next = curr->next->next;
- break;
- }
- curr = curr->next;
- }
-
- if (!fcb->ccb_list)
- {
- uc_close(fcb->fid);
- if (fcb->delPending)
- {
- uc_unlink(ccb->name+2);
- }
- if (fcb->lock)
- FsRtlFreeFileLock(fcb->lock);
- ExDeleteResourceLite(&fcb->_resource);
- ExDeleteResourceLite(&fcb->_pagingIoResource);
- RtlDeleteElementGenericTable(&rdrExt->fcbTable, &fcb);
- ExFreeToNPagedLookasideList(&rdrExt->fcbMemList, fcb);
- }
-
- ExFreePoolWithTag(ccb->name, AFS_RDR_TAG);
- if (ccb->filter && ccb->filter != SEARCH_MATCH_ALL)
- ExFreePoolWithTag(ccb->filter, AFS_RDR_TAG);
- ExFreeToNPagedLookasideList(&rdrExt->ccbMemList, ccb);
-
- UNLOCK_FCB_LIST;
-
- SYNC_FAIL(STATUS_SUCCESS);
- }
-
-
- /**********************************************************
- * AfsRdrShutdown
- * - should flush all data
- **********************************************************/
- NTSTATUS AfsRdrShutdown(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp)
- {
- STATUS(STATUS_SUCCESS, 0);
- COMPLETE;
- return 0;
- }
-
-
- /**********************************************************
- * AfsRdrFlushFile
- * - flushes specified file to userspace and then disk
- **********************************************************/
- NTSTATUS AfsRdrFlushFile(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb)
- {
- NTSTATUS ret;
- afs_ccb_t *ccb;
-
- if (IsDeviceFile(IrpSp->FileObject))
- SYNC_RET(STATUS_INVALID_DEVICE_REQUEST);
-
- ccb = IrpSp->FileObject->FsContext2;
-
- CcFlushCache(&fcb->sectionPtrs, NULL, 0, &Irp->IoStatus);
- uc_flush(fcb->fid);
-
- ret = Irp->IoStatus.Status;
- COMPLETE;
- return ret;
- }
-
-
- /**********************************************************
- * AfsRdrLockCtrl
- * - should handle lock requests
- **********************************************************/
- NTSTATUS AfsRdrLockCtrl(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb)
- {
- NTSTATUS ret;
-
- /* complete lock on control device object without processing, as directed */
- if (IrpSp->FileObject->FileName.Length == 0)
- {
- rpt0(("lock", "lock granted on root device obj"));
- SYNC_FAIL(STATUS_SUCCESS);
- }
-
- switch (IrpSp->MinorFunction)
- {
- case IRP_MN_LOCK:
- case IRP_MN_UNLOCK_ALL:
- case IRP_MN_UNLOCK_ALL_BY_KEY:
- case IRP_MN_UNLOCK_SINGLE:
- FsRtlEnterFileSystem();
- LOCK_PAGING_FCB;
- LOCK_FCB;
- if (!fcb->lock)
- {
- fcb->lock = FsRtlAllocateFileLock(NULL, NULL);
- }
- UNLOCK_FCB;
- UNLOCK_PAGING_FCB;
- FsRtlExitFileSystem();
- FsRtlProcessFileLock(fcb->lock, Irp, NULL);
- fcb->IsFastIoPossible = fcb->lock->FastIoIsQuestionable ? FastIoIsQuestionable : FastIoIsPossible;
- return STATUS_PENDING;
- default:
- SYNC_FAIL2(STATUS_NOT_IMPLEMENTED, 0);
- }
- SYNC_FAIL2(/*STATUS_LOCK_NOT_GRANTED*//*STATUS_NOT_IMPLEMENTED*/STATUS_SUCCESS, 0);
-
- /*EXCEPT(STATUS_UNSUCCESSFUL, 0);*/
- }
-
-
- /**********************************************************
- * AfsRdrQueryVol
- * - handle volume information requests
- **********************************************************/
- NTSTATUS AfsRdrQueryVol(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp)
- {
- FILE_FS_ATTRIBUTE_INFORMATION *infoAttr;
- FILE_FS_DEVICE_INFORMATION *infoDevice;
- FILE_FS_SIZE_INFORMATION * infoSize;
- FILE_FS_VOLUME_INFORMATION *infoVolume;
- NTSTATUS ret;
-
- TRY
-
- switch (IrpSp->Parameters.QueryVolume.FsInformationClass)
- {
- case FileFsAttributeInformation:
- infoAttr = (FILE_FS_ATTRIBUTE_INFORMATION*)Irp->AssociatedIrp.SystemBuffer;
- memset(infoAttr, 0, sizeof(FILE_FS_ATTRIBUTE_INFORMATION));
- infoAttr->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES | FILE_CASE_SENSITIVE_SEARCH; //TODOTODO:?
- infoAttr->MaximumComponentNameLength = 255; // should this be 255?
- ///RtlCopyMemory(infoAttr->FileSystemName, L"AFS", 2);
- ///infoAttr->FileSystemNameLength = 2;
- //StringCbCopyLen(infoAttr->FileSystemName, IrpSp->Parameters.QueryVolume.Length-sizeof(*infoAttr)-2, L"AFS", &infoAttr->FileSystemNameLength);
- //IrpSp->Parameters.QueryVolume.Length = 0;
- //Irp->IoStatus.Information = sizeof(*infoAttr) + (infoAttr->FileSystemNameLength - sizeof(WCHAR));
- if (sizeof(*infoAttr) + wcslen(AFS_FS_NAME)*sizeof(wchar_t) > IrpSp->Parameters.QueryVolume.Length)
- {
- infoAttr->FileSystemNameLength = 0;
- rpt0(("vol", "overflowing attr buffer %d", IrpSp->Parameters.QueryVolume.Length));
- SYNC_FAIL2(STATUS_BUFFER_OVERFLOW, sizeof(*infoAttr));
- }
- else
- {
- infoAttr->FileSystemNameLength = wcslen(AFS_FS_NAME)*sizeof(wchar_t);
- StringCbCopyW(infoAttr->FileSystemName, IrpSp->Parameters.QueryVolume.Length - sizeof(*infoAttr) + sizeof(WCHAR), AFS_FS_NAME);
- SYNC_FAIL2(STATUS_SUCCESS, sizeof(*infoAttr) + (infoAttr->FileSystemNameLength - sizeof(WCHAR)));
- }
- break;
-
- case FileFsDeviceInformation:
- infoDevice = (FILE_FS_DEVICE_INFORMATION*)Irp->AssociatedIrp.SystemBuffer;
- memset(infoDevice, 0, sizeof(FILE_FS_DEVICE_INFORMATION));
- infoDevice->DeviceType = FILE_DEVICE_DISK;//DeviceObject->DeviceType;// FILE_DEVICE_NETWORK_FILE_SYSTEM;
- infoDevice->Characteristics = DeviceObject->Characteristics;//FILE_DEVICE_IS_MOUNTED /*| FILE_REMOTE_DEVICE*/; // remote device?
- IrpSp->Parameters.QueryVolume.Length = sizeof(*infoDevice);
- SYNC_FAIL2(STATUS_SUCCESS, IrpSp->Parameters.QueryVolume.Length);
- break;
-
- case FileFsSizeInformation:
- infoSize = (FILE_FS_SIZE_INFORMATION*)Irp->AssociatedIrp.SystemBuffer;
- memset(infoSize, 0, sizeof(FILE_FS_SIZE_INFORMATION));
- /* this data needs to come from an upcall */
- infoSize->TotalAllocationUnits.QuadPart = 0x00000000F0000000;
- infoSize->AvailableAllocationUnits.QuadPart = 0x00000000E0000000;
- infoSize->SectorsPerAllocationUnit = 1;
- infoSize->BytesPerSector = 1;
- IrpSp->Parameters.QueryVolume.Length = sizeof(*infoSize);
- SYNC_FAIL2(STATUS_SUCCESS, IrpSp->Parameters.QueryVolume.Length);
- break;
-
- case FileFsVolumeInformation:
- infoVolume = (FILE_FS_VOLUME_INFORMATION*)Irp->AssociatedIrp.SystemBuffer;
- memset(infoVolume, 0, sizeof(FILE_FS_VOLUME_INFORMATION));
- /* this data needs to come from an upcall */
- infoVolume->VolumeCreationTime.QuadPart = AfsTimeToWindowsTime(1080000000);
- infoVolume->VolumeSerialNumber = 0x12345678;
- infoVolume->SupportsObjects = FALSE;
- //StringCbCopyLen(infoVolume->VolumeLabel, IrpSp->Parameters.QueryVolume.Length-sizeof(*infoVolume)-2, L"AfsRed", &infoVolume->VolumeLabelLength);
- //IrpSp->Parameters.QueryVolume.Length = 0;
- if (sizeof(*infoVolume) + 12 > IrpSp->Parameters.QueryVolume.Length)
- {
- infoVolume->VolumeLabelLength = 0;
- SYNC_FAIL2(STATUS_BUFFER_OVERFLOW, sizeof(*infoVolume));
- }
- else
- {
- infoVolume->VolumeLabelLength = 12;
- RtlCopyMemory(infoVolume->VolumeLabel, L"AfsRed", 12);
- SYNC_FAIL2(STATUS_SUCCESS, sizeof(*infoVolume) + (infoVolume->VolumeLabelLength - sizeof(WCHAR)));
- }
- break;
- }
-
- EXCEPT(STATUS_UNSUCCESSFUL, 0);
-
- rpt0(("vol", "vol class %d unknown", IrpSp->Parameters.QueryVolume.FsInformationClass));
- SYNC_FAIL(STATUS_NOT_IMPLEMENTED);
- }
-
- VOID AfsRdrUnload(DRIVER_OBJECT *DriverObject)
- {
- UNICODE_STRING userModeName;
-
- FsRtlNotifyUninitializeSync(&rdrExt->notifyList);
-
- RtlInitUnicodeString(&userModeName, L"\\DosDevices\\afscom");
- IoDeleteSymbolicLink(&userModeName);
-
- /*RtlInitUnicodeString(&userModeName, L"\\DosDevices\\T:");
- IoDeleteSymbolicLink(&userModeName);*/
-
- ExDeleteNPagedLookasideList(&rdrExt->fcbMemList);
- ExDeleteNPagedLookasideList(&rdrExt->ccbMemList);
-
- rpc_shutdown();
-
- IoDeleteDevice(ComDevice);
- IoDeleteDevice(RdrDevice);
-
- KdPrint(("RdrUnload exiting.\n"));
- }
-
-
- // handles all non-handled irp's synchronously
- NTSTATUS AfsRdrNull(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp)
- {
- NTSTATUS ret;
-
- /*TRY
- rpt0(("kunhand", IrpMjFuncDesc[IrpSp->MajorFunction]));*/
-
- SYNC_FAIL(STATUS_NOT_IMPLEMENTED);
-
- /*EXCEPT(STATUS_UNSUCCESSFUL, 0);
-
- ret = Irp->IoStatus.Status;
- COMPLETE_NO_BOOST;
- return ret;*/
- }
-
- NTSTATUS ComDispatch(DEVICE_OBJECT *DeviceObject, IRP *Irp)
- {
- IO_STACK_LOCATION *IrpSp, *IrpSpClient;
- NTSTATUS ret;
- struct ComExtension *ext;
- void *ptr, *ptr2;
- rpc_t find, *find_ptr;
- LARGE_INTEGER timeout;
- struct afsFcb *fcb;
- rpc_t *rpc, **rpcp;
- ULONG len;
- ULONG code, read;
- PACCESS_TOKEN acc_token;
- PVOID waitPair[2];
-
- ext = (struct ComExtension *)DeviceObject->DeviceExtension;
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
-
- switch (IrpSp->MajorFunction)
- {
- case IRP_MJ_CREATE:
- IrpSp->FileObject->FsContext = 0;
- IrpSp->FileObject->FsContext2 = 0;
- if (IrpSp->FileObject->FileName.Length)
- {
- /* ioctls come from fs, vos, bos, etc. using a pre-existing interface */
- /* downcalls come from afsd, using a new interface */
- /* upcall hooks come from afsd */
- if (!wcscmp(IrpSp->FileObject->FileName.Buffer, L"\\ioctl"))
- IrpSp->FileObject->FsContext2 = COMM_IOCTL;
- else if (!wcscmp(IrpSp->FileObject->FileName.Buffer, L"\\downcall"))
- IrpSp->FileObject->FsContext2 = COMM_DOWNCALL;
- else if (!wcscmp(IrpSp->FileObject->FileName.Buffer, L"\\upcallhook"))
- IrpSp->FileObject->FsContext2 = COMM_UPCALLHOOK;
- }
- if (!IrpSp->FileObject->FsContext2)
- SYNC_FAIL2(STATUS_INVALID_DEVICE_REQUEST, 0);
-
- acc_token = SeQuerySubjectContextToken(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
- ASSERT(acc_token);
- /* SeQueryAuthenticationIdToken */
- IrpSp->FileObject->FsContext = acc_token;
- STATUS(STATUS_SUCCESS, FILE_OPENED);
- break;
-
- case IRP_MJ_CLEANUP:
- /* acc_token does not have to be released */
- case IRP_MJ_CLOSE:
- STATUS(STATUS_SUCCESS, 0);
- break;
-
- case IRP_MJ_WRITE:
- /* we only process MDL writes */
- if (!Irp->MdlAddress ||
- !(ptr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority))) /* should be LowPagePriority */
- SYNC_FAIL(STATUS_INSUFFICIENT_RESOURCES);
-
- if (!IrpSp->FileObject->FsContext ||
- !IrpSp->FileObject->FsContext2)
- SYNC_FAIL(STATUS_INVALID_HANDLE);
-
- if (IrpSp->FileObject->FsContext2 == COMM_UPCALLHOOK)
- {
- rpc_recv(ptr, IrpSp->Parameters.Write.Length);
- STATUS(STATUS_SUCCESS, IrpSp->Parameters.Write.Length);
- }
- else
- STATUS(STATUS_INVALID_DEVICE_REQUEST, 0);
- break;
- case IRP_MJ_READ:
- if (!Irp->MdlAddress || !(ptr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority))) // should be LowPagePriority
- SYNC_FAIL(STATUS_INSUFFICIENT_RESOURCES);
-
- if (IrpSp->FileObject->FsContext2 == COMM_UPCALLHOOK)
- {
- KeClearEvent(&comExt->cancelEvent);
-
- timeout.QuadPart = -100000000L;
- waitPair[0] = &comExt->outEvent;
- waitPair[1] = &comExt->cancelEvent;
- ret = KeWaitForMultipleObjects(2, waitPair, WaitAny, Executive, KernelMode, FALSE, &timeout, NULL);
-
- if (ret == STATUS_WAIT_1)
- SYNC_FAIL(STATUS_UNSUCCESSFUL);
-
- if (!rpc_send(ptr, IrpSp->Parameters.Read.Length, &read))
- {
- KeClearEvent(&comExt->outEvent);
- ret = KeWaitForMultipleObjects(2, waitPair, WaitAny, Executive, KernelMode, FALSE, &timeout, NULL);
- if (!rpc_send(ptr, IrpSp->Parameters.Read.Length, &read))
- {
- KeClearEvent(&comExt->outEvent);
- SYNC_FAIL(STATUS_UNSUCCESSFUL);
- }
- }
- SYNC_RET2(STATUS_SUCCESS, read); /* complete with priority boost */
- }
- else
- STATUS(STATUS_INVALID_DEVICE_REQUEST, 0);
- break;
- case IRP_MJ_DEVICE_CONTROL:
- return AfsRdrDeviceControl(DeviceObject, Irp, IrpSp, NULL);
- default:
- STATUS(STATUS_INVALID_DEVICE_REQUEST, 0);
- break;
- }
-
- ret = Irp->IoStatus.Status;
- COMPLETE; /* complete with priority boost */
- return ret;
- }
-
-
- /* handles all irp's for primary (fs) device */
- NTSTATUS Dispatch(DEVICE_OBJECT *DeviceObject, IRP *Irp)
- {
- IO_STACK_LOCATION *IrpSp;
- NTSTATUS ret;
- afs_fcb_t *fcb;
- afs_ccb_t *ccb;
- LARGE_INTEGER wait;
-
- if (DeviceObject->DeviceType == FILE_DEVICE_DATALINK)
- return ComDispatch(DeviceObject, Irp);
-
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
-
- rpt4(("irp", "%s min %d on %d (%ws) %x %x", IrpMjFuncDesc[IrpSp->MajorFunction], IrpSp->MinorFunction, 0/*ExtractFid(IrpSp->FileObject->FsContext)*/, IrpSp->FileObject->FileName.Buffer, IrpSp->Flags, IrpSp->Parameters.Create.Options));
-
- fcb = IrpSp->FileObject->FsContext;
- if (IrpSp->MajorFunction != IRP_MJ_CREATE)
- ASSERT(fcb);
-
- if (IrpSp->FileObject && IrpSp->FileObject->FsContext2)
- {
- ccb = IrpSp->FileObject->FsContext2;
- wait.QuadPart = -1000;
- while (rpc_set_context(ccb->token) != 0) /* if there are no open thread spots... */
- KeDelayExecutionThread(KernelMode, FALSE, &wait); /* ...wait */
- }
-
- switch (IrpSp->MajorFunction)
- {
- case IRP_MJ_CREATE:
- ret = AfsRdrCreate(DeviceObject, Irp, IrpSp, NULL);
- break;
- case IRP_MJ_DIRECTORY_CONTROL:
- ret = AfsRdrDirCtrl(DeviceObject, Irp, IrpSp, fcb);
- break;
- case IRP_MJ_READ:
- ret = AfsRdrRead(DeviceObject, Irp, IrpSp, fcb);
- break;
- case IRP_MJ_WRITE:
- ret = AfsRdrWrite(DeviceObject, Irp, IrpSp, fcb);
- break;
- case IRP_MJ_CLOSE:
- ret = AfsRdrClose(DeviceObject, Irp, IrpSp, fcb);
- break;
- case IRP_MJ_QUERY_INFORMATION:
- ret = AfsRdrQueryInfo(DeviceObject, Irp, IrpSp, fcb);
- break;
- case IRP_MJ_DEVICE_CONTROL:
- ret = AfsRdrDeviceControl(DeviceObject, Irp, IrpSp, fcb);
- break;
- case IRP_MJ_CLEANUP:
- ret = AfsRdrCleanup(DeviceObject, Irp, IrpSp, fcb);
- break;
- case IRP_MJ_LOCK_CONTROL:
- ret = AfsRdrLockCtrl(DeviceObject, Irp, IrpSp, fcb);
- break;
- case IRP_MJ_QUERY_VOLUME_INFORMATION:
- ret = AfsRdrQueryVol(DeviceObject, Irp, IrpSp);
- break;
- case IRP_MJ_SHUTDOWN:
- ret = AfsRdrShutdown(DeviceObject, Irp, IrpSp);
- break;
- case IRP_MJ_FILE_SYSTEM_CONTROL:
- if (IrpSp->MinorFunction == IRP_MN_USER_FS_REQUEST &&
- (IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_REQUEST_OPLOCK_LEVEL_1 ||
- IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_REQUEST_OPLOCK_LEVEL_2 ||
- IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_REQUEST_BATCH_OPLOCK ||
- IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_REQUEST_FILTER_OPLOCK))
- STATUS(STATUS_OPLOCK_NOT_GRANTED, 0);
- else
- STATUS(STATUS_INVALID_DEVICE_REQUEST/*STATUS_NOT_IMPLEMENTED*//*STATUS_INVALID_PARAMETER*/, 0);
- ret = Irp->IoStatus.Status;
- goto complete;
- case IRP_MJ_SET_INFORMATION:
- ret = AfsRdrSetInfo(DeviceObject, Irp, IrpSp, fcb);
- break;
- case IRP_MJ_FLUSH_BUFFERS:
- ret = AfsRdrFlushFile(DeviceObject, Irp, IrpSp, fcb);
- break;
- default:
- ret = AfsRdrNull(DeviceObject, Irp, IrpSp);
- break;
- }
- rpc_remove_context();
- return ret;
-
- complete:
- rpc_remove_context();
- COMPLETE;
- return ret;
- }
-
-
- BOOLEAN
- fastIoCheck (
- IN struct _FILE_OBJECT *FileObject,
- IN PLARGE_INTEGER FileOffset,
- IN ULONG Length,
- IN BOOLEAN Wait,
- IN ULONG LockKey,
- IN BOOLEAN CheckForReadOperation,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN struct _DEVICE_OBJECT *DeviceObject
- )
- {
- afs_fcb_t *fcb;
- LARGE_INTEGER temp;
-
- fcb = FileObject->FsContext;
- ASSERT(fcb);
-
- if (!fcb->lock)
- return TRUE;
-
- temp.QuadPart = Length;
- if (CheckForReadOperation)
- return FsRtlFastCheckLockForRead(fcb->lock, FileOffset, &temp, LockKey, FileObject, IoGetCurrentProcess());
- return FsRtlFastCheckLockForWrite(fcb->lock, FileOffset, &temp, LockKey, FileObject, IoGetCurrentProcess());
- }
-
-
- BOOLEAN
- fastIoRead (
- IN struct _FILE_OBJECT *FileObject,
- IN PLARGE_INTEGER FileOffset,
- IN ULONG Length,
- IN BOOLEAN Wait,
- IN ULONG LockKey,
- OUT PVOID Buffer,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN struct _DEVICE_OBJECT *DeviceObject
- )
- {
- BOOLEAN ret;
- ULONG adj_len;
- afs_fcb_t *fcb;
- LARGE_INTEGER temp;
-
- fcb = FileObject->FsContext;
- ASSERT(fcb);
-
- FsRtlEnterFileSystem();
- LOCK_PAGING_FCB;
-
- if (fcb->lock)
- {
- temp.QuadPart = Length;
- if (!FsRtlFastCheckLockForRead(fcb->lock, FileOffset, &temp, LockKey, FileObject, IoGetCurrentProcess()))
- {
- UNLOCK_PAGING_FCB;
- FsRtlExitFileSystem();
- return FALSE;
- }
- }
-
- adj_len = Length;
- if (FileOffset->QuadPart > fcb->FileSize.QuadPart)
- {
- UNLOCK_PAGING_FCB;
- FsRtlExitFileSystem();
- IoStatus->Status = STATUS_END_OF_FILE;
- IoStatus->Information = 0;
- return TRUE;
- }
- if (FileOffset->QuadPart + Length > fcb->FileSize.QuadPart)
- adj_len = (ULONG)(fcb->FileSize.QuadPart - FileOffset->QuadPart);
-
- try
- {
- ret = CcCopyRead(FileObject, FileOffset, adj_len, Wait, Buffer, IoStatus);
-
- FileObject->CurrentByteOffset.QuadPart = FileOffset->QuadPart + IoStatus->Information;
- UNLOCK_PAGING_FCB;
- FsRtlExitFileSystem();
- }
- except (EXCEPTION_EXECUTE_HANDLER)
- {
- UNLOCK_PAGING_FCB;
- FsRtlExitFileSystem();
- return FALSE;
- }
- return ret;
- }
-
- BOOLEAN
- fastIoWrite (
- IN struct _FILE_OBJECT *FileObject,
- IN PLARGE_INTEGER FileOffset,
- IN ULONG Length,
- IN BOOLEAN Wait,
- IN ULONG LockKey,
- OUT PVOID Buffer,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN struct _DEVICE_OBJECT *DeviceObject
- )
- {
- BOOLEAN ret;
- LARGE_INTEGER adj_end;
- afs_fcb_t *fcb;
- LARGE_INTEGER temp;
-
- fcb = FileObject->FsContext;
- ASSERT(fcb);
-
- FsRtlEnterFileSystem();
- LOCK_PAGING_FCB;
-
- if (fcb->lock)
- {
- temp.QuadPart = Length;
- if (!FsRtlFastCheckLockForWrite(fcb->lock, FileOffset, &temp, LockKey, FileObject, IoGetCurrentProcess()))
- {
- UNLOCK_PAGING_FCB;
- FsRtlExitFileSystem();
- return FALSE;
- }
- }
-
-
- if (FileOffset->QuadPart + Length > fcb->FileSize.QuadPart)
- {
- adj_end.QuadPart = FileOffset->QuadPart + Length;
- fcb->AllocationSize = fcb->FileSize = fcb->ValidDataLength = adj_end;
- LOCK_FCB;
- try
- {
- CcSetFileSizes(FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize);
- }
- except (EXCEPTION_EXECUTE_HANDLER)
- {
- UNLOCK_FCB;
- UNLOCK_PAGING_FCB;
- FsRtlExitFileSystem();
- return FALSE;
- }
- UNLOCK_FCB;
- }
-
- try
- {
- ret = CcCopyWrite(FileObject, FileOffset, Length, Wait, Buffer);
- IoStatus->Status = ret?STATUS_SUCCESS:STATUS_UNSUCCESSFUL;
- IoStatus->Information = ret?Length:0;
-
- FileObject->CurrentByteOffset.QuadPart = FileOffset->QuadPart + IoStatus->Information;
- UNLOCK_PAGING_FCB;
- FsRtlExitFileSystem();
- }
- except (EXCEPTION_EXECUTE_HANDLER)
- {
- UNLOCK_PAGING_FCB;
- FsRtlExitFileSystem();
- return FALSE;
- }
- return ret;
- }
-
- RTL_GENERIC_COMPARE_RESULTS FcbCompareRoutine(struct _RTL_GENERIC_TABLE *Table, PVOID FirstStruct, PVOID SecondStruct)
- {
- afs_fcb_t *p1, *p2;
-
- p1 = (void*)*(afs_fcb_t**)FirstStruct; p2 = (void*)*(afs_fcb_t**)SecondStruct;
- if (p1->fid < p2->fid)
- return GenericLessThan;
- if (p1->fid > p2->fid)
- return GenericGreaterThan;
- return GenericEqual;
- }
-
- RTL_GENERIC_COMPARE_RESULTS ReqCompareRoutine(struct _RTL_GENERIC_TABLE *Table, PVOID FirstStruct, PVOID SecondStruct)
- {
- rpc_t *p1, *p2;
-
- p1 = *(rpc_t**)FirstStruct; p2 = *(rpc_t**)SecondStruct;
- if (p1->key < p2->key)
- return GenericLessThan;
- if (p1->key > p2->key)
- return GenericGreaterThan;
- return GenericEqual;
- }
-
- PVOID AllocateRoutine(struct _RTL_GENERIC_TABLE *Table, CLONG ByteSize)
- {
- PVOID ret;
- ret = ExAllocatePoolWithTag(NonPagedPool, ByteSize, AFS_RDR_TAG);
- ASSERT(ret);
- RtlZeroMemory(ret, ByteSize);
- return ret;
- }
-
- VOID FreeRoutine(struct _RTL_GENERIC_TABLE *Table, PVOID Buffer)
- {
- ExFreePoolWithTag(Buffer, AFS_RDR_TAG);
- }
-
- //KSPIN_LOCK rpc_lock;
- //KIRQL irql;
- FAST_MUTEX rpc_lock;
-
- void ifs_lock_rpcs()
- {
- ExAcquireFastMutex(&rpc_lock);
- //KeAcquireSpinLock(&rpc_lock, &irql);
- }
-
- void ifs_unlock_rpcs()
- {
- ExReleaseFastMutex(&rpc_lock);
- //KeReleaseSpinLock(&rpc_lock, irql);
- }
-
- NTSTATUS DriverEntry(DRIVER_OBJECT *DriverObject, UNICODE_STRING *RegistryPath)
- {
- NTSTATUS err;
- UNICODE_STRING rdrName, comName, userModeName, userModeCom;
- int x;
- IO_STATUS_BLOCK status;
- FAST_IO_DISPATCH *fastIoDispatch;
-
- //try {
- RtlInitUnicodeString(&rdrName, L"\\Device\\afsrdr");
- RtlInitUnicodeString(&comName, L"\\Device\\afscom");
-
- rpt0(("init", "kern initializing"));
- //KeInitializeSpinLock(&rpc_lock);
- ExInitializeFastMutex(&rpc_lock);
-
- IoAllocateDriverObjectExtension(DriverObject, (void *)0x394389f7, sizeof(FAST_IO_DISPATCH), &fastIoDispatch);
- RtlZeroMemory(fastIoDispatch, sizeof(FAST_IO_DISPATCH));
- fastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
- fastIoDispatch->FastIoCheckIfPossible = fastIoCheck;
- fastIoDispatch->FastIoRead = /*FsRtlCopyRead;*/fastIoRead;
- fastIoDispatch->FastIoWrite = /*FsRtlCopyWrite;*/fastIoWrite;
- DriverObject->FastIoDispatch = fastIoDispatch;
-
- for (x = 0; x < IRP_MJ_MAXIMUM_FUNCTION; x++)
- DriverObject->MajorFunction[x] = Dispatch;
- DriverObject->DriverUnload = AfsRdrUnload;
-
- err = IoCreateDevice(DriverObject, sizeof(struct AfsRdrExtension)*2, &rdrName, FILE_DEVICE_NETWORK_FILE_SYSTEM, /*FILE_REMOTE_DEVICE*/0, FALSE, &RdrDevice);
- if (!NT_SUCCESS(STATUS_SUCCESS))
- return STATUS_UNSUCCESSFUL;
- err = IoCreateDevice(DriverObject, sizeof(struct ComExtension)*2, &comName, FILE_DEVICE_DATALINK, 0, FALSE, &ComDevice);
- if (!NT_SUCCESS(STATUS_SUCCESS))
- return STATUS_UNSUCCESSFUL;
-
- RdrDevice->Flags |= DO_DIRECT_IO;
- RdrDevice->StackSize = 5; /* could this be zero? */
- rdrExt = ((struct AfsRdrExtension*)RdrDevice->DeviceExtension);
- RtlZeroMemory(rdrExt, sizeof(struct AfsRdrExtension));
-
- /* could raise exception */
- FsRtlNotifyInitializeSync(&rdrExt->notifyList);
- InitializeListHead(&rdrExt->listHead);
-
- rdrExt->callbacks.AcquireForLazyWrite = lazyWriteLock;
- rdrExt->callbacks.ReleaseFromLazyWrite = lazyWriteUnlock;
- rdrExt->callbacks.AcquireForReadAhead = readAheadLock;
- rdrExt->callbacks.ReleaseFromReadAhead = readAheadUnlock;
- ExInitializeNPagedLookasideList(&rdrExt->fcbMemList, NULL, NULL, 0, sizeof(afs_fcb_t), AFS_RDR_TAG, 0);
- ExInitializeNPagedLookasideList(&rdrExt->ccbMemList, NULL, NULL, 0, sizeof(afs_ccb_t), AFS_RDR_TAG, 0);
- ExInitializeFastMutex(&rdrExt->fcbLock);
- RtlInitializeGenericTable(&rdrExt->fcbTable, FcbCompareRoutine, AllocateRoutine, FreeRoutine, NULL);
-
-
- ComDevice->Flags |= DO_DIRECT_IO;
- ComDevice->StackSize = 5; // ??
- comExt = ((struct ComExtension*)ComDevice->DeviceExtension);
- RtlZeroMemory(comExt, sizeof(struct ComExtension));
-
- InitializeListHead(&comExt->outReqList);
- KeInitializeSpinLock(&comExt->outLock);
- ExInitializeFastMutex(&comExt->inLock);
- KeInitializeEvent(&comExt->outEvent, SynchronizationEvent/*NotificationEvent*/, TRUE);
- KeInitializeEvent(&comExt->cancelEvent, NotificationEvent, TRUE);
-
- comExt->rdr = rdrExt;
- rdrExt->com = comExt;
-
- RtlInitUnicodeString(&userModeCom, L"\\DosDevices\\afscom");
- err = IoCreateSymbolicLink(&userModeCom, &comName);
-
- /*RtlInitUnicodeString(&rdrName, L"\\Device\\afsrdr\\1\\CITI.UMICH.EDU");
- RtlInitUnicodeString(&userModeName, L"\\DosDevices\\W:");
- err = IoCreateSymbolicLink(&userModeName, &rdrName);*/
-
- /*} except(EXCEPTION_EXECUTE_HANDLER)
- {
- return -1;
- }*/
-
- KdPrint(("DriverEntry exiting.\n"));
- return STATUS_SUCCESS;
- }
--- 0 ----
Index: openafs/src/WINNT/afsrdr/afsrdr.h
diff -c openafs/src/WINNT/afsrdr/afsrdr.h:1.2 openafs/src/WINNT/afsrdr/afsrdr.h:removed
*** openafs/src/WINNT/afsrdr/afsrdr.h:1.2 Thu Aug 4 12:32:39 2005
--- openafs/src/WINNT/afsrdr/afsrdr.h Sat Mar 22 21:01:36 2008
***************
*** 1,66 ****
- /* copyright (c) 2005
- * the regents of the university of michigan
- * all rights reserved
- *
- * permission is granted to use, copy, create derivative works and
- * redistribute this software and such derivative works for any purpose,
- * so long as the name of the university of michigan is not used in
- * any advertising or publicity pertaining to the use or distribution
- * of this software without specific, written prior authorization. if
- * the above copyright notice or any other identification of the
- * university of michigan is included in any copy of any portion of
- * this software, then the disclaimer below must also be included.
- *
- * this software is provided as is, without representation from the
- * university of michigan as to its fitness for any purpose, and without
- * warranty by the university of michigan of any kind, either express
- * or implied, including without limitation the implied warranties of
- * merchantability and fitness for a particular purpose. the regents
- * of the university of michigan shall not be liable for any damages,
- * including special, indirect, incidental, or consequential damages,
- * with respect to any claim arising out or in connection with the use
- * of the software, even if it has been or is hereafter advised of the
- * possibility of such damages.
- */
-
- /* versioning history
- *
- * 03-jun 2005 (eric williams) entered into versioning
- */
-
- #include
-
- #define rpt0(args)
- #define rpt1(args)
- #define rpt2(args)
- #define rpt3(args)
- #define rpt4(args)
- #define rpt5(args)
-
- struct AfsRdrExtension
- {
- struct ComExtension *com;
- PNOTIFY_SYNC notifyList;
- LIST_ENTRY listHead;
- NPAGED_LOOKASIDE_LIST fcbMemList;
- FAST_MUTEX fcbLock;
- NPAGED_LOOKASIDE_LIST ccbMemList;
- RTL_GENERIC_TABLE fcbTable;
- CACHE_MANAGER_CALLBACKS callbacks;
- };
-
- struct ComExtension
- {
- struct AfsRdrExtension *rdr;
- LIST_ENTRY outReqList;
- KSPIN_LOCK outLock;
- FAST_MUTEX inLock;
- KEVENT outEvent, cancelEvent;
- };
-
- extern struct AfsRdrExtension *rdrExt;
- extern struct ComExtension *comExt;
-
-
- void ifs_lock_rpcs();
- void ifs_unlock_rpcs();
--- 0 ----
Index: openafs/src/WINNT/afsrdr/afsrdr.rc
diff -c openafs/src/WINNT/afsrdr/afsrdr.rc:1.1 openafs/src/WINNT/afsrdr/afsrdr.rc:removed
*** openafs/src/WINNT/afsrdr/afsrdr.rc:1.1 Thu Aug 4 12:32:39 2005
--- openafs/src/WINNT/afsrdr/afsrdr.rc Sat Mar 22 21:01:36 2008
***************
*** 1,59 ****
- /*
- * 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
- */
-
- /* Define VERSIONINFO resource */
-
- #define AFS_VERINFO_FILE_DESCRIPTION "AFS Network Redirector Driver"
- #define AFS_VERINFO_NAME "afsrdr"
- #define AFS_VERINFO_FILENAME "afsrdr.sys"
-
- #include "..\afsd\AFS_component_version_number.h"
-
- #include
-
- 1 VERSIONINFO
- FILEVERSION AFS_VERINFO_FILEVER
- PRODUCTVERSION AFS_VERINFO_FILEVER
- FILEOS VOS_NT
- #ifdef AFS_VERINFO_DLL
- FILETYPE VFT_DLL
- #else
- FILETYPE VFT_APP
- #endif
- BEGIN
- BLOCK "StringFileInfo"
- /* FileVersion must be specified or data won't appear on properties tab */
- /* Internalname and originalfilename must be specified or explorer won't
- show version and description */
- BEGIN
- BLOCK "000004E4"
- BEGIN
- VALUE "CompanyName", "OpenAFS Project", "\0"
- VALUE "LegalCopyright", "Copyright \251 the Regents of the University of Michigan, 2005.", "\0"
- VALUE "ProductName", "OpenAFS for Windows", "\0"
- VALUE "ProductVersion", "1.0", "\0"
- VALUE "FileVersion", "1.0", "\0"
- VALUE "FileDescription", AFS_VERINFO_FILE_DESCRIPTION, "\0"
- VALUE "Build", AFS_VERINFO_BUILD, "\0"
- VALUE "InternalName", AFS_VERINFO_NAME, "\0"
- VALUE "OriginalFilename", AFS_VERINFO_FILENAME, "\0"
- END
- END
- /* files in msi's are supposed to have language codes attached to them.
- this is how they get populated automatically */
- BLOCK "VarFileInfo"
- BEGIN
- #ifdef AFS_VERINFO_LANG_CODE
- VALUE "Translation", AFS_VERINFO_LANG_CODE, AFS_VERINFO_CHARSET
- #else
- /* default to 0, 1252 */
- VALUE "Translation", 0, 0x4e4
- #endif
- END
- END
--- 0 ----
Index: openafs/src/WINNT/afsrdr/ifs_rpc.c
diff -c openafs/src/WINNT/afsrdr/ifs_rpc.c:1.3.4.2 openafs/src/WINNT/afsrdr/ifs_rpc.c:removed
*** openafs/src/WINNT/afsrdr/ifs_rpc.c:1.3.4.2 Thu Jul 20 17:46:21 2006
--- openafs/src/WINNT/afsrdr/ifs_rpc.c Sat Mar 22 21:01:37 2008
***************
*** 1,1294 ****
- /* copyright (c) 2005
- * the regents of the university of michigan
- * all rights reserved
- *
- * permission is granted to use, copy, create derivative works and
- * redistribute this software and such derivative works for any purpose,
- * so long as the name of the university of michigan is not used in
- * any advertising or publicity pertaining to the use or distribution
- * of this software without specific, written prior authorization. if
- * the above copyright notice or any other identification of the
- * university of michigan is included in any copy of any portion of
- * this software, then the disclaimer below must also be included.
- *
- * this software is provided as is, without representation from the
- * university of michigan as to its fitness for any purpose, and without
- * warranty by the university of michigan of any kind, either express
- * or implied, including without limitation the implied warranties of
- * merchantability and fitness for a particular purpose. the regents
- * of the university of michigan shall not be liable for any damages,
- * including special, indirect, incidental, or consequential damages,
- * with respect to any claim arising out or in connection with the use
- * of the software, even if it has been or is hereafter advised of the
- * possibility of such damages.
- */
-
- /* versioning history
- *
- * 03-jun 2005 (eric williams) entered into versioning
- */
-
- #ifdef RPC_KERN
- #include
- #include "ifs_rpc.h"
- #include "afsrdr.h"
- #else
- #include "ifs_rpc.h"
- #endif
- #include "kif.h"
-
- /* general internal functions */
- rpc_t *rpc_create(int size_hint);
- void rpc_destroy(rpc_t *rpc);
- int rpc_marshal_long(rpc_t *rpc, ULONG data);
- int rpc_marshal_longlong(rpc_t *rpc, LARGE_INTEGER data);
- int rpc_marshal_wstr(rpc_t *rpc, WCHAR *str);
- int rpc_unmarshal_long(rpc_t *rpc, ULONG *data);
- int rpc_unmarshal_longlong(rpc_t *rpc, LARGE_INTEGER *data);
- int rpc_unmarshal_wstr(rpc_t *rpc, WCHAR *str);
-
- /* kernel-queue specific internal functions */
- #ifdef RPC_KERN
- int rpc_queue(rpc_t *rpc);
- rpc_queue_bulk(rpc_t *rpc, char *out_bulk, ULONG out_len, char *in_bulk, ULONG in_len);
- rpc_cancel(rpc_t *rpc);
- rpc_send_reg(rpc_t *rpc, char *out_buf);
- rpc_queue_bulk_mdl(rpc_t *rpc, MDL *mdl);
- rpc_t *rpc_find(int id);
- rpc_t *rpc_upgrade(rpc_t *rpc, int old_status, int new_status);
- rpc_wait(rpc_t *rpc, BOOLEAN long_op);
- rpc_send_mdl(rpc_t *rpc, char *out_buf);
- #endif
-
-
- /****** rpc security kernel functions ******/
- /* before making an upcall from kernel code, set the security context by
- * passing the access_token to rpc_set_context. remove the context after all
- * upcalls are done. the rpc library automatically checks and sets this
- * same context on the other end. */
- #ifdef RPC_KERN
- struct rpc_cred_map_entry
- {
- void *token;
- PETHREAD thread;
- int refs;
- };
-
- struct rpc_cred_map_entry cred_map[MAX_CRED_MAPS];
- rpc_t *rpc_list_head = NULL;
- long num_rpcs = 0;
-
- rpc_set_context(void *context)
- {
- int x, empty, ret;
- PETHREAD thd;
-
- thd = PsGetCurrentThread();
- empty = -1;
- ret = 0;
-
- ifs_lock_rpcs();
- for (x = 0; x < MAX_CRED_MAPS; x++)
- {
- if (cred_map[x].thread == NULL)
- empty = x;
- if (cred_map[x].thread == thd)
- {
- //////FIX///ASSERT(cred_map[x].token == context);
- cred_map[x].refs++;
- //cred_map[x].token = context;
- goto done;
- }
- }
- if (empty != -1)
- {
- cred_map[empty].thread = thd;
- cred_map[empty].token = context;
- cred_map[empty].refs = 1;
- }
- else
- ret = -1;
-
- done:
- ifs_unlock_rpcs();
- return ret;
- }
-
- void *rpc_get_context()
- {
- int x;
- PETHREAD thd;
-
- thd = PsGetCurrentThread();
-
- // no lock
- for (x = 0; x < MAX_CRED_MAPS; x++)
- if (cred_map[x].thread == thd)
- return cred_map[x].token;
- // no unlock
- return NULL;
- }
-
- rpc_remove_context()
- {
- int x;
- PETHREAD thd;
-
- thd = PsGetCurrentThread();
- ifs_lock_rpcs();
- for (x = 0; x < MAX_CRED_MAPS; x++)
- if (cred_map[x].thread == thd)
- {
- if (cred_map[x].refs > 1)
- {
- cred_map[x].refs--;
- }
- else
- {
- cred_map[x].token = NULL;
- cred_map[x].thread = NULL;
- }
- ifs_unlock_rpcs();
- return 0;
- }
-
- ifs_unlock_rpcs();
- return -1;
- }
- #endif
-
-
- /* rpc stubs in kernel */
- #ifdef RPC_KERN
- rpc_t *rpc_create(int size_hint)
- {
- ULONG size;
- rpc_t *rpc;
- SECURITY_SUBJECT_CONTEXT subj_context;
- PACCESS_TOKEN acc_token;
- LUID auth_id;
- LARGE_INTEGER user_id;
- NTSTATUS status;
- HANDLE token;
-
- /* get user's identification from auth token*/
- token = rpc_get_context();
- ASSERT(token);
- status = SeQueryAuthenticationIdToken(token, &auth_id);
-
- user_id.LowPart = auth_id.LowPart;
- user_id.HighPart = auth_id.HighPart;
-
- ifs_lock_rpcs();
-
- if (!(rpc = rpc_upgrade(NULL, 0, 1)))
- {
- size = sizeof(rpc_t) + 2*RPC_BUF_SIZE;
- rpc = ExAllocatePoolWithTag(NonPagedPool, size, 0x1234);
- if (!rpc)
- return NULL;
- num_rpcs++;
- memset(rpc, 0, size);
- rpc->next = rpc_list_head;
- rpc_list_head = rpc;
- rpc_upgrade(rpc, 0, 1);
- }
-
- rpc->out_buf = rpc->out_pos = (char*)(rpc+1);
- rpc->in_buf = rpc->in_pos = ((char*)(rpc+1))+RPC_BUF_SIZE;
-
- rpc->key = rand() + 10;
- rpc_marshal_long(rpc, rpc->key);
- rpc->bulk_out_len = (ULONG*)rpc->out_pos;
- rpc_marshal_long(rpc, 0);
-
- #if 0
- /* another way of obtaining credentials, with different effects */
- SeCaptureSubjectContext(&subj_context);
- acc_token = SeQuerySubjectContextToken(&subj_context);
- status = SeQueryAuthenticationIdToken(acc_token, &auth_id);
-
- user_id.LowPart = auth_id.LowPart;
- user_id.HighPart = auth_id.HighPart;
- SeReleaseSubjectContext(&subj_context);
- #endif
-
- rpc_marshal_longlong(rpc, user_id);
-
- ifs_unlock_rpcs();
-
- return rpc;
- }
-
- void rpc_destroy(rpc_t *rpc)
- {
- rpc_t *curr;
- int count;
-
- ifs_lock_rpcs();
-
- if (rpc_upgrade(rpc, -1, 0))
- ;
-
- ifs_unlock_rpcs();
- }
- #endif
-
-
- /* rpc internal functions for usermode */
- #ifndef RPC_KERN
- rpc_t *rpc_create(int size_hint)
- {
- ULONG size;
- rpc_t *rpc;
-
- size = sizeof(rpc_t) + 2*RPC_BUF_SIZE;
- rpc = malloc(size);
- if (!rpc)
- osi_panic("ifs_rpc: alloc buffer", __FILE__, __LINE__);
- memset(rpc, 0, size);
-
- rpc->out_buf = rpc->out_pos = (char*)(rpc+1);
- rpc->in_buf = rpc->in_pos = ((char*)(rpc+1)) + RPC_BUF_SIZE;
-
- rpc->key = rand() + 10;
- rpc_marshal_long(rpc, rpc->key);
-
- return rpc;
- }
-
- void rpc_destroy(rpc_t *rpc)
- {
- if (!rpc)
- return;
-
- free(rpc);
- }
-
- rpc_transact(rpc_t *rpc)
- {
- ULONG header_len;
- DWORD read = 0;
-
- if (!rpc)
- return IFSL_GENERIC_FAILURE;
-
- header_len = rpc->out_pos - rpc->out_buf;
-
- read = RPC_BUF_SIZE;
- return ifs_TransactRpc(rpc->out_buf, header_len, rpc->in_buf, &read);
- }
- #endif
-
-
- /* upcall stubs */
- #ifdef RPC_KERN
- long
- uc_namei(WCHAR *name, ULONG *fid)
- {
- rpc_t *rpc;
- ULONG status;
- MDL *mdl;
-
- /* consider putting namei cache here */
-
- rpc = rpc_create(0);
- if (!rpc)
- return IFSL_MEMORY;
-
- rpc_marshal_long(rpc, RPC_NAMEI);
- rpc_marshal_long(rpc, wcslen(name));
-
- rpc_queue_bulk(rpc, (void*)name, (wcslen(name)+1)*sizeof(wchar_t), NULL, 0);
-
- if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
- {
- rpc_cancel(rpc);
- rpt0(("cancel", "cancel namei"));
- return IFSL_RPC_TIMEOUT;
- }
-
- rpc_unmarshal_long(rpc, &status);
- rpc_unmarshal_long(rpc, fid);
-
- rpc_destroy(rpc);
- return status;
- }
-
- long
- uc_check_access(ULONG fid, ULONG access, ULONG *granted)
- {
- rpc_t *rpc;
- ULONG status;
-
- rpc = rpc_create(0);
- if (!rpc)
- return IFSL_MEMORY;
-
- rpc_marshal_long(rpc, RPC_CHECK_ACCESS);
- rpc_marshal_long(rpc, fid);
- rpc_marshal_long(rpc, access);
-
- rpc_queue(rpc);
- if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
- {
- rpc_cancel(rpc);
- rpt0(("cancel", "cancel access"));
- return IFSL_RPC_TIMEOUT;
- }
-
- rpc_unmarshal_long(rpc, &status);
- rpc_unmarshal_long(rpc, granted);
-
- rpc_destroy(rpc);
- return status;
- }
-
- long
- uc_create(WCHAR *name, ULONG attribs, LARGE_INTEGER alloc, ULONG access, ULONG *granted, ULONG *fid)
- {
- rpc_t *rpc;
- ULONG status;
-
- rpc = rpc_create(0);
- if (!rpc)
- return IFSL_MEMORY;
-
- rpc_marshal_long(rpc, RPC_CREATE);
- rpc_marshal_long(rpc, attribs);
- rpc_marshal_longlong(rpc, alloc);
- rpc_marshal_long(rpc, access);
-
- rpc_queue_bulk(rpc, (void*)name, (wcslen(name)+1)*sizeof(wchar_t), NULL, 0);
- if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
- {
- rpc_cancel(rpc);
- rpt0(("cancel", "cancel create"));
- return IFSL_RPC_TIMEOUT;
- }
-
- rpc_unmarshal_long(rpc, &status);
- rpc_unmarshal_long(rpc, granted);
- rpc_unmarshal_long(rpc, fid);
-
- rpc_destroy(rpc);
- return status;
- }
-
- long
- uc_stat(ULONG fid, ULONG *attribs, LARGE_INTEGER *size, LARGE_INTEGER *creation, LARGE_INTEGER *access, LARGE_INTEGER *change, LARGE_INTEGER *written)
- {
- rpc_t *rpc;
- ULONG status;
-
- rpc = rpc_create(0);
- if (!rpc)
- return IFSL_MEMORY;
-
- rpc_marshal_long(rpc, RPC_STAT);
- rpc_marshal_long(rpc, fid);
-
- rpc_queue(rpc);
- if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
- {
- rpc_cancel(rpc);
- rpt0(("cancel", "cancel stat"));
- return IFSL_RPC_TIMEOUT;
- }
-
- rpc_unmarshal_long(rpc, &status);
- rpc_unmarshal_long(rpc, attribs);
- rpc_unmarshal_longlong(rpc, size);
- rpc_unmarshal_longlong(rpc, creation);
- rpc_unmarshal_longlong(rpc, access);
- rpc_unmarshal_longlong(rpc, change);
- rpc_unmarshal_longlong(rpc, written);
-
- rpc_destroy(rpc);
- return status;
- }
-
- long
- uc_setinfo(ULONG fid, ULONG attribs, LARGE_INTEGER creation, LARGE_INTEGER access, LARGE_INTEGER change, LARGE_INTEGER written)
- {
- rpc_t *rpc;
- ULONG status;
-
- rpc = rpc_create(0);
- if (!rpc)
- return IFSL_MEMORY;
-
- rpc_marshal_long(rpc, RPC_SETINFO);
- rpc_marshal_long(rpc, fid);
- rpc_marshal_long(rpc, attribs);
- rpc_marshal_longlong(rpc, creation);
- rpc_marshal_longlong(rpc, access);
- rpc_marshal_longlong(rpc, change);
- rpc_marshal_longlong(rpc, written);
-
-
- rpc_queue(rpc);
- if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
- {
- rpc_cancel(rpc);
- rpt0(("cancel", "cancel setinfo"));
- return IFSL_RPC_TIMEOUT;
- }
-
- rpc_unmarshal_long(rpc, &status);
-
- rpc_destroy(rpc);
- return status;
- }
-
- long
- uc_trunc(ULONG fid, LARGE_INTEGER size)
- {
- rpc_t *rpc;
- ULONG status;
-
- rpc = rpc_create(0);
- if (!rpc)
- return IFSL_MEMORY;
-
- rpc_marshal_long(rpc, RPC_TRUNC);
- rpc_marshal_long(rpc, fid);
- rpc_marshal_longlong(rpc, size);
-
- rpc_queue(rpc);
- if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
- {
- rpc_cancel(rpc);
- rpt0(("cancel", "cancel trunc"));
- return IFSL_RPC_TIMEOUT;
- }
-
- rpc_unmarshal_long(rpc, &status);
-
- rpc_destroy(rpc);
- return status;
- }
-
- long
- uc_read(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *read, char *data)
- {
- rpc_t *rpc;
- ULONG status;
-
- rpc = rpc_create(0);
- if (!rpc)
- return IFSL_MEMORY;
-
- rpc_marshal_long(rpc, RPC_READ);
- rpc_marshal_long(rpc, fid);
- rpc_marshal_longlong(rpc, offset);
- rpc_marshal_long(rpc, length);
-
- rpc_queue_bulk(rpc, NULL, 0, data, length);
- if (!rpc_wait(rpc, RPC_TIMEOUT_LONG))
- {
- rpc_cancel(rpc);
- rpt0(("cancel", "cancel read"));
- return IFSL_RPC_TIMEOUT;
- }
-
- rpc_unmarshal_long(rpc, &status);
- rpc_unmarshal_long(rpc, read);
-
- rpc_destroy(rpc);
- return status;
- }
-
- long
- uc_write(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *written, char *data)
- {
- rpc_t *rpc;
- ULONG status;
-
- rpc = rpc_create(0);
- if (!rpc)
- return IFSL_MEMORY;
-
- rpc_marshal_long(rpc, RPC_WRITE);
- rpc_marshal_long(rpc, fid);
- rpc_marshal_longlong(rpc, offset);
- rpc_marshal_long(rpc, length);
-
- rpc_queue_bulk(rpc, data, length, NULL, 0);
- if (!rpc_wait(rpc, RPC_TIMEOUT_LONG))
- {
- rpc_cancel(rpc);
- rpt0(("cancel", "cancel write"));
- return IFSL_RPC_TIMEOUT;
- }
-
- rpc_unmarshal_long(rpc, &status);
- rpc_unmarshal_long(rpc, written);
-
- rpc_destroy(rpc);
- return status;
- }
-
- long
- uc_readdir(ULONG fid, LARGE_INTEGER cookie_in, WCHAR *filter, ULONG *count, char *data, ULONG *len)
- {
- rpc_t *rpc;
- ULONG status;
-
- rpc = rpc_create(0);
- if (!rpc)
- return IFSL_MEMORY;
-
- rpc_marshal_long(rpc, RPC_READDIR);
- rpc_marshal_long(rpc, fid);
- rpc_marshal_longlong(rpc, cookie_in);
- rpc_marshal_wstr(rpc, filter);
- rpc_marshal_long(rpc, *len);
-
- rpc_queue_bulk(rpc, NULL, 0, data, *len);
- if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
- {
- rpc_cancel(rpc);
- rpt0(("cancel", "cancel readdir"));
- return IFSL_RPC_TIMEOUT;
- }
-
- rpc_unmarshal_long(rpc, &status);
- rpc_unmarshal_long(rpc, count);
- rpc_unmarshal_long(rpc, len);
-
- rpc_destroy(rpc);
- return status;
- }
-
- long
- uc_close(ULONG fid)
- {
- rpc_t *rpc;
- ULONG status;
-
- rpc = rpc_create(0);
- if (!rpc)
- return IFSL_MEMORY;
-
- rpc_marshal_long(rpc, RPC_CLOSE);
- rpc_marshal_long(rpc, fid);
-
- rpc_queue(rpc);
- if (!rpc_wait(rpc, RPC_TIMEOUT_LONG))
- {
- rpc_cancel(rpc);
- rpt0(("cancel", "cancel close"));
- return IFSL_RPC_TIMEOUT;
- }
-
- rpc_unmarshal_long(rpc, &status);
-
- rpc_destroy(rpc);
- return status;
- }
-
- long
- uc_unlink(WCHAR *name)
- {
- rpc_t *rpc;
- ULONG status;
-
- rpc = rpc_create(0);
- if (!rpc)
- return IFSL_MEMORY;
-
- rpc_marshal_long(rpc, RPC_UNLINK);
- rpc_marshal_wstr(rpc, name);
-
- rpc_queue(rpc);
- if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
- {
- rpc_cancel(rpc);
- rpt0(("cancel", "cancel unlink"));
- return IFSL_RPC_TIMEOUT;
- }
-
- rpc_unmarshal_long(rpc, &status);
-
- rpc_destroy(rpc);
- return status;
- }
-
- long
- uc_ioctl_write(ULONG length, char *data, ULONG *key)
- {
- rpc_t *rpc;
- ULONG status;
-
- rpc = rpc_create(0);
- if (!rpc)
- return IFSL_MEMORY;
-
- rpc_marshal_long(rpc, RPC_IOCTL_WRITE);
- rpc_marshal_long(rpc, length);
-
- rpc_queue_bulk(rpc, data, length, NULL, 0);
- if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
- {
- rpc_cancel(rpc);
- rpt0(("cancel", "cancel ioctl write"));
- return IFSL_RPC_TIMEOUT;
- }
-
- rpc_unmarshal_long(rpc, &status);
- rpc_unmarshal_long(rpc, key);
-
- rpc_destroy(rpc);
- return status;
- }
-
- long
- uc_ioctl_read(ULONG key, ULONG *length, char *data)
- {
- rpc_t *rpc;
- ULONG status;
-
- rpc = rpc_create(0);
- if (!rpc)
- return IFSL_MEMORY;
-
- rpc_marshal_long(rpc, RPC_IOCTL_READ);
- rpc_marshal_long(rpc, key);
-
- rpc_queue_bulk(rpc, NULL, 0, data, *length);
- if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
- {
- rpc_cancel(rpc);
- rpt0(("cancel", "cancel ioctl read"));
- return IFSL_RPC_TIMEOUT;
- }
-
- rpc_unmarshal_long(rpc, &status);
- rpc_unmarshal_long(rpc, length);
-
- rpc_destroy(rpc);
- return status;
- }
-
- long
- uc_rename(ULONG fid, WCHAR *curr, WCHAR *new_dir, WCHAR *new_name, ULONG *new_fid)
- {
- rpc_t *rpc;
- ULONG status;
-
- rpc = rpc_create(0);
- if (!rpc)
- return IFSL_MEMORY;
-
- rpc_marshal_long(rpc, RPC_RENAME);
- rpc_marshal_long(rpc, fid);
- rpc_marshal_wstr(rpc, curr);
- rpc_marshal_wstr(rpc, new_dir);
- rpc_marshal_wstr(rpc, new_name);
-
- rpc_queue(rpc);
- if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
- {
- rpc_cancel(rpc);
- rpt0(("cancel", "cancel rename"));
- return IFSL_RPC_TIMEOUT;
- }
-
- rpc_unmarshal_long(rpc, &status);
- rpc_unmarshal_long(rpc, new_fid);
-
- rpc_destroy(rpc);
- return status;
- }
-
- long
- uc_flush(ULONG fid)
- {
- rpc_t *rpc;
- ULONG status;
-
- rpc = rpc_create(0);
- if (!rpc)
- return IFSL_MEMORY;
-
- rpc_marshal_long(rpc, RPC_FLUSH);
- rpc_marshal_long(rpc, fid);
-
- rpc_queue(rpc);
- if (!rpc_wait(rpc, RPC_TIMEOUT_LONG))
- {
- rpc_cancel(rpc);
- rpt0(("cancel", "cancel flush"));
- return IFSL_RPC_TIMEOUT;
- }
-
- rpc_unmarshal_long(rpc, &status);
-
- rpc_destroy(rpc);
- return status;
- }
- #endif
-
-
- /* downcall stubs */
- #ifndef RPC_KERN
- long dc_break_callback(ULONG fid)
- {
- rpc_t *rpc;
- ULONG status;
-
- rpc = rpc_create(0);
- if (!rpc)
- return IFSL_MEMORY;
-
- rpc_marshal_long(rpc, RPC_BREAK_CALLBACK);
- rpc_marshal_long(rpc, fid);
- if (!rpc_transact(rpc))
- {
- rpc_destroy(rpc);
- return IFSL_GENERIC_FAILURE;
- }
- rpc_unmarshal_long(rpc, &status);
- rpc_destroy(rpc);
- return status;
- }
-
- long dc_release_hooks(void)
- {
- rpc_t *rpc;
- ULONG status;
-
- rpc = rpc_create(0);
- if (!rpc)
- return IFSL_MEMORY;
-
- rpc_marshal_long(rpc, RPC_RELEASE_HOOKS);
- if (!rpc_transact(rpc))
- {
- rpc_destroy(rpc);
- return IFSL_GENERIC_FAILURE;
- }
- rpc_unmarshal_long(rpc, &status);
- rpc_destroy(rpc);
- return status;
- }
- #endif
-
-
- /* rpc packing function */
- rpc_marshal_long(rpc_t *rpc, ULONG data)
- {
- memcpy(rpc->out_pos, &data, sizeof(ULONG));
- rpc->out_pos += sizeof(ULONG);
- return 0;
- }
-
- rpc_marshal_longlong(rpc_t *rpc, LARGE_INTEGER data)
- {
- memcpy(rpc->out_pos, &data, sizeof(LARGE_INTEGER));
- rpc->out_pos += sizeof(LARGE_INTEGER);
- return 0;
- }
-
- rpc_marshal_wstr(rpc_t *rpc, WCHAR *str)
- {
- long len;
- len = wcslen(str);
- rpc_marshal_long(rpc, len);
- memcpy(rpc->out_pos, str, len*sizeof(WCHAR));
- rpc->out_pos += len*sizeof(WCHAR);
- return 0;
- }
-
-
- rpc_unmarshal_long(rpc_t *rpc, ULONG *data)
- {
- memcpy(data, rpc->in_pos, sizeof(ULONG));
- rpc->in_pos += sizeof(ULONG);
- return 0;
- }
-
- rpc_unmarshal_longlong(rpc_t *rpc, LARGE_INTEGER *data)
- {
- memcpy(data, rpc->in_pos, sizeof(LARGE_INTEGER));
- rpc->in_pos += sizeof(LARGE_INTEGER);
- return 0;
- }
-
- rpc_unmarshal_wstr(rpc_t *rpc, WCHAR *str)//, int len)
- {
- long len;
- rpc_unmarshal_long(rpc, &len);
- memcpy(str, rpc->in_pos, len*sizeof(WCHAR));
- rpc->in_pos += len*sizeof(WCHAR);
- str[len] = L'\0';
- return 0;
- }
-
-
- /* kernel-queue management functions */
- #ifdef RPC_KERN
- rpc_t *rpc_find(int id)
- {
- rpc_t *curr;
-
- curr = rpc_list_head;
- while (curr)
- {
- /* dead rpc structs should not be returned */
- if (curr->key == id && curr->status != 0)
- return curr;
- curr = curr->next;
- }
- return NULL;
- }
-
- rpc_t *rpc_upgrade(rpc_t *rpc, int old_status, int new_status)
- {
- rpc_t *curr;
-
- if (rpc)
- {
- ASSERT(!old_status || rpc_find(rpc->key));
- if (old_status != -1 && rpc->status != old_status)
- return NULL;
- curr = rpc;
- }
- else
- {
- curr = rpc_list_head;
- while (curr)
- {
- if (old_status == -1 || curr->status == old_status)
- break;
- curr = curr->next;
- }
- }
-
- if (!curr)
- return NULL;
-
- ASSERT(old_status == -1 || curr->status == old_status);
- curr->status = new_status;
-
- return curr;
- }
-
- rpc_queue(rpc_t *rpc)
- {
- int ret;
-
- ifs_lock_rpcs();
-
- KeInitializeEvent(&rpc->ev, NotificationEvent, FALSE);
- ret = (rpc_upgrade(rpc, 1, 2) != NULL);
- KeSetEvent(&comExt->outEvent, 0, FALSE);
-
- ifs_unlock_rpcs();
-
- return ret;
- }
-
- rpc_cancel(rpc_t *rpc)
- {
- rpc_destroy(rpc);
- }
-
- rpc_shutdown()
- {
- rpc_t *curr, *next;
-
- ifs_lock_rpcs();
-
- curr = rpc_list_head;
- while (curr)
- {
- next = curr->next;
- ExFreePoolWithTag(curr, 0x1234);
- num_rpcs--;
- curr = next;
- }
- rpc_list_head = NULL;
-
- ifs_unlock_rpcs();
- }
-
- rpc_wait(rpc_t *rpc, BOOLEAN long_op)
- {
- NTSTATUS ret;
- LARGE_INTEGER timeout;
-
- if (long_op)
- timeout.QuadPart = -600000000L; /* 60 seconds 60L*10000000L */
- else
- timeout.QuadPart = -200000000L; /* 20 seconds 20L*10000000L */
-
- do
- ret = KeWaitForSingleObject(&rpc->ev, Executive, KernelMode, FALSE, &timeout);
- while (ret != STATUS_SUCCESS && ret != STATUS_TIMEOUT);
-
- ifs_lock_rpcs();
- if (rpc->status == 2 || /* still queued */
- rpc->status == 5) /* send cancelled by library */
- {
- ifs_unlock_rpcs();
- return 0;
- }
-
- ifs_unlock_rpcs();
- if (ret == STATUS_SUCCESS)
- return 1;
- return 0;
- }
-
- rpc_queue_bulk(rpc_t *rpc, char *out_bulk, ULONG out_len, char *in_bulk, ULONG in_len)
- {
- rpc->bulk_out = out_bulk;
- *rpc->bulk_out_len = out_len;
- rpc->bulk_in = in_bulk;
- rpc->bulk_in_max = in_len;
- return rpc_queue(rpc);
- }
-
- rpc_get_len(rpc_t *rpc)
- {
- if (*rpc->bulk_out_len != 0xFFFFFFFC)
- return rpc->out_pos - rpc->out_buf + *rpc->bulk_out_len + sizeof(ULONG);
- else
- return rpc->out_pos - rpc->out_buf + sizeof(ULONG);
- }
-
- rpc_send(char *out_buf, int out_len, int *out_written)
- {
- rpc_t *rpc;
- int ret, mdl;
- ULONG header_len;
-
- restart:
-
- ifs_lock_rpcs();
- rpc = rpc_upgrade(NULL, 2, 3);
-
- if (!rpc)
- {
- ifs_unlock_rpcs();
- return 0;
- }
-
- if (rpc_get_len(rpc) > out_len)
- {
- ifs_unlock_rpcs();
- rpt0(("cancel", "cancel on send"));
- rpc_upgrade(rpc, -1, 5);
- KeSetEvent(&rpc->ev, IO_NETWORK_INCREMENT, FALSE);
- goto restart;
- }
-
- header_len = rpc->out_pos - rpc->out_buf;
- RtlCopyMemory(out_buf, rpc->out_buf, header_len);
-
- if (*rpc->bulk_out_len && rpc->bulk_out)
- RtlCopyMemory(out_buf + header_len, rpc->bulk_out, *rpc->bulk_out_len);
- *out_written = header_len + *rpc->bulk_out_len;
-
- ifs_unlock_rpcs();
- return (*out_written != 0);
- }
- #endif
-
-
- /* rpc library api */
- #ifdef RPC_KERN
- rpc_recv(char *in_buf, ULONG len)
- {
- ULONG key, header_size;
- char *alloc;
- rpc_t *rpc;
-
- ifs_lock_rpcs();
-
- rpc = rpc_find(*(ULONG*)in_buf);
- if (!rpc) /* rpc was cancelled while waiting */
- {
- ifs_unlock_rpcs();
- return -1;
- }
-
- alloc = rpc->in_buf;
- rpc->in_buf = rpc->in_pos = in_buf;
- rpc_unmarshal_long(rpc, &key);
- ASSERT(key == rpc->key);
- rpc_unmarshal_long(rpc, &rpc->bulk_in_len);
-
- rpc->in_buf = rpc->in_pos = alloc;
- header_size = len - rpc->bulk_in_len;
- ASSERT(header_size < RPC_BUF_SIZE);
-
- RtlCopyMemory(rpc->in_buf, in_buf + 2*sizeof(ULONG), header_size - 2*sizeof(ULONG));
- if (rpc->bulk_in_len && rpc->bulk_in)
- {
- ASSERT(rpc->bulk_in_len <= rpc->bulk_in_max);
- RtlCopyMemory(rpc->bulk_in, in_buf + header_size, rpc->bulk_in_len);
- }
-
- KeSetEvent(&rpc->ev, IO_NETWORK_INCREMENT, FALSE); /* priority boost for waiting thread */
- ifs_unlock_rpcs();
- return 0;
- }
-
- rpc_call(ULONG in_len, char *in_buf, ULONG out_max, char *out_buf, ULONG *out_len)
- {
- long rpc_code;
- ULONG status;
- WCHAR name[1024];
- ULONG key, fid;
- LARGE_INTEGER user_id;
- rpc_t rpc;
-
- rpc.in_buf = rpc.in_pos = in_buf;
- rpc.out_buf = rpc.out_pos = out_buf;
-
- rpc_unmarshal_long(&rpc, &key);
- rpc_unmarshal_long(&rpc, &rpc_code);
-
- switch (rpc_code)
- {
- case RPC_BREAK_CALLBACK:
- rpc_unmarshal_long(&rpc, &fid);
- status = dc_break_callback(fid);
- rpc_marshal_long(&rpc, status);
- break;
- case RPC_RELEASE_HOOKS:
- status = dc_release_hooks();
- break;
- }
- *out_len = rpc.out_pos - rpc.out_buf;
- return 0;
- }
- #endif
-
- #ifndef RPC_KERN
- rpc_parse(rpc_t *rpc)
- {
- long rpc_code;
- ULONG status;
- WCHAR name[1024];
- ULONG key;
- LARGE_INTEGER user_id;
-
- rpc_unmarshal_long(rpc, &key);
- rpc_unmarshal_long(rpc, &rpc->bulk_in_len);
- rpc_unmarshal_longlong(rpc, &user_id);
- rpc_unmarshal_long(rpc, &rpc_code);
-
- ifs_ImpersonateClient(user_id);
-
- rpc_marshal_long(rpc, key);
- rpc->bulk_out_len = (ULONG*)rpc->out_pos;
- rpc_marshal_long(rpc, 0);
-
- switch (rpc_code)
- {
- case RPC_NAMEI:
- {
- ULONG fid, length;
- char *data;
- //rpc_unmarshal_wstr(rpc, name);
- rpc_unmarshal_long(rpc, &length);
- //data = *((char**)rpc->in_pos);
- data = rpc->in_pos;
- status = uc_namei((WCHAR*)data, &fid);
- //status = uc_namei(name, &fid);
- rpc_marshal_long(rpc, status);
- rpc_marshal_long(rpc, fid);
- }
- break;
- case RPC_CHECK_ACCESS:
- {
- ULONG fid, access, granted;
- rpc_unmarshal_long(rpc, &fid);
- rpc_unmarshal_long(rpc, &access);
- status = uc_check_access(fid, access, &granted);
- rpc_marshal_long(rpc, status);
- rpc_marshal_long(rpc, granted);
- }
- break;
- case RPC_CREATE:
- {
- LARGE_INTEGER alloc;
- ULONG access, granted, fid, attribs;
- char *data;
-
- rpc_unmarshal_long(rpc, &attribs);
- rpc_unmarshal_longlong(rpc, &alloc);
- rpc_unmarshal_long(rpc, &access);
- //rpc_unmarshal_wstr(rpc, name);
- data = rpc->in_pos;
- status = uc_create((WCHAR*)data, attribs, alloc, access, &granted, &fid);
- rpc_marshal_long(rpc, status);
- rpc_marshal_long(rpc, granted);
- rpc_marshal_long(rpc, fid);
- }
- break;
- case RPC_STAT:
- {
- ULONG fid, attribs;
- LARGE_INTEGER size, creation, access, change, written;
- rpc_unmarshal_long(rpc, &fid);
- status = uc_stat(fid, &attribs, &size, &creation, &access, &change, &written);
- rpc_marshal_long(rpc, status);
- rpc_marshal_long(rpc, attribs);
- rpc_marshal_longlong(rpc, size);
- rpc_marshal_longlong(rpc, creation);
- rpc_marshal_longlong(rpc, access);
- rpc_marshal_longlong(rpc, change);
- rpc_marshal_longlong(rpc, written);
- }
- break;
- case RPC_READ:
- {
- ULONG fid, length, read;
- LARGE_INTEGER offset;
- char *data, *save;
- rpc_unmarshal_long(rpc, &fid);
- rpc_unmarshal_longlong(rpc, &offset);
- rpc_unmarshal_long(rpc, &length);
- save = rpc->out_pos;
- rpc_marshal_long(rpc, 0);
- rpc_marshal_long(rpc, 0);
- data = rpc->out_pos;
- rpc->out_pos = save;
- status = uc_read(fid, offset, length, &read, data);
- rpc_marshal_long(rpc, status);
- rpc_marshal_long(rpc, read);
- rpc->out_pos += read;
- *rpc->bulk_out_len = read;
- }
- break;
- case RPC_WRITE:
- {
- ULONG fid, length, written;
- LARGE_INTEGER offset;
- char *data;
- rpc_unmarshal_long(rpc, &fid);
- rpc_unmarshal_longlong(rpc, &offset);
- rpc_unmarshal_long(rpc, &length);
- data = rpc->in_pos;
- status = uc_write(fid, offset, length, &written, data);
- rpc_marshal_long(rpc, status);
- rpc_marshal_long(rpc, written);
- }
- break;
- case RPC_TRUNC:
- {
- ULONG fid;
- LARGE_INTEGER size;
- rpc_unmarshal_long(rpc, &fid);
- rpc_unmarshal_longlong(rpc, &size);
- status = uc_trunc(fid, size);
- rpc_marshal_long(rpc, status);
- }
- break;
- case RPC_SETINFO:
- {
- ULONG fid, attribs;
- LARGE_INTEGER creation, access, change, written;
- rpc_unmarshal_long(rpc, &fid);
- rpc_unmarshal_long(rpc, &attribs);
- rpc_unmarshal_longlong(rpc, &creation);
- rpc_unmarshal_longlong(rpc, &access);
- rpc_unmarshal_longlong(rpc, &change);
- rpc_unmarshal_longlong(rpc, &written);
- status = uc_setinfo(fid, attribs, creation, access, change, written);
- rpc_marshal_long(rpc, status);
- }
- break;
- case RPC_READDIR:
- {
- ULONG fid, count, len;
- LARGE_INTEGER cookie_in;
- char *data, *save;
- rpc_unmarshal_long(rpc, &fid);
- rpc_unmarshal_longlong(rpc, &cookie_in);
- rpc_unmarshal_wstr(rpc, name);
- rpc_unmarshal_long(rpc, &len);
- save = rpc->out_pos;
- rpc_marshal_long(rpc, 0);
- rpc_marshal_long(rpc, 0);
- rpc_marshal_long(rpc, 0);
- data = rpc->out_pos;
- rpc->out_pos = save;
- status = uc_readdir(fid, cookie_in, name, &count, data, &len);
- rpc_marshal_long(rpc, status);
- rpc_marshal_long(rpc, count);
- rpc_marshal_long(rpc, len);
- rpc->out_pos += len;
- *rpc->bulk_out_len = len;
- }
- break;
- case RPC_CLOSE:
- {
- ULONG fid;
- rpc_unmarshal_long(rpc, &fid);
- status = uc_close(fid);
- rpc_marshal_long(rpc, status);
- }
- break;
- case RPC_UNLINK:
- {
- rpc_unmarshal_wstr(rpc, name);
- status = uc_unlink(name);
- rpc_marshal_long(rpc, status);
- }
- break;
- case RPC_IOCTL_WRITE:
- {
- ULONG length, key;
- rpc_unmarshal_long(rpc, &length);
- status = uc_ioctl_write(length, rpc->in_pos, &key);
- rpc_marshal_long(rpc, status);
- rpc_marshal_long(rpc, key);
- }
- break;
- case RPC_IOCTL_READ:
- {
- ULONG key, length;
- char *save, *data;
- rpc_unmarshal_long(rpc, &key);
- save = rpc->out_pos;
- rpc_marshal_long(rpc, 0);
- rpc_marshal_long(rpc, 0);
- data = rpc->out_pos;
- rpc->out_pos = save;
- status = uc_ioctl_read(key, &length, data);
- rpc_marshal_long(rpc, status);
- rpc_marshal_long(rpc, length);
- rpc->out_pos += length;
- *rpc->bulk_out_len = length;
- }
- break;
- case RPC_RENAME:
- {
- ULONG fid, new_fid;
- WCHAR curr[1024], new_dir[1024], new_name[1024];
- rpc_unmarshal_long(rpc, &fid);
- rpc_unmarshal_wstr(rpc, curr);
- rpc_unmarshal_wstr(rpc, new_dir);
- rpc_unmarshal_wstr(rpc, new_name);
- status = uc_rename(fid, curr, new_dir, new_name, &new_fid);
- rpc_marshal_long(rpc, status);
- rpc_marshal_long(rpc, new_fid);
- }
- break;
- case RPC_FLUSH:
- {
- ULONG fid;
- rpc_unmarshal_long(rpc, &fid);
- status = uc_flush(fid);
- rpc_marshal_long(rpc, status);
- }
- break;
- }
- }
- #endif
--- 0 ----
Index: openafs/src/WINNT/afsrdr/ifs_rpc.h
diff -c openafs/src/WINNT/afsrdr/ifs_rpc.h:1.3.4.1 openafs/src/WINNT/afsrdr/ifs_rpc.h:removed
*** openafs/src/WINNT/afsrdr/ifs_rpc.h:1.3.4.1 Thu Jul 20 17:46:21 2006
--- openafs/src/WINNT/afsrdr/ifs_rpc.h Sat Mar 22 21:01:37 2008
***************
*** 1,119 ****
- /* copyright (c) 2005
- * the regents of the university of michigan
- * all rights reserved
- *
- * permission is granted to use, copy, create derivative works and
- * redistribute this software and such derivative works for any purpose,
- * so long as the name of the university of michigan is not used in
- * any advertising or publicity pertaining to the use or distribution
- * of this software without specific, written prior authorization. if
- * the above copyright notice or any other identification of the
- * university of michigan is included in any copy of any portion of
- * this software, then the disclaimer below must also be included.
- *
- * this software is provided as is, without representation from the
- * university of michigan as to its fitness for any purpose, and without
- * warranty by the university of michigan of any kind, either express
- * or implied, including without limitation the implied warranties of
- * merchantability and fitness for a particular purpose. the regents
- * of the university of michigan shall not be liable for any damages,
- * including special, indirect, incidental, or consequential damages,
- * with respect to any claim arising out or in connection with the use
- * of the software, even if it has been or is hereafter advised of the
- * possibility of such damages.
- */
-
- /* versioning history
- *
- * 03-jun 2005 (eric williams) entered into versioning
- */
-
- #ifdef RPC_KERN
- #include
- #include
- #else
- #include
- #include
- #include
- #endif
-
-
- /* maximum number of users, based on SID, that can access AFS at one time */
- #define MAX_AFS_USERS 256
-
- /* maximum number of threads that can make simultaneous calls into afsrdr,
- because we maintain a credential set for each thread in a single table. */
- #define MAX_CRED_MAPS 64
-
- /* size if outgoing/incoming RPC buffer (for parameters only, not bulk data) */
- #define RPC_BUF_SIZE 2048
-
- /* max. chunk size for RPC transfers */
- #define TRANSFER_CHUNK_SIZE (1024*1024)
-
-
- /* upcalls */
- #define RPC_NAMEI 0x10
- #define RPC_CHECK_ACCESS 0x11
- #define RPC_CREATE 0x12
- #define RPC_STAT 0x13
- #define RPC_READ 0x14
- #define RPC_WRITE 0x15
- #define RPC_TRUNC 0x16
- #define RPC_SETINFO 0x17
- #define RPC_READDIR 0x18
- #define RPC_CLOSE 0x19
- #define RPC_UNLINK 0x1A
- #define RPC_IOCTL_WRITE 0x1B
- #define RPC_IOCTL_READ 0x1C
- #define RPC_RENAME 0x1D
- #define RPC_FLUSH 0x1E
-
-
- /* downcalls */
- #define RPC_BREAK_CALLBACK 0x80
- #define RPC_RELEASE_HOOKS 0x81
-
-
- /* internal module flags */
- #define RPC_TIMEOUT_SHORT 0
- #define RPC_TIMEOUT_LONG 1
-
-
- /* internal data struct for both client and server */
- struct rpc
- {
- #ifdef RPC_KERN
- struct rpc *next;
- int size;
- KEVENT ev;
- MDL *bulk_mdl;
- #endif
- char *bulk_out;
- ULONG *bulk_out_len;
- char *bulk_in;
- ULONG bulk_in_len, bulk_in_max;
- ULONG key;
- char *out_buf, *out_pos;
- char *in_buf, *in_pos;
- int status;
- };
- typedef struct rpc rpc_t;
-
-
- /* application interface into rpc library */
- #ifdef RPC_KERN
- rpc_call(ULONG in_len, char *in_buf, ULONG out_max, char *out_buf, ULONG *out_len);
- rpc_set_context(void *context);
- rpc_remove_context();
- rpc_get_len(rpc_t *rpc);
- rpc_send(char *out_buf, int out_len, int *out_written);
- rpc_recv(char *in_buf, ULONG len);
- rpc_shutdown();
-
- #else
-
- rpc_parse(rpc_t *rpc);
- #endif
-
-
--- 0 ----
Index: openafs/src/WINNT/afsrdr/kif.h
diff -c openafs/src/WINNT/afsrdr/kif.h:1.4.4.2 openafs/src/WINNT/afsrdr/kif.h:removed
*** openafs/src/WINNT/afsrdr/kif.h:1.4.4.2 Thu Jul 20 17:46:21 2006
--- openafs/src/WINNT/afsrdr/kif.h Sat Mar 22 21:01:37 2008
***************
*** 1,113 ****
- /* copyright (c) 2005
- * the regents of the university of michigan
- * all rights reserved
- *
- * permission is granted to use, copy, create derivative works and
- * redistribute this software and such derivative works for any purpose,
- * so long as the name of the university of michigan is not used in
- * any advertising or publicity pertaining to the use or distribution
- * of this software without specific, written prior authorization. if
- * the above copyright notice or any other identification of the
- * university of michigan is included in any copy of any portion of
- * this software, then the disclaimer below must also be included.
- *
- * this software is provided as is, without representation from the
- * university of michigan as to its fitness for any purpose, and without
- * warranty by the university of michigan of any kind, either express
- * or implied, including without limitation the implied warranties of
- * merchantability and fitness for a particular purpose. the regents
- * of the university of michigan shall not be liable for any damages,
- * including special, indirect, incidental, or consequential damages,
- * with respect to any claim arising out or in connection with the use
- * of the software, even if it has been or is hereafter advised of the
- * possibility of such damages.
- */
-
- /* versioning history
- *
- * 03-jun 2005 (eric williams) entered into versioning
- */
-
-
- /* this is based on BUF_FILEHASH, but we were not getting unique hashes */
- #define FID_HASH_FN(fidp) \
- ((((fidp)->vnode + \
- ((fidp)->unique << 13) + ((fidp)->unique >> (32-13)) + \
- (fidp)->volume + \
- (fidp)->cell)))
-
-
- /* dirent information */
- struct readdir_data
- {
- LARGE_INTEGER cookie;
- long offset;
- LARGE_INTEGER creation, access, write, change, size;
- ULONG attribs, name_length; /* chars */
- CCHAR short_name_length; /* chars */
- WCHAR short_name[14];
- WCHAR name[];
- };
- typedef struct readdir_data readdir_data_t;
-
-
- /* error codes */
- #define IFSL_SUCCESS_BASE 0x00000000
- #define IFSL_FAIL_BASE 0x80000000
-
- #define IFSL_SUCCESS (IFSL_SUCCESS_BASE + 0)
- #define IFSL_DOES_NOT_EXIST (IFSL_FAIL_BASE + 1)
- #define IFSL_NOT_IMPLEMENTED (IFSL_FAIL_BASE + 2)
- #define IFSL_END_OF_ENUM (IFSL_SUCCESS_BASE + 3)
- #define IFSL_CANNOT_MAKE (IFSL_FAIL_BASE + 4)
- #define IFSL_END_OF_FILE (IFSL_SUCCESS_BASE + 5)
- #define IFSL_NO_ACCESS (IFSL_FAIL_BASE + 6)
- #define IFSL_BUFFER_TOO_SMALL (IFSL_FAIL_BASE + 7)
- #define IFSL_SHARING_VIOLATION (IFSL_FAIL_BASE + 8)
- #define IFSL_BAD_INPUT (IFSL_FAIL_BASE + 9)
- #define IFSL_GENERIC_FAILURE (IFSL_FAIL_BASE + 10)
- #define IFSL_OPEN_CREATED (IFSL_SUCCESS_BASE + 11)
- #define IFSL_OPEN_EXISTS (IFSL_FAIL_BASE + 12)
- #define IFSL_OPEN_OPENED (IFSL_SUCCESS_BASE + 13)
- #define IFSL_OPEN_OVERWRITTEN (IFSL_SUCCESS_BASE + 14)
- #define IFSL_OPEN_SUPERSCEDED (IFSL_SUCCESS_BASE + 15)
- #define IFSL_BADFILENAME (IFSL_FAIL_BASE + 16)
- #define IFSL_READONLY (IFSL_FAIL_BASE + 17)
- #define IFSL_IS_A_DIR (IFSL_FAIL_BASE + 18)
- #define IFSL_PATH_DOES_NOT_EXIST (IFSL_FAIL_BASE + 19)
- #define IFSL_IS_A_FILE (IFSL_FAIL_BASE + 20)
- #define IFSL_NO_FILE (IFSL_FAIL_BASE + 21)
- #define IFSL_NOT_EMPTY (IFSL_FAIL_BASE + 22)
- #define IFSL_RPC_TIMEOUT (IFSL_FAIL_BASE + 23)
- #define IFSL_OVERQUOTA (IFSL_FAIL_BASE + 24)
- #define IFSL_MEMORY (IFSL_FAIL_BASE + 25)
- #define IFSL_UNSPEC (IFSL_FAIL_BASE + 26)
-
-
- /* ioctl codes */
- #define IOCTL_AFSRDR_IOCTL CTL_CODE(IOCTL_DISK_BASE, 0x007, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
- #define IOCTL_AFSRDR_DOWNCALL CTL_CODE(IOCTL_DISK_BASE, 0x008, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
- #define IOCTL_AFSRDR_GET_PATH CTL_CODE(IOCTL_DISK_BASE, 0x009, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
-
-
- /* upcalls */
- long uc_namei(WCHAR *name, ULONG *fid);
- long uc_check_access(ULONG fid, ULONG access, ULONG *granted);
- long uc_create(WCHAR *str, ULONG attribs, LARGE_INTEGER alloc, ULONG access, ULONG *granted, ULONG *fid);
- long uc_stat(ULONG fid, ULONG *attribs, LARGE_INTEGER *size, LARGE_INTEGER *creation, LARGE_INTEGER *access, LARGE_INTEGER *change, LARGE_INTEGER *written);
- long uc_setinfo(ULONG fid, ULONG attribs, LARGE_INTEGER creation, LARGE_INTEGER access, LARGE_INTEGER change, LARGE_INTEGER written);
- long uc_trunc(ULONG fid, LARGE_INTEGER size);
- long uc_read(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *read, char *data);
- long uc_write(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *written, char *data);
- long uc_readdir(ULONG fid, LARGE_INTEGER cookie_in, WCHAR *filter, ULONG *count, char *data, ULONG_PTR *len);
- long uc_close(ULONG fid);
- long uc_unlink(WCHAR *name);
- long uc_ioctl_write(ULONG length, char *data, ULONG_PTR *key);
- long uc_ioctl_read(ULONG_PTR key, ULONG *length, char *data);
- long uc_rename(ULONG fid, WCHAR *curr, WCHAR *new_dir, WCHAR *new_name, ULONG *new_fid);
- long uc_flush(ULONG fid);
-
-
- /* downcalls */
- long dc_break_callback(ULONG fid);
- long dc_release_hooks(void);
--- 0 ----
Index: openafs/src/WINNT/afsrdr/makefile
diff -c openafs/src/WINNT/afsrdr/makefile:1.1 openafs/src/WINNT/afsrdr/makefile:removed
*** openafs/src/WINNT/afsrdr/makefile:1.1 Wed Jun 15 12:51:47 2005
--- openafs/src/WINNT/afsrdr/makefile Sat Mar 22 21:01:37 2008
***************
*** 1 ****
- !INCLUDE $(NTMAKEENV)\makefile.def
--- 0 ----
Index: openafs/src/WINNT/afsrdr/sources
diff -c openafs/src/WINNT/afsrdr/sources:1.2 openafs/src/WINNT/afsrdr/sources:removed
*** openafs/src/WINNT/afsrdr/sources:1.2 Thu Aug 4 12:32:39 2005
--- openafs/src/WINNT/afsrdr/sources Sat Mar 22 21:01:37 2008
***************
*** 1,31 ****
- #/* copyright (c) 2005
- # * the regents of the university of michigan
- # * all rights reserved
- # *
- # * permission is granted to use, copy, create derivative works and
- # * redistribute this software and such derivative works for any purpose,
- # * so long as the name of the university of michigan is not used in
- # * any advertising or publicity pertaining to the use or distribution
- # * of this software without specific, written prior authorization. if
- # * the above copyright notice or any other identification of the
- # * university of michigan is included in any copy of any portion of
- # * this software, then the disclaimer below must also be included.
- # *
- # * this software is provided as is, without representation from the
- # * university of michigan as to its fitness for any purpose, and without
- # * warranty by the university of michigan of any kind, either express
- # * or implied, including without limitation the implied warranties of
- # * merchantability and fitness for a particular purpose. the regents
- # * of the university of michigan shall not be liable for any damages,
- # * including special, indirect, incidental, or consequential damages,
- # * with respect to any claim arising out or in connection with the use
- # * of the software, even if it has been or is hereafter advised of the
- # * possibility of such damages.
- # */
-
- SOURCES= afsrdr.c ifs_rpc.c afsrdr.rc
- TARGETNAME=afsrdr
- TARGETPATH=obj
- TARGETTYPE=DRIVER
- DRIVERTYPE=FS
- C_DEFINES=-DUNICODE -DRPT_CLI -DRPC_KERN
--- 0 ----
Index: openafs/src/WINNT/aklog/aklog.c
diff -c openafs/src/WINNT/aklog/aklog.c:1.14.4.8 openafs/src/WINNT/aklog/aklog.c:1.14.4.10
*** openafs/src/WINNT/aklog/aklog.c:1.14.4.8 Sat Jan 5 12:01:24 2008
--- openafs/src/WINNT/aklog/aklog.c Fri Mar 21 20:20:24 2008
***************
*** 194,208 ****
static int usev5 = TRUE; /* use kerberos 5? */
static int use524 = FALSE; /* use krb524? */
static krb5_ccache _krb425_ccache;
long GetLocalCell(struct afsconf_dir **pconfigdir, char *local_cell)
{
if (!(*pconfigdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH)))
{
fprintf(stderr, "%s: can't get afs configuration (afsconf_Open(%s))\n",
progname, AFSDIR_CLIENT_ETC_DIRPATH);
! exit(AKLOG_AFS);
}
return afsconf_GetLocalCell(*pconfigdir, local_cell, MAXCELLCHARS);
--- 194,218 ----
static int usev5 = TRUE; /* use kerberos 5? */
static int use524 = FALSE; /* use krb524? */
+ static krb5_context context = 0;
static krb5_ccache _krb425_ccache;
+ void akexit(int exit_code)
+ {
+ if (_krb425_ccache)
+ krb5_cc_close(context, _krb425_ccache);
+ if (context)
+ krb5_free_context(context);
+ exit(exit_code);
+ }
+
long GetLocalCell(struct afsconf_dir **pconfigdir, char *local_cell)
{
if (!(*pconfigdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH)))
{
fprintf(stderr, "%s: can't get afs configuration (afsconf_Open(%s))\n",
progname, AFSDIR_CLIENT_ETC_DIRPATH);
! akexit(AKLOG_AFS);
}
return afsconf_GetLocalCell(*pconfigdir, local_cell, MAXCELLCHARS);
***************
*** 398,403 ****
--- 408,414 ----
int des_pcbc_init()
{
abort();
+ return 0; /* avoid warning */
}
#ifdef HAVE_KRB4
***************
*** 430,435 ****
--- 441,451 ----
krb5_error_code r;
static krb5_principal client_principal = 0;
+ if (client_principal) {
+ krb5_free_principal(context, client_principal);
+ client_principal = 0;
+ }
+
memset((char *)&increds, 0, sizeof(increds));
if ((r = krb5_build_principal(context, &increds.server,
***************
*** 440,449 ****
return((int)r);
}
! if (!_krb425_ccache)
! krb5_cc_default(context, &_krb425_ccache);
! if (!client_principal)
! krb5_cc_get_principal(context, _krb425_ccache, &client_principal);
increds.client = client_principal;
increds.times.endtime = 0;
--- 456,471 ----
return((int)r);
}
! if (!_krb425_ccache) {
! if ((r = krb5_cc_default(context, &_krb425_ccache)))
! return ((int)r);
! }
! if (!client_principal) {
! if ((r = krb5_cc_get_principal(context, _krb425_ccache, &client_principal))) {
! krb5_cc_close(context, _krb425_ccache);
! return ((int)r);
! }
! }
increds.client = client_principal;
increds.times.endtime = 0;
***************
*** 451,462 ****
increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
r = krb5_get_credentials(context, 0, _krb425_ccache, &increds, creds);
! if (r)
return((int)r);
!
/* This requires krb524d to be running with the KDC */
if (c != NULL)
r = krb5_524_convert_creds(context, *creds, c);
return((int)r);
}
--- 473,485 ----
increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
r = krb5_get_credentials(context, 0, _krb425_ccache, &increds, creds);
! if (r) {
return((int)r);
! }
/* This requires krb524d to be running with the KDC */
if (c != NULL)
r = krb5_524_convert_creds(context, *creds, c);
+
return((int)r);
}
***************
*** 566,572 ****
if (GetLocalCell(&configdir, local_cell))
{
fprintf(stderr, "%s: can't determine local cell.\n", progname);
! exit(AKLOG_AFS);
}
if ((cell == NULL) || (cell[0] == 0))
--- 589,595 ----
if (GetLocalCell(&configdir, local_cell))
{
fprintf(stderr, "%s: can't determine local cell.\n", progname);
! akexit(AKLOG_AFS);
}
if ((cell == NULL) || (cell[0] == 0))
***************
*** 1046,1052 ****
if (++symlinkcount > MAXSYMLINKS)
{
fprintf(stderr, "%s: %s\n", progname, strerror(ELOOP));
! exit(AKLOG_BADPATH);
}
memset(tmpbuf, 0, sizeof(tmpbuf));
if (elast_comp)
--- 1069,1075 ----
if (++symlinkcount > MAXSYMLINKS)
{
fprintf(stderr, "%s: %s\n", progname, strerror(ELOOP));
! akexit(AKLOG_BADPATH);
}
memset(tmpbuf, 0, sizeof(tmpbuf));
if (elast_comp)
***************
*** 1116,1122 ****
fprintf(stderr, "Unable to find current working directory:\n");
fprintf(stderr, "%s\n", pathtocheck);
fprintf(stderr, "Try an absolute pathname.\n");
! exit(AKLOG_BADPATH);
}
else
{
--- 1139,1145 ----
fprintf(stderr, "Unable to find current working directory:\n");
fprintf(stderr, "%s\n", pathtocheck);
fprintf(stderr, "Try an absolute pathname.\n");
! akexit(AKLOG_BADPATH);
}
else
{
***************
*** 1217,1223 ****
fprintf(stderr, " No commandline arguments means ");
fprintf(stderr, "authenticate to the local cell.\n");
fprintf(stderr, "\n");
! exit(AKLOG_USAGE);
}
void
--- 1240,1246 ----
fprintf(stderr, " No commandline arguments means ");
fprintf(stderr, "authenticate to the local cell.\n");
fprintf(stderr, "\n");
! akexit(AKLOG_USAGE);
}
void
***************
*** 1233,1239 ****
FreeLibrary(h);
else {
fprintf(stderr, "Kerberos for Windows library %s is not available.\n", KRB5LIB);
! exit(AKLOG_KFW_NOT_INSTALLED);
}
}
--- 1256,1262 ----
FreeLibrary(h);
else {
fprintf(stderr, "Kerberos for Windows library %s is not available.\n", KRB5LIB);
! akexit(AKLOG_KFW_NOT_INSTALLED);
}
}
***************
*** 1246,1256 ****
FreeLibrary(h);
else {
fprintf(stderr, "Kerberos for Windows library krbv4w32.dll is not available.\n");
! exit(AKLOG_KFW_NOT_INSTALLED);
}
#else
fprintf(stderr, "Kerberos v4 is not available in this build of aklog.\n");
! exit(AKLOG_USAGE);
#endif
}
--- 1269,1279 ----
FreeLibrary(h);
else {
fprintf(stderr, "Kerberos for Windows library krbv4w32.dll is not available.\n");
! akexit(AKLOG_KFW_NOT_INSTALLED);
}
#else
fprintf(stderr, "Kerberos v4 is not available in this build of aklog.\n");
! akexit(AKLOG_USAGE);
#endif
}
***************
*** 1277,1284 ****
linked_list paths; /* List of paths to log to */
ll_node *cur_node;
- krb5_context context = 0;
-
memset(&cellinfo, 0, sizeof(cellinfo));
memset(realm, 0, sizeof(realm));
--- 1300,1305 ----
***************
*** 1376,1389 ****
else
{
fprintf(stderr, "%s: failure copying cellinfo.\n", progname);
! exit(AKLOG_MISC);
}
}
else
{
fprintf(stderr, "%s: failure adding cell to cells list.\n",
progname);
! exit(AKLOG_MISC);
}
memset(&cellinfo, 0, sizeof(cellinfo));
cmode = FALSE;
--- 1397,1410 ----
else
{
fprintf(stderr, "%s: failure copying cellinfo.\n", progname);
! akexit(AKLOG_MISC);
}
}
else
{
fprintf(stderr, "%s: failure adding cell to cells list.\n",
progname);
! akexit(AKLOG_MISC);
}
memset(&cellinfo, 0, sizeof(cellinfo));
cmode = FALSE;
***************
*** 1402,1415 ****
{
fprintf(stderr, "%s: failure copying path name.\n",
progname);
! exit(AKLOG_MISC);
}
}
else
{
fprintf(stderr, "%s: failure adding path to paths list.\n",
progname);
! exit(AKLOG_MISC);
}
pmode = FALSE;
memset(path, 0, sizeof(path));
--- 1423,1436 ----
{
fprintf(stderr, "%s: failure copying path name.\n",
progname);
! akexit(AKLOG_MISC);
}
}
else
{
fprintf(stderr, "%s: failure adding path to paths list.\n",
progname);
! akexit(AKLOG_MISC);
}
pmode = FALSE;
memset(path, 0, sizeof(path));
***************
*** 1455,1462 ****
status = AKLOG_SOMETHINGSWRONG;
}
! if(usev5)
! krb5_free_context(context);
!
! exit(status);
}
--- 1476,1480 ----
status = AKLOG_SOMETHINGSWRONG;
}
! akexit(status);
}
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.5.6.2 openafs/src/WINNT/client_config/lang/de_DE/afs_config.rc:1.5.6.3
*** openafs/src/WINNT/client_config/lang/de_DE/afs_config.rc:1.5.6.2 Tue Dec 12 15:41:15 2006
--- openafs/src/WINNT/client_config/lang/de_DE/afs_config.rc Mon Mar 10 14:18:13 2008
***************
*** 357,364 ****
BEGIN
EDITTEXT IDC_LAN_ADAPTER,90,20,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_PROBE,90,40,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_THREADS,90,60,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_DAEMONS,90,80,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_SYSNAME,90,100,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_MOUNTDIR,90,120,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_ROOTVOLUME,90,140,83,13,ES_AUTOHSCROLL
--- 357,364 ----
BEGIN
EDITTEXT IDC_LAN_ADAPTER,90,20,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_PROBE,90,40,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_DAEMONS,90,60,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_THREADS,90,80,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_SYSNAME,90,100,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_MOUNTDIR,90,120,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_ROOTVOLUME,90,140,83,13,ES_AUTOHSCROLL
Index: openafs/src/WINNT/client_config/lang/en_US/afs_config.rc
diff -c openafs/src/WINNT/client_config/lang/en_US/afs_config.rc:1.7.6.4 openafs/src/WINNT/client_config/lang/en_US/afs_config.rc:1.7.6.5
*** openafs/src/WINNT/client_config/lang/en_US/afs_config.rc:1.7.6.4 Fri Jul 27 11:41:53 2007
--- openafs/src/WINNT/client_config/lang/en_US/afs_config.rc Mon Mar 10 14:18:14 2008
***************
*** 354,361 ****
FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_PROBE,90,16,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_THREADS,90,36,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_DAEMONS,90,56,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_SYSNAME,90,76,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_MOUNTDIR,90,96,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_ROOTVOLUME,90,116,83,13,ES_AUTOHSCROLL
--- 354,361 ----
FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_PROBE,90,16,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_DAEMONS,90,36,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_THREADS,90,56,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_SYSNAME,90,76,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_MOUNTDIR,90,96,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_ROOTVOLUME,90,116,83,13,ES_AUTOHSCROLL
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.5.6.2 openafs/src/WINNT/client_config/lang/es_ES/afs_config.rc:1.5.6.3
*** openafs/src/WINNT/client_config/lang/es_ES/afs_config.rc:1.5.6.2 Tue Dec 12 15:41:15 2006
--- openafs/src/WINNT/client_config/lang/es_ES/afs_config.rc Mon Mar 10 14:18:14 2008
***************
*** 356,363 ****
BEGIN
EDITTEXT IDC_LAN_ADAPTER,113,20,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_PROBE,113,40,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_THREADS,113,60,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_DAEMONS,113,80,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_SYSNAME,112,100,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_MOUNTDIR,112,120,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_ROOTVOLUME,112,140,83,13,ES_AUTOHSCROLL
--- 356,363 ----
BEGIN
EDITTEXT IDC_LAN_ADAPTER,113,20,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_PROBE,113,40,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_DAEMONS,113,60,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_THREADS,113,80,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_SYSNAME,112,100,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_MOUNTDIR,112,120,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_ROOTVOLUME,112,140,83,13,ES_AUTOHSCROLL
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.5.6.2 openafs/src/WINNT/client_config/lang/ja_JP/afs_config.rc:1.5.6.3
*** openafs/src/WINNT/client_config/lang/ja_JP/afs_config.rc:1.5.6.2 Tue Dec 12 15:41:16 2006
--- openafs/src/WINNT/client_config/lang/ja_JP/afs_config.rc Mon Mar 10 14:18:15 2008
***************
*** 354,361 ****
BEGIN
EDITTEXT IDC_LAN_ADAPTER,128,20,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_PROBE,128,40,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_THREADS,128,60,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_DAEMONS,128,80,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_SYSNAME,128,100,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_MOUNTDIR,128,120,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_ROOTVOLUME,128,140,83,13,ES_AUTOHSCROLL
--- 354,361 ----
BEGIN
EDITTEXT IDC_LAN_ADAPTER,128,20,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_PROBE,128,40,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_DAEMONS,128,60,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_THREADS,128,80,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_SYSNAME,128,100,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_MOUNTDIR,128,120,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_ROOTVOLUME,128,140,83,13,ES_AUTOHSCROLL
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.5.6.2 openafs/src/WINNT/client_config/lang/ko_KR/afs_config.rc:1.5.6.3
*** openafs/src/WINNT/client_config/lang/ko_KR/afs_config.rc:1.5.6.2 Tue Dec 12 15:41:17 2006
--- openafs/src/WINNT/client_config/lang/ko_KR/afs_config.rc Mon Mar 10 14:18:15 2008
***************
*** 349,356 ****
BEGIN
EDITTEXT IDC_LAN_ADAPTER,90,20,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_PROBE,90,40,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_THREADS,90,60,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_DAEMONS,90,80,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_SYSNAME,90,100,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_MOUNTDIR,90,120,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_ROOTVOLUME,90,140,83,13,ES_AUTOHSCROLL
--- 349,356 ----
BEGIN
EDITTEXT IDC_LAN_ADAPTER,90,20,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_PROBE,90,40,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_DAEMONS,90,60,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_THREADS,90,80,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_SYSNAME,90,100,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_MOUNTDIR,90,120,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_ROOTVOLUME,90,140,83,13,ES_AUTOHSCROLL
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.5.6.2 openafs/src/WINNT/client_config/lang/pt_BR/afs_config.rc:1.5.6.4
*** openafs/src/WINNT/client_config/lang/pt_BR/afs_config.rc:1.5.6.2 Tue Dec 12 15:41:17 2006
--- openafs/src/WINNT/client_config/lang/pt_BR/afs_config.rc Wed Mar 12 01:47:38 2008
***************
*** 356,363 ****
BEGIN
EDITTEXT IDC_LAN_ADAPTER,101,20,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_PROBE,101,40,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_THREADS,101,60,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_DAEMONS,101,80,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_SYSNAME,101,100,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_MOUNTDIR,101,120,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_ROOTVOLUME,101,140,83,13,ES_AUTOHSCROLL
--- 356,363 ----
BEGIN
EDITTEXT IDC_LAN_ADAPTER,101,20,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_PROBE,101,40,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_DAEMONS,101,60,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_THREADS,101,80,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_SYSNAME,101,100,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_MOUNTDIR,101,120,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_ROOTVOLUME,101,140,83,13,ES_AUTOHSCROLL
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.5.6.2 openafs/src/WINNT/client_config/lang/zh_CN/afs_config.rc:1.5.6.3
*** openafs/src/WINNT/client_config/lang/zh_CN/afs_config.rc:1.5.6.2 Tue Dec 12 15:41:17 2006
--- openafs/src/WINNT/client_config/lang/zh_CN/afs_config.rc Mon Mar 10 14:18:15 2008
***************
*** 342,349 ****
BEGIN
EDITTEXT IDC_LAN_ADAPTER,90,20,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_PROBE,90,40,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_THREADS,90,60,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_DAEMONS,90,80,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_SYSNAME,90,100,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_MOUNTDIR,90,120,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_ROOTVOLUME,90,140,83,13,ES_AUTOHSCROLL
--- 342,349 ----
BEGIN
EDITTEXT IDC_LAN_ADAPTER,90,20,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_PROBE,90,40,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_DAEMONS,90,60,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_THREADS,90,80,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_SYSNAME,90,100,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_MOUNTDIR,90,120,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_ROOTVOLUME,90,140,83,13,ES_AUTOHSCROLL
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.5.6.2 openafs/src/WINNT/client_config/lang/zh_TW/afs_config.rc:1.5.6.3
*** openafs/src/WINNT/client_config/lang/zh_TW/afs_config.rc:1.5.6.2 Tue Dec 12 15:41:17 2006
--- openafs/src/WINNT/client_config/lang/zh_TW/afs_config.rc Mon Mar 10 14:18:15 2008
***************
*** 344,351 ****
BEGIN
EDITTEXT IDC_LAN_ADAPTER,96,20,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_PROBE,96,40,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_THREADS,96,60,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_DAEMONS,96,80,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_SYSNAME,96,100,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_MOUNTDIR,96,120,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_ROOTVOLUME,96,140,83,13,ES_AUTOHSCROLL
--- 344,351 ----
BEGIN
EDITTEXT IDC_LAN_ADAPTER,96,20,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_PROBE,96,40,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_DAEMONS,96,60,32,13,ES_AUTOHSCROLL
! EDITTEXT IDC_THREADS,96,80,32,13,ES_AUTOHSCROLL
EDITTEXT IDC_SYSNAME,96,100,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_MOUNTDIR,96,120,83,13,ES_AUTOHSCROLL
EDITTEXT IDC_ROOTVOLUME,96,140,83,13,ES_AUTOHSCROLL
Index: openafs/src/WINNT/client_exp/gui2fs.cpp
diff -c openafs/src/WINNT/client_exp/gui2fs.cpp:1.19.4.5 openafs/src/WINNT/client_exp/gui2fs.cpp:1.19.4.6
*** openafs/src/WINNT/client_exp/gui2fs.cpp:1.19.4.5 Fri Feb 8 21:32:24 2008
--- openafs/src/WINNT/client_exp/gui2fs.cpp Wed Mar 19 09:24:05 2008
***************
*** 554,571 ****
return tp;
}
! struct Acl *ParseAcl(char *astr)
{
! int nplus, nminus, i, trights;
char tname[MAXNAME];
! struct AclEntry *first, *last, *tl;
struct Acl *ta;
! ta = (struct Acl *) malloc (sizeof (struct Acl));
! ta->dfs = 0;
! sscanf(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell);
astr = SkipLine(astr);
! sscanf(astr, "%d", &ta->nminus);
astr = SkipLine(astr);
nplus = ta->nplus;
--- 554,598 ----
return tp;
}
! struct Acl *EmptyAcl(char *astr)
{
! register struct Acl *tp;
! int junk;
!
! tp = (struct Acl *)malloc(sizeof (struct Acl));
! tp->nplus = tp->nminus = 0;
! tp->pluslist = tp->minuslist = 0;
! tp->dfs = 0;
! if (astr == NULL || sscanf(astr, "%d dfs:%d %s", &junk, &tp->dfs, tp->cell) <= 0) {
! tp->dfs = 0;
! tp->cell[0] = '\0';
! }
! return tp;
! }
!
! struct Acl *
! ParseAcl (char *astr)
! {
! int nplus, nminus, i, trights, ret;
char tname[MAXNAME];
! struct AclEntry *first, *next, *last, *tl;
struct Acl *ta;
! ta = EmptyAcl(NULL);
! if (astr == NULL || strlen(astr) == 0)
! return ta;
!
! ret = sscanf(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell);
! if (ret <= 0) {
! free(ta);
! return NULL;
! }
astr = SkipLine(astr);
! ret = sscanf(astr, "%d", &ta->nminus);
! if (ret <= 0) {
! free(ta);
! return NULL;
! }
astr = SkipLine(astr);
nplus = ta->nplus;
***************
*** 573,611 ****
last = 0;
first = 0;
! for(i = 0; i < nplus; i++) {
! sscanf(astr, "%100s %d", tname, &trights);
astr = SkipLine(astr);
tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
! if (!first)
! first = tl;
strcpy(tl->name, tname);
tl->rights = trights;
tl->next = 0;
! if (last)
! last->next = tl;
last = tl;
}
ta->pluslist = first;
last = 0;
first = 0;
! for(i=0; i < nminus; i++) {
! sscanf(astr, "%100s %d", tname, &trights);
astr = SkipLine(astr);
tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
if (!first)
! first = tl;
strcpy(tl->name, tname);
tl->rights = trights;
tl->next = 0;
if (last)
! last->next = tl;
last = tl;
}
ta->minuslist = first;
return ta;
}
/* clean up an access control list of its bad entries; return 1 if we made
--- 600,662 ----
last = 0;
first = 0;
! for(i=0;iname, tname);
tl->rights = trights;
tl->next = 0;
! if (last)
! last->next = tl;
last = tl;
}
ta->pluslist = first;
last = 0;
first = 0;
! for(i=0;iname, tname);
tl->rights = trights;
tl->next = 0;
if (last)
! last->next = tl;
last = tl;
}
ta->minuslist = first;
+ exit:
return ta;
+
+ nminus_err:
+ for (;first; first = next) {
+ next = first->next;
+ free(first);
+ }
+ first = ta->pluslist;
+
+ nplus_err:
+ for (;first; first = next) {
+ next = first->next;
+ free(first);
+ }
+ free(ta);
+ return NULL;
}
/* clean up an access control list of its bad entries; return 1 if we made
***************
*** 678,683 ****
--- 729,738 ----
}
ta = ParseAcl(space);
+ if (ta == NULL) {
+ ShowMessageBox(IDS_INVALID_ACL_DATA, MB_ICONERROR, IDS_INVALID_ACL_DATA);
+ continue;
+ }
if (ta->dfs) {
ShowMessageBox(IDS_CLEANACL_NOT_SUPPORTED, MB_ICONERROR, IDS_CLEANACL_NOT_SUPPORTED, names[i]);
continue;
***************
*** 728,733 ****
--- 783,792 ----
}
ta = ParseAcl(space);
+ if (ta == NULL) {
+ ShowMessageBox(IDS_INVALID_ACL_DATA, MB_ICONERROR, IDS_INVALID_ACL_DATA);
+ return FALSE;
+ }
if (ta->dfs) {
ShowMessageBox(IDS_DFSACL_ERROR, MB_ICONERROR, IDS_DFSACL_ERROR);
return FALSE;
***************
*** 924,929 ****
--- 983,993 ----
else
pToAcl = ParseAcl(space);
+ if (pToAcl == NULL) {
+ ShowMessageBox(IDS_INVALID_ACL_DATA, MB_ICONERROR, IDS_INVALID_ACL_DATA);
+ return FALSE;
+ }
+
CleanAcl(pToAcl);
if (pToAcl->dfs) {
Index: openafs/src/WINNT/client_exp/resource.h
diff -c openafs/src/WINNT/client_exp/resource.h:1.8.4.2 openafs/src/WINNT/client_exp/resource.h:1.8.4.3
*** openafs/src/WINNT/client_exp/resource.h:1.8.4.2 Sat Jan 12 18:31:24 2008
--- openafs/src/WINNT/client_exp/resource.h Wed Mar 19 09:24:05 2008
***************
*** 74,79 ****
--- 74,80 ----
#define IDS_ALL_SERVERS_RUNNING 65
#define IDS_CHECK_VOLUMES_OK 66
#define IDS_CHECK_VOLUMES_ERROR 67
+ #define IDS_INVALID_ACL_DATA 68
#define IDS_ACL_ENTRY_NAME_IN_USE 80
#define IDS_REALLY_DEL_MOUNT_POINTS 81
Index: openafs/src/WINNT/client_exp/lang/en_US/afs_shl_ext.rc
diff -c openafs/src/WINNT/client_exp/lang/en_US/afs_shl_ext.rc:1.10.4.2 openafs/src/WINNT/client_exp/lang/en_US/afs_shl_ext.rc:1.10.4.3
*** openafs/src/WINNT/client_exp/lang/en_US/afs_shl_ext.rc:1.10.4.2 Sat Jan 12 18:31:25 2008
--- openafs/src/WINNT/client_exp/lang/en_US/afs_shl_ext.rc Wed Mar 19 09:24:06 2008
***************
*** 602,607 ****
--- 602,608 ----
IDS_ALL_SERVERS_RUNNING "All servers are running."
IDS_CHECK_VOLUMES_OK "All volumeID/name mappings checked."
IDS_CHECK_VOLUMES_ERROR "Error checking volumeID/name mappings: %o"
+ IDS_INVALID_ACL_DATA "Internal Error: Invalid ACL data was received."
END
STRINGTABLE DISCARDABLE
Index: openafs/src/WINNT/client_osi/libosi.def
diff -c openafs/src/WINNT/client_osi/libosi.def:1.3.14.1 openafs/src/WINNT/client_osi/libosi.def:1.3.14.2
*** openafs/src/WINNT/client_osi/libosi.def:1.3.14.1 Thu Jun 1 11:39:55 2006
--- openafs/src/WINNT/client_osi/libosi.def Wed Feb 27 12:06:44 2008
***************
*** 70,72 ****
--- 70,73 ----
osi_LogEvent @63
osi_HexifyString @64
osi_QRemoveHT @65
+ lock_ConvertRToW @66
Index: openafs/src/WINNT/client_osi/osibasel.c
diff -c openafs/src/WINNT/client_osi/osibasel.c:1.4.4.2 openafs/src/WINNT/client_osi/osibasel.c:1.4.4.3
*** openafs/src/WINNT/client_osi/osibasel.c:1.4.4.2 Mon Oct 2 22:48:23 2006
--- openafs/src/WINNT/client_osi/osibasel.c Wed Feb 27 12:06:44 2008
***************
*** 19,24 ****
--- 19,25 ----
/* atomicity-providing critical sections */
CRITICAL_SECTION osi_baseAtomicCS[OSI_MUTEXHASHSIZE];
+ static long atomicIndexCounter = 0;
void osi_BaseInit(void)
{
***************
*** 179,184 ****
--- 180,217 ----
}
}
+ void lock_ConvertRToW(osi_rwlock_t *lockp)
+ {
+ long i;
+ CRITICAL_SECTION *csp;
+
+ if ((i = lockp->type) != 0) {
+ if (i >= 0 && i < OSI_NLOCKTYPES)
+ (osi_lockOps[i]->ConvertRToWProc)(lockp);
+ return;
+ }
+
+ /* otherwise we're the fast base type */
+ csp = &osi_baseAtomicCS[lockp->atomicIndex];
+ EnterCriticalSection(csp);
+
+ osi_assertx(!(lockp->flags & OSI_LOCKFLAG_EXCL), "write lock held");
+ osi_assertx(lockp->readers > 0, "read lock not held");
+
+ if (--lockp->readers == 0) {
+ /* convert read lock to write lock */
+ lockp->flags |= OSI_LOCKFLAG_EXCL;
+ } else {
+ lockp->waiters++;
+ osi_TWait(&lockp->d.turn, OSI_SLEEPINFO_W4WRITE, &lockp->flags, csp);
+ lockp->waiters--;
+ osi_assert(lockp->readers == 0 && (lockp->flags & OSI_LOCKFLAG_EXCL));
+ }
+
+ lockp->tid = thrd_Current();
+ LeaveCriticalSection(csp);
+ }
+
void lock_ObtainMutex(struct osi_mutex *lockp)
{
long i;
***************
*** 443,449 ****
mp->type = 0;
mp->flags = 0;
mp->tid = 0;
! mp->atomicIndex = osi_MUTEXHASH(mp);
osi_TInit(&mp->d.turn);
return;
}
--- 476,482 ----
mp->type = 0;
mp->flags = 0;
mp->tid = 0;
! mp->atomicIndex = (unsigned short)(InterlockedIncrement(&atomicIndexCounter) % OSI_MUTEXHASHSIZE);
osi_TInit(&mp->d.turn);
return;
}
***************
*** 463,469 ****
*/
mp->type = 0;
mp->flags = 0;
! mp->atomicIndex = osi_MUTEXHASH(mp);
mp->readers = 0;
mp->tid = 0;
osi_TInit(&mp->d.turn);
--- 496,502 ----
*/
mp->type = 0;
mp->flags = 0;
! mp->atomicIndex = (unsigned short)(InterlockedIncrement(&atomicIndexCounter) % OSI_MUTEXHASHSIZE);
mp->readers = 0;
mp->tid = 0;
osi_TInit(&mp->d.turn);
Index: openafs/src/WINNT/client_osi/osibasel.h
diff -c openafs/src/WINNT/client_osi/osibasel.h:1.5.4.2 openafs/src/WINNT/client_osi/osibasel.h:1.5.4.3
*** openafs/src/WINNT/client_osi/osibasel.h:1.5.4.2 Sun Nov 4 19:18:37 2007
--- openafs/src/WINNT/client_osi/osibasel.h Wed Feb 27 12:06:44 2008
***************
*** 109,114 ****
--- 109,116 ----
extern void lock_ConvertWToR(struct osi_rwlock *);
+ extern void lock_ConvertRToW(struct osi_rwlock *);
+
/* and stat functions */
extern int lock_GetRWLockState(struct osi_rwlock *);
Index: openafs/src/WINNT/client_osi/osilog.h
diff -c openafs/src/WINNT/client_osi/osilog.h:1.7 openafs/src/WINNT/client_osi/osilog.h:1.7.4.1
*** openafs/src/WINNT/client_osi/osilog.h:1.7 Sat Nov 5 01:47:55 2005
--- openafs/src/WINNT/client_osi/osilog.h Wed Feb 27 12:06:44 2008
***************
*** 1,4 ****
! /*
* Copyright (C) 1998, 1989 Transarc Corporation - All rights reserved
*
* (C) COPYRIGHT IBM CORPORATION 1987, 1988
--- 1,4 ----
! /*
* Copyright (C) 1998, 1989 Transarc Corporation - All rights reserved
*
* (C) COPYRIGHT IBM CORPORATION 1987, 1988
***************
*** 86,97 ****
extern char *osi_HexifyString(char *s);
/* define macros */
! #define osi_Log0(l,f) osi_LogAdd((l), (f), 0, 0, 0, 0)
! #define osi_Log1(l,f,a) osi_LogAdd((l), (f), (size_t) (a), 0, 0, 0)
! #define osi_Log2(l,f,a,b) osi_LogAdd((l), (f), (size_t) (a), (size_t) (b), 0, 0)
! #define osi_Log3(l,f,a,b,c) osi_LogAdd((l), (f), (size_t) (a), (size_t) (b), (size_t) (c), 0)
! #define osi_Log4(l,f,a,b,c,d) osi_LogAdd((l), (f), (size_t) (a), (size_t) (b), (size_t) (c), (size_t) (d))
! #define osi_Log5(l,f,a,b,c,d,e) osi_LogAdd((l), (f), (size_t) (a), (size_t) (b), (size_t) (c), (size_t) (d), (size_t) (e))
#ifdef DEBUG_VERBOSE
#define DEBUG_EVENT1(a,b,c) {HANDLE h; char *ptbuf[1],buf[132];\
--- 86,97 ----
extern char *osi_HexifyString(char *s);
/* define macros */
! #define osi_Log0(l,f) if ((l) && (l)->enabled) osi_LogAdd((l), (f), 0, 0, 0, 0)
! #define osi_Log1(l,f,a) if ((l) && (l)->enabled) osi_LogAdd((l), (f), (size_t) (a), 0, 0, 0)
! #define osi_Log2(l,f,a,b) if ((l) && (l)->enabled) osi_LogAdd((l), (f), (size_t) (a), (size_t) (b), 0, 0)
! #define osi_Log3(l,f,a,b,c) if ((l) && (l)->enabled) osi_LogAdd((l), (f), (size_t) (a), (size_t) (b), (size_t) (c), 0)
! #define osi_Log4(l,f,a,b,c,d) if ((l) && (l)->enabled) osi_LogAdd((l), (f), (size_t) (a), (size_t) (b), (size_t) (c), (size_t) (d))
! #define osi_Log5(l,f,a,b,c,d,e) if ((l) && (l)->enabled) osi_LogAdd((l), (f), (size_t) (a), (size_t) (b), (size_t) (c), (size_t) (d), (size_t) (e))
#ifdef DEBUG_VERBOSE
#define DEBUG_EVENT1(a,b,c) {HANDLE h; char *ptbuf[1],buf[132];\
Index: openafs/src/WINNT/client_osi/osiltype.h
diff -c openafs/src/WINNT/client_osi/osiltype.h:1.2 openafs/src/WINNT/client_osi/osiltype.h:1.2.4.1
*** openafs/src/WINNT/client_osi/osiltype.h:1.2 Sat Nov 19 09:30:38 2005
--- openafs/src/WINNT/client_osi/osiltype.h Wed Feb 27 12:06:44 2008
***************
*** 35,40 ****
--- 35,41 ----
void (*FinalizeMutexProc)(struct osi_mutex *);
void (*FinalizeRWLockProc)(struct osi_rwlock *);
void (*ConvertWToRProc)(struct osi_rwlock *);
+ void (*ConvertRToWProc)(struct osi_rwlock *);
int (*GetRWLockState)(struct osi_rwlock *);
int (*GetMutexState)(struct osi_mutex *);
} osi_lockOps_t;
Index: openafs/src/WINNT/client_osi/osistatl.c
diff -c openafs/src/WINNT/client_osi/osistatl.c:1.3 openafs/src/WINNT/client_osi/osistatl.c:1.3.4.1
*** openafs/src/WINNT/client_osi/osistatl.c:1.3 Sun Nov 20 20:56:22 2005
--- openafs/src/WINNT/client_osi/osistatl.c Wed Feb 27 12:06:44 2008
***************
*** 206,211 ****
--- 206,261 ----
}
}
+ static void lock_ConvertRToWStat(osi_rwlock_t *lockp)
+ {
+ osi_activeInfo_t *ap;
+ osi_rwlockStat_t *realp;
+ CRITICAL_SECTION *csp;
+
+ realp = (osi_rwlockStat_t *)lockp->d.privateDatap;
+
+ /* otherwise we're the fast base type */
+ csp = &osi_statAtomicCS[lockp->atomicIndex];
+ EnterCriticalSection(csp);
+
+ osi_assert(lockp->flags & OSI_LOCKFLAG_EXCL);
+ ap = osi_FindActiveInfo(&realp->qi);
+ osi_assert(ap !=NULL);
+ osi_RemoveActiveInfo(&realp->qi, ap);
+ realp->readLockedCount++;
+ realp->readLockedTime = LargeIntegerAdd(realp->readLockedTime, ap->startTime);
+ osi_FreeActiveInfo(ap);
+
+ if (--lockp->readers == 0) {
+ /* and obtain the write lock */
+ lockp->readers--;
+ lockp->flags |= OSI_LOCKFLAG_EXCL;
+ } else {
+ lockp->waiters++;
+ ap = osi_QueueActiveInfo(&realp->qi,
+ OSI_ACTIVEFLAGS_WRITER | OSI_ACTIVEFLAGS_WAITER);
+ osi_TWait(&realp->turn, OSI_SLEEPINFO_W4WRITE, &lockp->flags, csp);
+ lockp->waiters--;
+ osi_assert((lockp->flags & OSI_LOCKFLAG_EXCL) && lockp->readers == 0);
+
+ /* we have some timer info about the last sleep operation
+ * that we should merge in under the spin lock.
+ */
+
+ /* remove from queue and turn time to incremental time */
+ osi_RemoveActiveInfo(&realp->qi, ap);
+
+ /* add in increment to statistics */
+ realp->writeBlockedCount++;
+ realp->writeBlockedTime = LargeIntegerAdd(realp->writeBlockedTime,
+ ap->startTime);
+ osi_FreeActiveInfo(ap);
+ }
+
+ osi_QueueActiveInfo(&realp->qi, OSI_ACTIVEFLAGS_WRITER);
+ LeaveCriticalSection(csp);
+ }
+
static void lock_ReleaseWriteStat(osi_rwlock_t *lockp)
{
osi_activeInfo_t *ap;
***************
*** 444,450 ****
return i;
}
! static void osi_SleepRStat(long sleepVal, struct osi_rwlock *lockp)
{
osi_rwlockStat_t *realp;
osi_activeInfo_t *ap;
--- 494,500 ----
return i;
}
! static void osi_SleepRStat(LONG_PTR sleepVal, struct osi_rwlock *lockp)
{
osi_rwlockStat_t *realp;
osi_activeInfo_t *ap;
***************
*** 474,480 ****
osi_SleepSpin(sleepVal, csp);
}
! static void osi_SleepWStat(long sleepVal, struct osi_rwlock *lockp)
{
osi_activeInfo_t *ap;
osi_rwlockStat_t *realp;
--- 524,530 ----
osi_SleepSpin(sleepVal, csp);
}
! static void osi_SleepWStat(LONG_PTR sleepVal, struct osi_rwlock *lockp)
{
osi_activeInfo_t *ap;
osi_rwlockStat_t *realp;
***************
*** 505,511 ****
osi_SleepSpin(sleepVal, csp);
}
! static void osi_SleepMStat(long sleepVal, struct osi_mutex *lockp)
{
osi_mutexStat_t *realp;
osi_activeInfo_t *ap;
--- 555,561 ----
osi_SleepSpin(sleepVal, csp);
}
! static void osi_SleepMStat(LONG_PTR sleepVal, struct osi_mutex *lockp)
{
osi_mutexStat_t *realp;
osi_activeInfo_t *ap;
***************
*** 740,745 ****
--- 790,796 ----
lock_FinalizeMutexStat,
lock_FinalizeRWLockStat,
lock_ConvertWToRStat,
+ lock_ConvertRToWStat,
lock_GetRWLockStateStat,
lock_GetMutexStateStat
};
***************
*** 798,804 ****
memset((void *) parmsp, 0, sizeof(*parmsp));
backMutexp = mp->qi.backp;
! parmsp->idata[0] = backMutexp;
parmsp->idata[1] = (backMutexp->flags & OSI_LOCKFLAG_EXCL)? 1 : 0;
/* reader count [2] is 0 */
parmsp->idata[3] = (backMutexp->waiters > 0)? 1 : 0;
--- 849,855 ----
memset((void *) parmsp, 0, sizeof(*parmsp));
backMutexp = mp->qi.backp;
! parmsp->idata[0] = (LONG_PTR)backMutexp;
parmsp->idata[1] = (backMutexp->flags & OSI_LOCKFLAG_EXCL)? 1 : 0;
/* reader count [2] is 0 */
parmsp->idata[3] = (backMutexp->waiters > 0)? 1 : 0;
***************
*** 816,822 ****
memset((void *) parmsp, 0, sizeof(*parmsp));
backRWLockp = rwp->qi.backp;
! parmsp->idata[0] = backRWLockp;
parmsp->idata[1] = (backRWLockp->flags & OSI_LOCKFLAG_EXCL)? 1 : 0;
parmsp->idata[2] = backRWLockp->readers;
parmsp->idata[3] = (backRWLockp->waiters > 0)? 1 : 0;
--- 867,873 ----
memset((void *) parmsp, 0, sizeof(*parmsp));
backRWLockp = rwp->qi.backp;
! parmsp->idata[0] = (LONG_PTR)backRWLockp;
parmsp->idata[1] = (backRWLockp->flags & OSI_LOCKFLAG_EXCL)? 1 : 0;
parmsp->idata[2] = backRWLockp->readers;
parmsp->idata[3] = (backRWLockp->waiters > 0)? 1 : 0;
Index: openafs/src/WINNT/doc/install/Documentation/en_US/html/index.htm
diff -c openafs/src/WINNT/doc/install/Documentation/en_US/html/index.htm:1.5.4.28 openafs/src/WINNT/doc/install/Documentation/en_US/html/index.htm:1.5.4.29
*** openafs/src/WINNT/doc/install/Documentation/en_US/html/index.htm:1.5.4.28 Mon Feb 25 00:24:46 2008
--- openafs/src/WINNT/doc/install/Documentation/en_US/html/index.htm Sat Mar 8 20:09:30 2008
***************
*** 57,63 ****
OpenAFS for Windows
! Version 1.5.33
--- 57,63 ----
OpenAFS for Windows
! Version 1.5.34
***************
*** 80,86 ****
·
OpenAFS for Windows 1.5.33
Release Notes
--- 80,86 ----
·
OpenAFS for Windows 1.5.34
Release Notes
Index: openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/logo.htm
diff -c openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/logo.htm:1.1.6.28 openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/logo.htm:1.1.6.29
*** openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/logo.htm:1.1.6.28 Mon Feb 25 00:24:51 2008
--- openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/logo.htm Sat Mar 8 20:09:47 2008
***************
*** 18,24 ****
.shape {behavior:url(#default#VML);}
!
OpenAFS for Windows 1.5.33 Release Notes
! OpenAFS for Windows 1.5.34 Release Notes
!